You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PythonAnywhere部署Telegram Bot Webhook报Bad Request错误求助

解决PythonAnywhere上Telegram Bot Webhook的Bad Request错误

我帮你梳理下这个Bad Request问题的几个关键原因和解决办法,结合PythonAnywhere的部署特性来看,你的配置和代码里有几个容易踩的坑:

1. 冗余的HTTPS证书与端口配置

PythonAnywhere已经为你的username.pythonanywhere.com域名提供了官方可信的HTTPS证书,并且默认通过443端口对外提供服务,完全不需要你手动指定8443端口、加载本地证书文件。你的代码里的PORTCERTCERT_KEY配置,以及app.run中的context参数,在WSGI部署环境下完全无效,甚至可能干扰请求解析。

解决方式

  • 删除代码中所有与PORTCERTCERT_KEY相关的变量和代码
  • 调用set_webhook时不需要传入certificate参数(Telegram信任PythonAnywhere的SSL证书)

2. Webhook未被实际设置

你的setwebhook()函数放在了if __name__ == '__main__'代码块中,但在PythonAnywhere的WSGI部署模式下,这个代码块永远不会执行(WSGI服务器是导入你的Flask app,而非直接运行脚本),导致Webhook根本没被正确配置。

解决方式
你有两种可靠的设置Webhook的方法:

  • 临时执行脚本:在PythonAnywhere的控制台中,进入项目目录,运行python main.py,此时会执行if __name__ == '__main__'里的setwebhook(),看到提示后按Ctrl+C停止即可(WSGI服务已经在后台运行)。
  • 手动调用:在PythonAnywhere的交互式Python控制台中,导入你的bot并手动设置Webhook:
    from main import bot, HOST, TOKEN
    bot.set_webhook(url=f"https://{HOST}/{TOKEN}")
    

3. Flask路由与请求处理的细节优化

虽然你的路由逻辑看起来正确,但有两个细节需要调整:

  • Telegram要求Webhook的响应必须是200 OK的简单文本(比如'OK'),返回HTML可能不会触发错误,但没必要。
  • 要处理可能的无效更新(比如非消息类型的更新,或者解析失败的请求),避免抛出异常导致500错误。

优化后的webhook_handler代码

@app.route('/' + TOKEN, methods=['POST'])
def webhook_handler():
    try:
        update = telegram.Update.de_json(request.get_json(force=True), bot)
        # 只处理有消息的更新
        if update.message:
            bot.send_message(chat_id=update.message.chat.id, text='Hello, there')
        return 'OK'
    except Exception as e:
        # 打印错误日志到PythonAnywhere的控制台
        print(f"Error processing update: {str(e)}")
        # 无论如何都返回200 OK,避免Telegram重复发送请求
        return 'OK', 200

4. 虚拟环境路径配置问题

你的代码中sys.path.append(os.path.join(os.path.abspath('.'), 'path/to/virtualenv/'))存在路径风险:在WSGI环境下,当前工作目录不一定是你的项目目录,相对路径可能无法正确指向虚拟环境。

更可靠的方式

  • 直接在PythonAnywhere的Web管理页面中,找到"Virtualenv"设置项,输入你的虚拟环境绝对路径(比如/home/username/.virtualenvs/your_env),PythonAnywhere会自动将虚拟环境的site-packages加入sys.path,不需要手动在代码中添加。

修改后的完整代码示例

import sys
from flask import Flask, request
import telegram

# CONFIG
TOKEN = '<你的Bot Token>'
HOST = 'username.pythonanywhere.com'

bot = telegram.Bot(TOKEN)
app = Flask(__name__)

@app.route('/')
def hello():
    return '<h1> BITCONNECT!!! </h1>'

@app.route('/' + TOKEN, methods=['POST'])
def webhook_handler():
    try:
        update = telegram.Update.de_json(request.get_json(force=True), bot)
        if update.message:
            bot.send_message(chat_id=update.message.chat.id, text='Hello, there')
        return 'OK'
    except Exception as e:
        print(f"Error processing update: {str(e)}")
        return 'OK', 200

def setwebhook():
    bot.set_webhook(url=f"https://{HOST}/{TOKEN}")

if __name__ == '__main__':
    setwebhook()
    print("Webhook set successfully!")
    # 本地测试时可以打开下面的注释,部署到PythonAnywhere后不需要
    # app.run(host='0.0.0.0', debug=True)

内容的提问来源于stack exchange,提问作者Trafalgar Law

火山引擎 最新活动