← 所有文章
教程

Telegram getUpdates 与 setWebhook 冲突:安全切换 Runbook

Telegram Bot API 的接收规则很直接:同一个机器人不能同时用 getUpdates 轮询和 setWebhook 推送。若部署后收不到消息,先确认当前到底由谁接收,再决定是删除 webhook 后恢复轮询,还是停止轮询 worker 后设置 webhook。Telegram 官方文档也说明,待处理 updates 只会临时保存,因此跨境团队切换客服入口时不要凭感觉操作。

关键结论

官方边界是什么

Telegram 官方 Bot API 文档把接收 updates 分成两种:getUpdates 是你的服务长轮询 Telegram;webhook 是 Telegram 向你的 HTTPS 地址发送请求。官方文档同时说明,只要 outgoing webhook 仍然存在,就不能通过 getUpdates 接收 updates;如需切回轮询,要使用 deleteWebhook

所以大多数“切换后没消息”的问题,先按状态排查:

现象可能状态先检查
轮询没有返回消息webhook URL 仍在getWebhookInfo
webhook 端点没有请求旧轮询 worker 仍在运行,或 webhook 未正确设置停 worker,再查 getWebhookInfo
内部队列重复或漏处理多个应用实例抢同一份业务处理先确定唯一 owner
切换后涌入测试消息旧 pending updates 被保留决定处理还是丢弃

步骤 1:查看当前接收端

在受控环境执行,BOT_TOKEN 放在环境变量中,不要写进日志:

curl "https://api.telegram.org/bot$BOT_TOKEN/getWebhookInfo"

如果返回中 url 非空,说明这个 bot 仍有 webhook。若 url 为空,Bot API webhook 未启用,getUpdates 可以作为接收路径。

步骤 2:从 webhook 切回 getUpdates

先删除 webhook:

curl -X POST "https://api.telegram.org/bot$BOT_TOKEN/deleteWebhook" \
  -d "drop_pending_updates=false"

生产客服消息通常应保留 false,然后由一个轮询 worker 幂等消化。只有确认 backlog 都是测试流量,或业务明确选择干净切换时,才把它设为 true

随后只启动一个轮询 worker,并在每次 getUpdates 返回后推进 offset

curl "https://api.telegram.org/bot$BOT_TOKEN/getUpdates?timeout=30"

步骤 3:从 getUpdates 切到 setWebhook

先停掉轮询 worker,再设置生产 webhook:

curl -X POST "https://api.telegram.org/bot$BOT_TOKEN/setWebhook" \
  -d "url=https://support.example.com/telegram/bot-webhook"

接收端应快速响应:先存下 update,再让 CRM、AI 分类或人工分派异步运行。这一点也适用于 webhook-first inbound integration checklist 里的入站架构,只是 Telegram Bot API update 与 UnifyPort 事件 schema 不同。

什么时候改用统一入站 webhook

这份 runbook 解决的是 Telegram bot 的接收模式切换。它不会把 bot 变成普通账号收件箱,也不会自动统一 WhatsApp、LINE、TikTok、Zalo 或 X 的消息格式。

如果你的客服系统需要共享事件层,可以创建 UnifyPort webhook。深度文档是 Create webhook endpoint:配置 HTTPS urlstatus: "active",订阅 message.received["*"],需要签名时设置 signing_secret

UnifyPort 的 Telegram 入站事件使用跨平台统一结构:

{
  "id": "evt_b1a7c3e5f8",
  "type": "message.received",
  "provider": "telegram",
  "account_id": "acc_8c21d0",
  "occurred_at": "2026-06-08T12:37:00Z",
  "data": {
    "conversation": { "id": "5005", "type": "user" },
    "sender": { "id": "4004", "type": "user", "name": "Jordan Lee" },
    "message": { "id": "3003", "direction": "inbound", "sent_at": "2026-06-08T12:37:00Z", "text": "Can you check my order?" },
    "event": { "kind": "message_received" }
  }
}

如果用户本来就应该与 bot 对话,继续使用官方 Bot API。若目标是把现有 Telegram 账号或多个渠道的入站消息放进同一个队列,使用 UnifyPort 的非官方接口更合适。

FAQ

getUpdates 和 setWebhook 能同时使用吗?

不能。Telegram 官方把二者定义为互斥的 bot update 接收方式。轮询前删除 webhook;设置 webhook 前停止轮询。

drop_pending_updates 应该设为 true 吗?

只有当待处理更新可以丢弃时才设为 true。生产客服消息通常应保留,并用幂等存储慢慢消化。

这等于连接 Telegram 普通账号吗?

不是。getUpdatessetWebhook 属于 Bot API,使用 bot token。UnifyPort 连接 Telegram 账号后,会发送标准化 message.received 事件。

Sources checked on 2026-09-09

UnifyPort API

让消息接入变成一条稳定的产品管线。

先用统一 API 跑通发送,再用标准事件把所有入站消息接回业务系统。