二者互斥。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 來源的群組事件與入群申請操作仍處於預發布。
