使用telepot开发的电报机器人被拉黑或移出群组后持续报错、重复打印旧消息的问题咨询
问题根源
报错本质是Telegram Bot服务端未收到已处理更新的确认信号,导致所有历史待发更新长期积压在队列中被反复拉取:
- 拉黑机器人、将机器人移出群组的操作,本身会生成对应的会话状态变更更新存入服务端队列
- 如果之前的机器人进程异常退出、网络连接中断,或是同时有多个进程使用同一Token调用接口,已经拉取过的更新不会被标记为已确认,会一直留在队列中反复返回
- 这些积压更新对应的会话状态已经发生变化(用户已拉黑机器人、机器人已退出群组),机器人尝试处理这些旧更新时,就会因为权限不足、会话不存在触发持续报错
- 观察到接口返回甚至包含已删除的历史消息,就是因为这些消息对应的更新还在服务端队列中没有被清除
修复步骤
第一步:清空积压待处理更新
不需要手动逐次拉取计算offset,直接调用接口一步完成清理即可:
import telepot TOKEN = "你的机器人Token" bot = telepot.Bot(TOKEN) # 清理逻辑:移除可能存在的Webhook配置,同时丢弃所有积压的待处理更新 bot.deleteWebhook(drop_pending_updates=True) print("服务端历史积压更新已全部清除")
注意:执行这一步前必须确保没有其他进程在运行该机器人的监听逻辑,否则会因为接口权限冲突(409 Conflict报错)无法完成清理。
第二步:改造原有代码避免问题复现
原代码直接启动消息循环没有做前置检查,很容易再次触发积压问题,修改后的完整可运行代码如下:
import telepot from pprint import pprint import time TOKEN = "你的机器人Token" def handler(msg): content, chat, msg_id = telepot.glance(msg) pprint(msg) bot = telepot.Bot(TOKEN) # 启动监听前执行前置清理 bot.deleteWebhook(drop_pending_updates=True) # 启动长轮询消息监听 bot.message_loop(handler) print("机器人启动成功,正在监听消息") # 维持进程运行 while True: time.sleep(10)
长期避坑提示
- 同一个机器人Token绝对不要同时在多个进程/服务器上运行长轮询监听,否则会互相抢占接口请求权,导致部分更新永远得不到确认,形成反复拉取历史更新的循环
- 如果后续切换到Webhook模式接收消息,调用
setWebhook接口时带上drop_pending_updates=True参数,即可直接跳过所有历史积压更新 - telepot 12.7版本本身的长轮询逻辑可以自动维护offset续接,触发积压问题绝大多数都是因为多进程抢占接口、或是异常退出时没来得及把已处理的offset回传给服务端
内容的提问来源于stack exchange,提问作者ciprinani
相关产品推荐
相关产品推荐

