跳转到主要内容

接收 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 来源的群事件与入群申请操作仍处于预发布。

这是否解答了您的问题?