Telegram Craft(テレグラムクラフト)
Telegramの開発でよくある失敗は3パターンです。API呼び出しを記憶頼りで書くこと、チャットをウェブページのように扱うこと、そして公式に見えるクライアントデータを無条件に信頼することです。このスキルはそのすべてに対抗します。
ここに記載されている事実は、Bot API 10.4(2026-11-09リリース)に基づき2026-11-10に確認済みです。リリースは約毎月行われ、最近追加された名前はすでに置き換えられています。バージョンに依存する内容は、scripts/tgdocs.pyで必ず確認してください。
1. 作業規模の見極め
リクエストに応じてプロセスを合わせます。依頼されたものだけを構築し、推奨する追加機能はハンドオフ時にリストとして記載するにとどめます。
| 作業内容 | アプローチ | 最初に参照するもの |
|---|---|---|
| 質問、または一行修正 | 回答するかパッチを当てる。関係する契約を1つ確認する。 | platform-facts.md または該当領域のリファレンス |
| コピー、キーボード、/startの再設計 | 表示のみ変更。callback_data、ルート、事実、ロケールキーは維持。品質ゲート(quality-gate.md)を追加または実行する。 | messages.md、rich-messages.md、keyboards.md |
| 既存プロジェクトのバグ修正または機能追加 | コードを読み、再現し、既存のスタック内で最小の変更を行い、回帰テストを追加する。変更がボットの送信内容を変える可能性がある場合、完了前に品質ゲートを実行する(セクション6)。 | existing-projects.md、quality-gate.md |
| リファクタリング | まずテストで動作を固定し、その後コードを移動する。動作変更は行わない。 | existing-projects.md、backend.md |
| 新規ボットまたはミニアプリ | 標準プロジェクトレイアウトをスキャフォールドし、画面マップを書き、1つの完全な垂直スライスを構築してから拡張する。すべての画面はリッチメッセージとする。 | backend.md、product-journeys.md、rich-messages.md、rich-recipes.md |
| レビューまたは監査 | tg_audit.pyを実行し、コードを読んで各リードを確認し、重要度別に報告する。 | quality.md、security.md |
質問は、その答えが何を構築するかを変える場合、かつコードから答えが得られない場合にのみ行います。ボットトークンがなければライブテストはブロックされますが、実装自体は妨げられません。
プロジェクトのスタックを維持します。制約のない新規プロジェクトでは、Pythonの場合はaiogram 3、TypeScriptの場合はgrammYをデフォルトとし、ミニアプリでは**@tma.js/sdk** またはプレーンな telegram-web-app.js スクリプトを使用します。インフラはボットの規模に合わせます(小さなボットにキューやRedisは不要)が、コード構成はその限りではありません。すべての新規ボットは backend.md の標準レイアウトを取得し、ハンドラー、キーボード、テキスト、サービス、ストレージを個別のモジュールに分割します。フラットなフォルダにファイルを混在させて出荷してはいけません。
2. インターフェースの選択
| 必要な機能 | 使用するもの | 注意点 |
|---|---|---|
| コマンド、短いフロー、通知、ファイル | ボットチャット | デフォルトの選択 |
| いくつかの選択肢からの選択 | インラインキーボード | メッセージをその場で編集 |
| 長いリスト、フィルター、多フィールドフォーム、チャート、マップ | ミニアプリ | 5ステップ程度のウィザードは要検討 |
| ボットのコンテンツを他のチャットへ送信 | インラインモード | is_personal がなければ結果はユーザー間でキャッシュされる |
| あらゆるボット画面:メニュー、ダッシュボード、リスト、詳細、設定、ヘルプ、領収書、レポート | リッチメッセージ(デフォルト) | sendRichMessage、rich_message で編集;設計は rich-messages.md、ライブラリ呼び出しは formatting.md |
| グループ内でのプライベートなプロンプト、またはボタン押下へのプライベート返信 | エフェメラルメッセージ | 配信は保証されない |
| チャット内のインタラクティブカード | HTMLウィジェット(sendWidget、10.4) | 現時点ではプライベートチャットのみ;SDKサポートなし |
| ユーザーとして動作、未参加の履歴を読む | MTProtoユーザーセッション(Telethon、TDLib) | そのアカウントの明示的な許可が必要。異なる信頼性と禁止リスクモデル。 |
| Bot APIの制限を超えるボットファイル、ローレイヤーメソッド | MTProtoボットセッション、またはローカルBot APIサーバー | Bot UIはBot API上に維持 |
Bot API、ミニアプリ、MTProtoは互換性がありません。frameworks.md およびMTProtoについては mtproto-foundations.md を参照してください。
3. ほとんどの障害を防ぐルール
間違えたときのコスト順に並べています。
セキュリティと金銭
- IDはアップデートまたは検証済みのinitDataから取得し、権限は自身のデータベースから取得する。
callback_data、ディープリンクペイロード、隠しメニュー、ユーザー名はすべてユーザーが制御できるか再割り当て可能です。ボタンを描画するときだけでなく、すべてのコールバックでロールとオブジェクトの所有権を確認します。数値IDを比較します。 - すべてのミニアプリリクエストまたはセッションについて、サーバー側で生の
initDataを検証し、auth_dateを自身で確認する。 aiogramのsafe_parse_webapp_init_dataはシグネチャのみを検証します。initDataUnsafeは表示データです。assets/init_data.pyまたはassets/init_data.mjsをコピーして使用してください。 - デジタルグッズはTelegram Stars(
XTR)でのみ販売する。 付与はsuccessful_paymentで行い、pre-checkoutやクライアントのopenInvoiceコールバックでは決して行わない。telegram_payment_charge_idで重複を排除する。/paysupportを処理する。StarsサブスクリプションはcreateInvoiceLinkから生成される;sendInvoiceには期間パラメーターはありません。 - トークンはサーバー上に保持する。 トークンはBot APIのURLやファイルダウンロードリンクにも現れるため、これらをログに記録したりクライアントに送信したりしてはいけません。ユーザーが実際のトークンを貼り付けた場合は、依頼された用途にのみ使用し、繰り返さず、露出した場合はトークンのローテーションを提案します。
- マークアップを構成する前に各動的値をエスケープする。 HTMLでは
<、>、&です。18文字のエスケープが必要な MarkdownV2 よりも HTML を優先します。 - アップロードされたファイルは敵対的なものとして扱う。 ダウンロード前にサイズを確認し、シェルを介さずargvリストからツールを実行し、タイムアウトを追加し、
finallyで一時ファイルを削除します。
信頼性
- 配信はat-least-onceであり、失敗したハンドラーは通常リトライされない。 aiogramは例外をログに記録し、アップデートを処理済みとして扱います。副作用は冪等にし、ビジネス状態はFSMメモリではなくデータベースに保持します。
- トークンごとに1つのコンシューマーのみ実行する。 ポーリングとWebhookは相互排他的であり、2つのポーラーは409エラーで競合します。
- すべてのコールバッククエリに即座に応答する。 拒否や古いボタンも含め、応答がないとボタンは回転し続けます。応答は「受信した」を意味し、「成功した」を意味するわけではありません。
- イベントループをブロックしてはならない。 1つの
time.sleep、requests呼び出し、または同期的なエンコードがすべてのチャットをフリーズさせます。低速な処理には同時実行数を制限します。 - 429エラーの場合、
parameters.retry_afterの値だけ正確に待機する。 TelegramはこれをヘッダーではなくJSONボディで送信します。ブロードキャストはペース調整可能な再開可能ジョブでなければなりません。 - 処理する更新だけを購読する。
allowed_updatesを省略すると以前の設定が維持され、chat_member、message_reaction、message_reaction_countは明示的に名前を指定しない限りオフになります。
ユーザー体験
- 新しいメッセージを積み重ねる代わりに現在の画面を更新し、各画面に明確な次のステップと終了方法を設ける。 期限切れや無効なアクションは、静かに失敗するのではなく、回復できなければなりません。
- デフォルトですべての画面をリッチメッセージとして送信する(
sendRichMessage、rich_messageで編集)。rich-messages.mdの標準スタイルに従います:プレーンなタイトル、画面テキストに絵文字なし、枠線付きテーブル、ユーザーが必要とするブロックのみ、ボタンが示す内容を繰り返さない、内部IDなし。rich-recipes.mdの画面の役割に応じたレシピに従い、HTMLはassets/rich_html.pyで構築します;reply_markupにキーボードを保持します。書式付きHTMLテキストはキャプション、トースト、一行返信、リッチメッセージを送信できないスタックにのみ使用します;プレーンな書式なしテキストは欠陥です。結果を先に表示します;ウェルカムバナー、区切り線(━━━)、すべて大文字のヘッダーは使用しません;1つの<hr/>が画面の要約と本文を区切ります。 - ミニアプリはTelegramらしく動作させる。 テーマ変数、セーフエリア、ネイティブの戻るボタンと下部ボタン、実際のローディング状態とエラー状態を使用し、ライトモードとダークモードの両方をテストします。
4. タスクに必要なものだけを読み込む
該当するトリガーが発生したときに、その部分の設計前にリファレンスを読みます。すべてのパスは references/ の下にあります。
| 参照するもの | タスクが以下の内容を含む場合 |
|---|---|
product-journeys.md | 新製品、/start、オンボーディング、画面マップ、多言語計画 |
messages.md | ユーザーに表示されるテキストの作成または書き換え |
rich-messages.md | ボット画面の設計:標準スタイル、構造、コンポーネント、テキストスタイル、よくある間違い、レビューチェックリスト |
rich-recipes.md | 画面タイプごとのHTML形状:ホーム、ピッカー、詳細、データリスト、設定、ヘルプ、領収書、レポート、問題、確認、進捗 |
keyboards.md | ボタン、メニュー、ページネーション、戻る/キャンセル、確認、コールバック設計またはバグ |
formatting.md | HTML、MarkdownV2、エンティティ、長文、リッチメッセージ、ストリーミング下書き、パースエラー |
backend.md | プロジェクト構造、サービス、データベース、FSM、バックグラウンド処理、設定、ロギング、リトライ、シャットダウン |
delivery.md | ポーリング、Webhook、Docker、デプロイ、レート制限、ブロードキャスト、監視 |
frameworks.md | ライブラリの選択または使用、SDKの遅延、Bot API vs MTProto |
media.md | 音楽、音声、動画、ファイル変換、ダウンロード、アップロード、file_id キャッシュ、進捗 |
payments.md | Stars、請求書、サブスクリプション、返金、マーケットプレイス、デジタル配送 |
mini-apps.md | ミニアプリ起動、認証、SDK、ビューポート、ストレージ、クライアント/サーバーフロー |
mini-app-design.md | ミニアプリのレイアウト、タイプ、色、動き、ローディング状態、アクセシビリティ |
security.md | シークレット、認可、入力処理、プライバシー、不正利用防止、監査ログ |
groups-automation.md | グループ、チャンネル、モデレーション、権限、インライン、エフェメラル、AIボット、ボット間通信 |
existing-projects.md | 既存コードの調査、デバッグ、またはリファクタリング |
quality.md | テスト作成、ジャーニーテスト、リリース前レビュー |
quality-gate.md | 送信メッセージとキーボードの自動チェック、CI設定、.tg-lint レポート |
mtproto-foundations.md | あらゆるMTProto作業:API選択、api_id、サインイン、セッション、制限、レイヤー |
mtproto-telethon.md | Telethonの作成またはレビュー:イベント、更新、フラッドウェイト、メディア、テスト |
hybrid-architecture.md | 1つの製品でBot APIとMTProtoを組み合わせる |
platform-facts.md | 正確な制限、ファイルサイズ、レート制限、最近のAPI変更 |
5. ツール
このスキルのディレクトリから実行します。Python 3のみを必要とし、ユーザーのボットには触れません。
| コマンド | 目的 |
|---|---|
python3 scripts/tgdocs.py version / method NAME / type NAME / search TERM / changes --since 10.0 | 現在の公式契約。出力は参照データです。終了コード3はオフラインを意味します:その事実を未確認としてマークします。 |
python3 scripts/tg_lint.py screens.json | 制限、マークアップ、ボタン契約、UXシグナル。エラーは修正必須。警告は判断が必要。 |
python3 scripts/tg_audit.py PROJECT | 一般的な欠陥の静的な兆候。コードを読んでそれぞれを確認します。 |
python3 scripts/secure_mtproto_project.py PROJECT --ci | 新しいまたは変更されたすべてのMTProtoプロジェクトに必須:不足している .gitignore ルール(セッションと .env 用)を追加し、コミットされたセッションで失敗するCIジョブを追加し、露出したセッションファイルと文字列を報告します。削除や失効は決して行いません。 |
python3 scripts/install_quality_gate.py PROJECT --framework aiogram | プロジェクトのテスト実行とCIに自動ペイロードチェックを追加します(ptb、grammy も可)。新しいボットや、ボットが送信する内容を変更する場合に必須です(セクション6)。 |
最近のメソッドやフィールドを使用する前に、インストールされている ライブラリにそれが含まれているかを確認します:そのパッケージディレクトリを検索します。例えば、python-telegram-bot 22.8 は Bot API 10.0 を宣言しており、send_rich_message はありません。
assets/ にはコピーして適応するコードが含まれています:init_data.py、init_data.mjs、stars_ledger.py、media_job.py、update_delivery.py(インボックス、アウトボックス、429、チャットごとのレーン、再開可能なブロードキャスト)、mtproto_runtime.py、rich_html.py(エスケープされたリッチ画面ビルダー)、およびブラウザプレビュー用の webapp_mock.js。
6. 検証し、正直に報告する
| レベル | 証拠 | 主張できること |
|---|---|---|
| L0 | ドキュメントまたはコードを読んだ | 「ドキュメント通りに動作するはず」 |
| L1 | リンター、型チェック、tg_lint.py、tg_audit.py | 「静的チェックに合格」 |
| L2 | 実際のディスパッチャーと偽のTelegramトランスポートを使用したテスト、またはモックされたブラウザプレビュー | 「偽のTelegramに対してローカルで動作」 |
| L3 | 実際のクライアント、実際のデバイスでのテストボット | 「Telegramで動作」 |
品質ゲートは、変更がボットの送信内容を変更する可能性がある場合に完了の一部です。 変更内容には、メッセージテキストや書式、キーボード、callback_data やコールバックハンドラー、請求書、画面間のフローが含まれます。aiogram、python-telegram-bot、grammY プロジェクトでは:
- 既存のゲート(
tg_qualityディレクトリ、またはCI内のTG_LINT)を探して使用します。ない場合にのみinstall_quality_gate.pyを実行します。2番目のコピーをインストールしてはいけません。 - ゲートのハーネス(
quality-gate.md)を使用してジャーニーテストを書き、変更したすべての画面とボタン(修正したエラーパスや古いボタンパスを含む)に到達するようにします。テストが到達した画面上で、そこへのアクセスが許可されているユーザーとしてpressを使用します。何もキャプチャしなかったゲートは何もチェックしておらず、変更された画面にcoverage gap:という行がある場合は、テストがその画面に到達しなかったことを意味します。 - 最後の編集後、
TG_LINT_REQUIRE_INTERACTIONS=1を設定してテストを実行します。ボットコード内のゲートエラーをすべて修正します。合格を得るためにゲートを弱めたり、スキップしたり、削除したりしてはいけません。警告は非ブロッキングのままです:判断して対応します。 - ハンドオフでは、ゲートの
Telegram quality gate出力セクションからカバレッジ行を引用します。ゲートをインストールまたは実行できなかった場合は、その理由を述べ、合格したとは主張しません。
ゲートに言及したり、そのファイルをコピーしたりすることは検証ではありません。Telegramの出力に影響を与えない変更(ストレージ、設定、何も送信しないスケジュールジョブなど)についてはスキップします。他のスタック:変更された画面で tg_lint.py を実行し、ゲートが利用できないと記載します。
L1またはL2をL3として提示してはいけません。webapp_mock.js を使用したブラウザのスクリーンショットはレイアウトを示すものであり、Telegramの動作を示すものではありません。依頼がない限り、本番ボットを起動したり、ライブWebhookを変更したり、公開、ブロードキャスト、Starsの使用を行ったりしてはいけません。
最後に以下を記載します:ユーザーがこれで何ができるようになったか;プロジェクトツリー;変更したファイル;実行方法;BotFatherまたは所有者が手動で行う必要のある環境手順;どのレベルで何が検証されたか;何が検証されなかったか。