跳至主要內容

接收 Bot 訊息與事件:輪詢與 Webhook

接收 MPChat 更新的兩種互斥方式:開發用 getUpdates 長輪詢、生產用 setWebhook,含 secret_token 校驗與選型建議。

二者互斥。Webhook 啟用時,getUpdates 回傳 409。開發用輪詢,生產用 Webhook。


總覽

只選一種投遞模式。輪詢是主動拉取,Webhook 是被動推送。setWebhook 與 deleteWebhook 是高危受控操作——勿對生產 Bot 隨意執行。

getUpdates 參數

  • offset——上一批最大 update_id + 1,避免重複消費。

  • limit——1 到 100,預設 100。

  • timeout——0 到 50 秒長輪詢。

  • allowed_updates——型別過濾,如 ["message", "callback_query"]。

getUpdates 成功時只消費本次回傳的批次。先儲存回傳的更新,再執行業務處理。一般未投遞的更新最多保留 24 小時。callback_query 投遞時限最長 150 秒,answerCallbackQuery 的獨立回應時限為 300 秒。

curl --silent --show-error "https://call.mp.net/bot/getUpdates" -X POST \
-H "Authorization: Bearer ${MPCHAT_BOT_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"offset":0,"timeout":30,"limit":50,"allowed_updates":["message","callback_query"]}'

配置 Webhook

curl --silent --show-error "https://call.mp.net/bot/setWebhook" -X POST \
-H "Authorization: Bearer ${MPCHAT_BOT_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"url":"https://example.com/mp-bot/webhook","secret_token":"YOUR_WEBHOOK_SECRET","allowed_updates":["message","callback_query"]}'
  • url——必填,必須 HTTPS。空字串等同 deleteWebhook。

  • secret_token——可選;設定後請求帶 X-MpChat-Bot-Api-Secret-Token 標頭。

  • max_connections、allowed_updates——可選調優與型別過濾。

更換 Webhook URL 會保留待傳遞更新、重試狀態和原有期限。需要捨棄切換前已接收的待傳遞更新時,設定 drop_pending_updates: true。max_connections 預設 40,範圍 1–100,是此 Bot 跨服務執行個體的總並行數。

allowed_updates 的三種用法

  • 省略此欄位時,沿用上次的篩選設定。

  • 傳入 [] 時使用預設集合,排除 chat_member、message_reaction 和 message_reaction_count。

  • 傳入非空清單時,只訂閱指定類型,例如 ["message", "callback_query"]。

輪詢和 Webhook 註冊皆適用。變更對新更新生效,既有佇列不會依新設定重新篩選。

Webhook 探測與投遞確認

註冊探測可能傳送空 JSON 物件 {}。設定 secret_token 後,探測和正式更新都會帶上 X-MpChat-Bot-Api-Secret-Token 標頭。

先驗證標頭,探測通過後回傳 2xx。收到正式更新時,先寫入持久儲存或可靠佇列,再回傳 2xx。投遞失敗時可能重試,請依每個 Bot 的 update_id 去除重複,避免重複執行業務操作。

註冊時與接收端須使用相同密鑰。下列處理器假設已設定 JSON 解析器與可靠佇列,佇列以 Bot 和更新 ID 組合為唯一鍵。

async function handleWebhook(req, res) {
const secret = process.env.WEBHOOK_SECRET;
const incoming = req.headers["x-mpchat-bot-api-secret-token"];
if (!secret || incoming !== secret) return res.status(401).end();

const update = req.body;
if (!update || typeof update !== "object" || Array.isArray(update)) {
return res.status(400).end();
}
if (Object.keys(update).length === 0) return res.status(204).end();
if (!Number.isSafeInteger(update.update_id)) return res.status(400).end();

try {
await enqueueUpdateOnce(update);
return res.status(204).end();
} catch {
return res.status(503).end();
}
}

如何選型

  • 本地開發:getUpdates;用 getWebhookInfo 確認未配置 Webhook。

  • 生產:Webhook + secret_token 校驗。

  • 切換:先在測試環境驗證,再對目標 Bot 執行 setWebhook。

相關文章

在已支援這些群組事件的環境中,加入、退出與置頂分別對應 message.new_chat_members、message.left_chat_member 和 message.pinned_message。Kafka 來源的群組事件與入群申請操作仍處於預發布。

是否回答了您的問題?