You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 17:56:17