在Django中配置异步python-telegram-bot(PTB)Webhook遇超时问题求助
Django集成python-telegram-bot 21.0.1 解决httpcore.ConnectTimeout问题
问题根源
python-telegram-bot的async with application:语句在进入上下文时,会自动尝试与Telegram API建立连接(比如获取Webhook配置、初始化Bot参数)。如果你的运行环境无法直接访问Telegram API(本地无代理、防火墙拦截等),就会触发ConnectTimeout错误。而你在FastAPI中的成功实现,大概率是将PTB初始化逻辑延迟到了请求处理阶段,避免了启动时的阻塞。
解决方案
1. 延迟PTB初始化时机
不要在Django启动入口(如asgi.py、settings.py)直接执行async with application:,而是将PTB逻辑封装到Webhook视图中,仅在Telegram请求到来时才初始化并处理:
# views.py from django.http import JsonResponse from telegram import Update from telegram.ext import Application, CommandHandler, ContextTypes async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("Hello from Django!") async def telegram_webhook(request): if request.method != "POST": return JsonResponse({"status": "error"}, status=405) # 仅在请求触发时初始化PTB应用 application = Application.builder().token("YOUR_BOT_TOKEN").build() application.add_handler(CommandHandler("start", start)) # 解析并处理Telegram更新 update = Update.de_json(request.body.decode(), application.bot) await application.process_update(update) return JsonResponse({"status": "ok"})
2. 配置Telegram API代理(按需)
如果环境无法直接访问Telegram API,给PTB的HTTP客户端配置代理:
from httpx import AsyncClient, Proxy # 替换为你的代理地址 proxy = Proxy(url="http://your-proxy-address:port") application = Application.builder().token("YOUR_BOT_TOKEN").http_client(AsyncClient(proxy=proxy)).build()
3. 异步启动PTB后台任务(若需常驻)
如果需要让PTB保持常驻连接(比如轮询模式),不要在启动时同步阻塞,用异步任务并行运行Django和PTB:
# asgi.py import os import asyncio from django.core.asgi import get_asgi_application from telegram.ext import Application os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'yourproject.settings') django_asgi_app = get_asgi_application() async def run_ptb(): application = Application.builder().token("YOUR_BOT_TOKEN").build() async with application: await application.run_polling() # 或设置Webhook async def main(): await asyncio.gather(django_asgi_app, run_ptb()) application = main()
4. 验证Webhook请求格式
用Postman模拟请求时,确保符合Telegram要求:
- 请求方法为POST
- 请求体是标准的Telegram Update JSON结构
- 若已设置Webhook,确保Django服务可被公网访问
错误日志排查方向
从终端日志确认超时阶段:
- 若在
application.__aenter__()阶段超时:是PTB初始化时连接Telegram API失败 - 若在处理Update时超时:是请求处理过程中的网络问题
FastAPI成功案例对比
FastAPI中你可能是将PTB初始化放在路由函数内,或者用lifespan异步上下文管理启动PTB,而Django默认启动逻辑易导致异步连接被同步阻塞,这是两者的核心差异点。
内容的提问来源于stack exchange,提问作者Mortaza Faryabi
相关产品推荐
相关产品推荐

