Telegram Craft
Telegram 的工作通常在三個地方出錯:憑記憶寫的 API 呼叫、把聊天當網頁來處理,以及相信看起來官方的客戶端資料。這個技能就是為了對抗這三點。
此處的事實已根據 Bot API 10.4(2026-11-09 發布)於 2026-11-10 驗證。發布週期約為每月一次,近期新增的名稱已替換,因此請對任何版本敏感的事項使用 scripts/tgdocs.py 確認。
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 |
| 新機器人或 Mini App | 建立標準專案佈局、撰寫螢幕地圖、建立一個可運作的垂直切片,然後擴展它。每個螢幕都是一則豐富訊息。 | backend.md、product-journeys.md、rich-messages.md、rich-recipes.md |
| 審查或稽核 | 執行 tg_audit.py,透過閱讀程式碼確認每個線索,按嚴重性報告。 | quality.md、security.md |
只在答案會改變你建立的內容,且程式碼無法告訴你時才提問。缺少 bot token 會阻止即時測試,但不影響實作。
維持專案的技術堆疊。對於沒有約束的新專案,Python 預設使用 aiogram 3,TypeScript 預設使用 grammY;Mini App 則預設使用 @tma.js/sdk 或純粹的 telegram-web-app.js 腳本。基礎設施應根據機器人規模調整(小型機器人不需要佇列或 Redis),但程式碼組織則不應縮水:每個新機器人都應採用 backend.md 中的標準佈局,將處理器、鍵盤、文字、服務和儲存分離到不同的模組。切勿交付混合檔案的平面資料夾。
2. 選擇互動介面
| 任務需求 | 使用 | 記住 |
|---|---|---|
| 指令、簡短流程、通知、檔案 | Bot 聊天 | 預設選擇 |
| 從少數選項中選擇 | 行內鍵盤 | 就地編輯訊息 |
| 長列表、篩選器、多欄位表單、圖表、地圖 | Mini App | 超過大約五個步驟的精靈模式就是一個訊號 |
| 將機器人內容發送到其他聊天 | Inline 模式 | 結果在使用者之間快取,除非設為 is_personal |
| 任何機器人畫面:選單、儀表板、列表、詳細資訊、設定、幫助、收據、報告 | 豐富訊息(預設) | sendRichMessage,使用 rich_message 編輯;在 rich-messages.md 中設計,在 formatting.md 中查詢函式庫呼叫 |
| 群組內的私人提示,或對按鈕按下的私人回覆 | 短暫訊息 | 不保證送達 |
| 聊天內的互動卡片 | HTML widget(sendWidget,10.4) | 目前僅限私人聊天;尚無 SDK 支援 |
| 作為使用者操作、閱讀未加入的歷史記錄 | MTProto 使用者 session(Telethon、TDLib) | 僅在獲得該帳號的明確授權時使用。具有不同的信任與 ban 風險模型。 |
| 超過 Bot API 限制的機器人檔案、原始層方法 | MTProto 機器人 session,或本地 Bot API 伺服器 | 將機器人 UI 保留在 Bot API 上 |
Bot API、Mini App 和 MTProto 不可互換。請參閱 frameworks.md,以及 MTProto 相關的 mtproto-foundations.md。
3. 防止大多數錯誤的規則
按錯誤成本排序。
安全與金錢
- 從更新或驗證過的 init data 取得身份,從你的資料庫取得權限。
callback_data、深層連結 payload、隱藏選單和使用者名稱都是使用者控制或可重新指派的。在每次回呼上都檢查角色和物件所有權,而不僅僅是在繪製按鈕時。比較數值 ID。 - 在伺服器端對每個 Mini App 請求或 session 驗證原始的
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沒有 period 參數。 - 將 token 保留在伺服器端。 它也會出現在 Bot API URL 和檔案下載連結中,因此絕對不要記錄它們或將它們發送給客戶端。如果使用者貼出了一個真實的 token,請僅按請求使用它,不要重複它,並建議如果 token 已暴露則進行輪換。
- 在組合標記之前,跳脫每個動態值。 在 HTML 中是
<、>、&。優先使用 HTML 而非 MarkdownV2,後者需要跳脫 18 個字元。 - 將上傳的檔案視為敵對的。 在下載前檢查大小,從 argv 列表(無 shell)執行工具,加入超時,並在
finally中刪除暫存檔。
可靠性
- 傳遞是至少一次,並且失敗的處理器通常不會重試。 aiogram 記錄異常並將該更新視為已處理。使副作用具有冪等性,並將業務狀態保存在資料庫中,而不是 FSM 記憶體中。
- 每個 token 僅運行一個消費者。 Polling 和 webhook 是互斥的,兩個 poller 會以 409 錯誤互相衝突。
- 立即回答每個回呼查詢, 包括拒絕和過期的按鈕,否則按鈕會一直轉圈。回答意味著「已收到」,而非「已成功」。
- 絕不阻塞事件迴圈。 一個
time.sleep、requests呼叫或同步編碼會凍結每個聊天。對緩慢的工作限制並發數量。 - 遇到 429 時,確切等待
parameters.retry_after。 Telegram 在 JSON body 中發送它,而不是在 header 中。廣播必須是可調速、可恢復的任務。 - 訂閱你要處理的更新類型。 省略
allowed_updates會保留先前的設定,而chat_member、message_reaction和message_reaction_count除非明確命名,否則預設關閉。
體驗
- 更新當前畫面,而不是堆疊新訊息, 並為每個畫面提供一個明確的下一步和一條離開的路徑。過期或無效的操作必須能恢復,而不是靜默失敗。
- 預設情況下,將每個畫面作為豐富訊息發送(
sendRichMessage,使用rich_message編輯),採用rich-messages.md中的標準樣式:純文字標題,畫面文字中無表情符號,有邊框的表格,僅包含使用者需要的區塊,絕不重複按鈕顯示的內容,且無內部 ID。按照rich-recipes.md中畫面類型的配方進行構建,並使用assets/rich_html.py建構 HTML;將鍵盤保留在reply_markup中。僅對標題、toast、單行回覆以及無法發送豐富訊息的堆疊使用格式化 HTML 文字;純文字(無格式)是一個缺陷。以結果開頭;無歡迎橫幅、打字風格的分隔線(━━━)或全大寫標題;一個<hr/>分隔畫面的摘要與主體。 - Mini App 應該感覺像 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 | Polling、Webhook、Docker、部署、速率限制、廣播、監控 |
frameworks.md | 選擇或使用函式庫、SDK 滯後、Bot API 與 MTProto |
media.md | 音樂、音訊、影片、檔案轉換、下載、上傳、file_id 快取、進度 |
payments.md | Stars、發票、訂閱、退款、市集、數位交付 |
mini-apps.md | Mini App 啟動、認證、SDK、視窗、儲存、客戶端/伺服器流程 |
mini-app-design.md | Mini App 佈局、類型、顏色、動畫、載入狀態、無障礙性 |
security.md | 秘密、授權、輸入處理、隱私、濫用防範、稽核日誌 |
groups-automation.md | 群組、頻道、審核、權限、Inline、短暫訊息、AI 機器人、機器人對機器人 |
existing-projects.md | 檢查、除錯或重構現有程式碼 |
quality.md | 編寫測試、測試旅程、發布前審查 |
quality-gate.md | 對外發送訊息和鍵盤的自動檢查、CI 設定、.tg-lint 報告 |
mtproto-foundations.md | 任何 MTProto 工作:API 選擇、api_id、登入、Session、限制、層級 |
mtproto-telethon.md | 撰寫或審查 Telethon:事件、更新、洪水平息、媒體、測試 |
hybrid-architecture.md | 在一個產品中結合 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 專案都需要:附加缺失的 session 和 .env 的 .gitignore 規則,加入一個在已提交 session 時失敗的 CI 任務,並報告暴露的 session 檔案和字串。它不會刪除或撤銷任何東西。 |
python3 scripts/install_quality_gate.py PROJECT --framework aiogram | 將自動 payload 檢查加入專案的測試執行和 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 | Linter、型別檢查、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。切勿安裝第二個副本。 - 使用閘道的測試框架(
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 或環境步驟;在哪些層級驗證了什麼;以及未驗證的內容。