Ubuntu虚拟机中无法启用Telegram Bot Webhook问题求助
Telegram Bot Webhook 部署问题解决
一、WEBHOOK_HOST 取值逻辑
- 公网服务器部署:直接填写服务器公网IP或绑定的域名,需满足两个条件:
- 使用Telegram允许的webhook端口:443/80/88/8443
- 配置有效的SSL证书(公网证书如Let's Encrypt更可靠,自签证书需在设置webhook时上传)
- 本地虚拟机测试(无公网IP):使用ngrok等反向代理工具,WEBHOOK_HOST必须填ngrok提供的完整HTTPS地址(如
https://9339-31-41-61-134.eu.ngrok.io),且ngrok需映射到CherryPy监听的端口。
二、现有问题分析
- ngrok配置失效:你之前设置
WEBHOOK_PORT = 80,但代码中CherryPy监听443端口,端口不匹配导致Telegram请求无法到达服务。 - 127.0.0.1无法工作:该地址是本地回环地址,仅虚拟机自身可访问,Telegram服务器无法连接,因此无响应或报错。
- 代码潜在问题:
while True循环无意义:CherryPy启动后会阻塞进程,循环无法重复执行,还可能导致重复设置webhook。- SSL配置冲突:使用ngrok时无需自定义SSL证书,ngrok自带SSL;公网部署时自签证书可能不被Telegram认可。
三、修正方案
方案1:ngrok本地测试
- 启动ngrok,映射到CherryPy监听端口(以80端口为例):
ngrok http 80 - 修改代码配置:
import json import telebot import requests from decimal import Decimal as dec from telebot import types from telebot.types import InputMediaPhoto, InputMediaVideo import psycopg2 import cherrypy import config # 替换为ngrok提供的完整HTTPS地址 WEBHOOK_HOST = 'https://9339-31-41-61-134.eu.ngrok.io' WEBHOOK_PORT = 80 WEBHOOK_LISTEN = '0.0.0.0' # 注释SSL相关配置,ngrok自带SSL # WEBHOOK_SSL_CERT = './webhook_cert.pem' # WEBHOOK_SSL_PRIV = './webhook_pkey.pem' WEBHOOK_URL_BASE = WEBHOOK_HOST WEBHOOK_URL_PATH = "/%s/" % (config.token) cherrypy.config.update({ 'server.socket_host': WEBHOOK_LISTEN, 'server.socket_port': WEBHOOK_PORT }) bot = telebot.TeleBot(config.token) class WebhookServer(object): @cherrypy.expose def index(self): if 'content-length' in cherrypy.request.headers and \ 'content-type' in cherrypy.request.headers and \ cherrypy.request.headers['content-type'] == 'application/json': length = int(cherrypy.request.headers['content-length']) json_string = cherrypy.request.body.read(length).decode("utf-8") update = telebot.types.Update.de_json(json_string) bot.process_new_updates([update]) return '' else: cherrypy.process.wspbus.bus.exit() # 去掉无效循环,仅启动一次 bot.remove_webhook() bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH) cherrypy.quickstart(WebhookServer(), WEBHOOK_URL_PATH, {'/': {}})
方案2:公网服务器部署
- 放行服务器防火墙/安全组的443端口。
- 申请Let's Encrypt免费SSL证书(以域名为例):
sudo apt install certbot sudo certbot certonly --standalone -d your-domain.com - 修改代码配置:
WEBHOOK_HOST = 'your-domain.com' # 替换为你的域名 WEBHOOK_PORT = 443 WEBHOOK_LISTEN = '0.0.0.0' # 替换为certbot生成的证书路径 WEBHOOK_SSL_CERT = '/etc/letsencrypt/live/your-domain.com/fullchain.pem' WEBHOOK_SSL_PRIV = '/etc/letsencrypt/live/your-domain.com/privkey.pem' WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT) WEBHOOK_URL_PATH = "/%s/" % (config.token) cherrypy.config.update({ 'server.socket_host': WEBHOOK_LISTEN, 'server.socket_port': WEBHOOK_PORT, 'server.ssl_module': 'builtin', 'server.ssl_certificate': WEBHOOK_SSL_CERT, 'server.ssl_private_key': WEBHOOK_SSL_PRIV }) # 其余代码同方案1,去掉while循环
内容的提问来源于stack exchange,提问作者KrekerMeister
相关产品推荐
相关产品推荐

