如果你用 TG 机器人做自动回复、通知推送或客服系统,消息接收方式通常有两种:轮询(getUpdates)和 Webhook。轮询需要程序不断向服务器询问新消息,延迟和资源消耗都较高;Webhook 则由 TG 服务器主动把更新推送到你指定的 HTTPS 地址,实时性更好,也更适合长期运行的服务。本文围绕 Webhook 的配置与使用展开,先给结论,再讲步骤和排查。
结论先行:什么情况下该用 Webhook
当你的机器人需要低延迟接收消息、长期在线运行,并且你有一个可公网访问的 HTTPS 域名时,优先使用 Webhook。反之,如果只是本地调试、没有公网地址,或者服务器无法配置证书,继续用轮询更省事。两者互斥:设置 Webhook 后,再调用 getUpdates 会返回冲突错误,需要先删除 Webhook 才能恢复轮询。
准备工作
- 一个已创建的机器人,并拿到 BotFather 提供的 Token。
- 一个公网可访问的 HTTPS 地址,例如
https://example.com/tg/webhook。证书需有效,自签名证书在部分场景下可能不被接受。 - 服务端能够处理 POST 请求,并返回 200 状态码。
- 建议设置一个随机且不易猜测的路径或密钥参数,避免被无关请求干扰。
配置 Webhook 的核心步骤
第一步:确定接收地址
你的服务端需要暴露一个 HTTPS 接口,用于接收 TG 推送的更新数据。路径可以自定义,但建议包含随机字符串,例如 /tg/webhook/abc123,降低被扫描的风险。
第二步:调用 setWebhook
通过 TG Bot API 的 setWebhook 方法提交地址。请求格式如下(把 Token 和地址替换成你自己的):
https://api.telegram.org/bot<Token>/setWebhook?url=https://example.com/tg/webhook/abc123
如果接口需要额外校验,可以附加 secret_token 参数,之后在请求头中核对对应字段。成功时返回结果中会包含 ok: true 和描述信息。
第三步:验证是否生效
调用 getWebhookInfo 查看当前状态,重点关注 url 是否为你设置的地址、pending_update_count 是否持续增长、last_error_message 是否有报错。若 pending 长期不为零,通常说明你的服务端没有正确返回 200,或响应超时。
第四步:处理更新数据
TG 会以 POST 方式把 JSON 格式的更新推送到你的地址。服务端应尽快解析并返回 200,避免长时间阻塞。耗时逻辑建议放入队列异步处理,否则容易触发超时重推。
注意事项
- 必须 HTTPS:Webhook 地址不支持纯 HTTP,证书异常会导致设置失败或推送中断。
- 返回要快:处理逻辑再复杂,也应先应答再处理,减少重复推送。
- 幂等设计:网络抖动可能导致同一更新被重复推送,业务侧应做去重。
- 密钥保护:Token 和 secret_token 不要写进前端代码或公开仓库。
- 切换模式:从 Webhook 切回轮询前,先调用 deleteWebhook,否则 getUpdates 会报冲突。
常见问题
设置 Webhook 返回 400 或证书错误
先检查地址是否为 HTTPS、证书链是否完整、域名是否解析到正确服务器。部分免费证书或自签名证书可能不被接受,建议使用受信任的证书。
Webhook 设置成功但收不到消息
用 getWebhookInfo 查看 last_error_message。常见原因包括:服务端返回非 200、响应超时、防火墙拦截、路径写错。也可以在服务端日志中确认是否收到 POST 请求。
pending_update_count 一直增加
说明推送到达了但未被成功确认。检查服务端是否在限定时间内返回 200,以及是否有异常导致进程崩溃。必要时先删除 Webhook,清理积压后再重新设置。
能否同时用 Webhook 和轮询
不能。两者互斥,设置 Webhook 后轮询会失效。调试阶段可以临时删除 Webhook 改用轮询,上线后再切回。
本地开发怎么调试
本地没有公网地址时,可用内网穿透工具临时映射 HTTPS 地址,或直接使用轮询模式开发,部署到公网服务器后再配置 Webhook。
小结
Webhook 的核心是「一个 HTTPS 地址 + 快速返回 200 + 幂等处理」。配置本身不复杂,难点多在证书、超时和重复推送。按本文步骤设置并用 getWebhookInfo 持续观察,大多数问题都能定位。若你的机器人只是轻量使用,轮询同样可行,不必为了 Webhook 而增加运维负担。