OpenClaw 与 Telegram 是怎么通信的:为什么我从 long polling 切到了 webhook
OpenClaw 与 Telegram 是怎么通信的:为什么我从 long polling 切到了 webhook
官方文档写得很直接:Telegram 在 OpenClaw 里是一个 Bot API 通道,默认用 long polling,webhook 是可选模式。
而 Telegram 官方 Bot API 也明确把两种收消息方式分开了:一种是 getUpdates,一种是 setWebhook。我这次从前者切到后者,本质上不是调参,而是把通信机制换掉了。

先说结论
OpenClaw 和 Telegram 通信,核心就两种方式:
long pollingwebhook
如果你的环境比较简单,没有公网入口,也没有复杂代理,long polling 上手最省事。
但如果你和我一样,跑在 WSL + 代理 这类链路不够稳定的环境里,webhook 往往更稳。因为它不再要求 OpenClaw 长时间主动挂着一条 getUpdates 连接去拉消息。
long polling 是怎么工作的
long polling 就是 OpenClaw 主动请求 Telegram,通过 getUpdates 拉取新消息,再交给后面的会话和模型链路处理。
它的优点是简单:
- 不需要公网 URL
- 本地起服务就能跑
- 适合先快速接通 bot
但它有个前提:这条主动拉取链路得长期稳定。
一旦链路卡住,表面现象通常就是:
- 服务还在
- token 没问题
- Telegram API 也不是完全不通
- 但消息就是收不到(真的折磨!!!)
webhook 又是怎么工作的
webhook 则相反,是 Telegram 主动把消息推给 OpenClaw。
你给 Telegram 配一个可访问的 HTTPS 地址,bot 收到消息后,Telegram 就会把更新直接 POST 到这个地址。
所以两者的区别可以直接理解成:
long polling:OpenClaw 主动拉消息webhook:Telegram 主动推消息
我这次为什么放弃 long polling
我当时遇到的典型日志是:
[telegram] Polling stall detected (no getUpdates for 91.54s); forcing restart.
这句已经很说明问题了:卡住的是 getUpdates 这条轮询链路。
一开始很容易怀疑 token、session、provider auth,甚至模型侧异常,但这次都不是。因为问题根本不在模型层,而是在 Telegram 消息进入 OpenClaw 的入口层。
我后面确认了几件事:
- systemd 服务大部分时候是
running - Telegram API 不是完全不可达
- 手动
getUpdates能看到消息进队列 - 真正不稳的是 OpenClaw 自己长期维持的 polling 链路
这次不是在修一个报错,而是在替换一条不稳定的收消息机制。
我是怎么落地 webhook 的
OpenClaw 官方文档给了 Telegram webhook 模式的关键配置项:
channels.telegram.webhookUrlchannels.telegram.webhookSecret- 可选的
channels.telegram.webhookPath - 可选的
channels.telegram.webhookHost
文档还说明了,OpenClaw 在 webhook 模式下会起本地 listener,默认监听本地端口,再由你自己的公网入口或反代把请求转进来。
我的实际落地方案是:
webhook + Tailscale Funnel
原因很简单:我没有直接暴露公网服务的条件,但 webhook 又要求 Telegram 能访问一个 HTTPS 地址。那就用 Funnel 把本地 listener 暴露成一个可访问的公网入口。
Tailscale Funnel 可以简单理解成:把本地服务暴露成一个公网 HTTPS 地址。对这个场景来说,它刚好解决了 webhook 最关键的问题:Telegram 需要访问一个公网入口,而 OpenClaw 实际跑在本地 WSL 里。
实际配置里,挂:
- 本地监听:
http://127.0.0.1:8787/telegram-main - 公网入口:
https://.../telegram-main
对应要保证独立的字段包括:
webhookPathwebhookHostwebhookPortwebhookSecretwebhookUrl
怎么判断切换成功
这件事不能只看“服务还活着”,要看 Telegram 的投递链路是不是已经真的切成 webhook。
我判断成功主要看两类信号。
第一类是日志:
[telegram] webhook local listener on http://127.0.0.1:8787/telegram-main
[telegram] webhook advertised to telegram on https://.../telegram-main
第二类是行为:
- 连续发几条消息
- 不再出现那种偶发性长时间无响应
- 服务重启后,消息链路仍然稳定
结尾
我最后从 long polling 切到 webhook,本质上是在替换 OpenClaw 与 Telegram 的消息进入机制。如果大家感兴趣的话,下一篇我会出一个Tailscale Funnel的详细配置教程
关键词: OpenClaw、Telegram Bot API、getUpdates、setWebhook、long polling、webhook、Tailscale Funnel

浙公网安备 33010602011771号