Telegram机器人连接超时求助:Python+CherryPy Webhook模式故障排查
排查Telegram Webhook连接超时问题
从你提供的get_webhook_info返回信息来看,核心问题是Connection timed out——Telegram服务器无法成功连接到你的Webhook端点。咱们一步步来排查:
1. 先检查Webhook URL的合理性
你当前的URL是https://IP/571605115:token/,这里有几个潜在问题:
- 直接用公网IP没问题,但要确保这个IP是公网可访问的,不是内网IP;
- Telegram只允许Webhook使用特定端口:443(默认HTTPS端口)、80、88、8443。如果你的CherryPy服务跑在其他端口(比如8000),Telegram根本连不上,这是常见的超时原因;
- 路径里的
571605115:token是机器人的token吗?虽然把token放在路径里做鉴权是可行的,但要确保你的CherryPy路由正确匹配了这个路径,能接收POST请求。
2. 验证服务器的网络连通性
超时最常见的原因是外部无法访问你的服务器端点:
- 先检查服务器的防火墙(包括系统自带的
ufw/firewalld,以及云服务商的安全组),确保你使用的端口(比如443)是开放的入站端口; - 用另一台外网机器测试连接:比如运行
telnet 你的公网IP 443,如果连接失败,说明端口没开或者服务器没监听这个端口; - 用
curl模拟POST请求测试:
如果curl也超时,那问题肯定在网络/服务器监听配置上,和Telegram无关。curl -X POST https://你的公网IP/你的路径 -v
3. 检查自定义证书的有效性
返回里显示has_custom_certificate: true,证书配置错误也会导致连接失败:
- 证书必须是PEM格式,并且包含完整的证书链(如果是CA签发的);
- 如果是自签名证书,你必须在调用
set_webhook时通过cert参数把证书上传给Telegram,否则Telegram会因为无法验证证书而拒绝连接; - 证书的**通用名称(CN)**必须和Webhook URL里的IP/域名完全一致,否则会触发SSL验证错误,最终导致超时。
4. 确认CherryPy的HTTPS配置
Telegram要求Webhook必须使用HTTPS(localhost测试除外),所以CherryPy必须正确配置SSL:
import cherrypy class WebhookHandler: @cherrypy.expose def index(self): # 处理Telegram的POST请求 if cherrypy.request.method == 'POST': data = cherrypy.request.body.read() # 解析并处理消息逻辑 return 'ok' return 'Method not allowed' if __name__ == '__main__': cherrypy.config.update({ 'server.socket_host': '0.0.0.0', # 监听所有网卡 'server.socket_port': 443, # 使用Telegram允许的端口 'server.ssl_module': 'builtin', 'server.ssl_certificate': '/path/to/your/cert.pem', 'server.ssl_private_key': '/path/to/your/private.key', }) cherrypy.quickstart(WebhookHandler(), '/571605115:token') # 匹配你的URL路径
注意:如果你的服务器普通用户无法监听443端口(需要root权限),可以考虑用反向代理(比如Nginx)来处理HTTPS,CherryPy跑在本地端口,由Nginx转发请求。
5. 清理pending更新
等你解决连接问题后,可以调用delete_webhook清除当前的Webhook配置,然后重新设置,同时清理pending的更新:
import requests TOKEN = '你的机器人token' requests.post(f'https://api.telegram.org/bot{TOKEN}/deleteWebhook') # 重新设置Webhook,确保cert参数正确(如果用自签名证书) requests.post(f'https://api.telegram.org/bot{TOKEN}/setWebhook', json={'url': 'https://你的公网IP/正确路径'}, files={'cert': open('/path/to/cert.pem', 'rb')})
按照这个顺序排查,应该能解决超时问题。
内容的提问来源于stack exchange,提问作者Timur Nasyrov
相关产品推荐
相关产品推荐

