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

Django异步上下文报错:“不能从异步上下文调用”,Telegram Bot如何修复?

Django异步Telegram Bot调用send_message报错的修复方案

问题重现

我在Django中开发Telegram Bot时使用异步方法,代码如下:

@dp.message(Command('habits'))
async def handle_habits(message: types.Message):
    chat_id = message.chat.id

    profile = await TelegramProfile.objects.aget(chat_id=chat_id)
    user = profile.user

    await bot.send_message(chat_id, text=f'user - {user}')

执行最后一行时触发错误:You cannot call this from an async context - use a thread or sync_to_async。

错误原因

当前使用的bot实例是同步版本,其send_message方法是同步阻塞调用,无法直接在Django的异步上下文环境中执行。

修复方法

方法1:用sync_to_async包装同步方法

借助Django提供的asgiref.sync.sync_to_async工具,将同步的send_message方法转为异步调用:

from asgiref.sync import sync_to_async

@dp.message(Command('habits'))
async def handle_habits(message: types.Message):
    chat_id = message.chat.id

    profile = await TelegramProfile.objects.aget(chat_id=chat_id)
    user = profile.user

    # 包装同步方法后异步调用
    await sync_to_async(bot.send_message)(chat_id, text=f'user - {user}')

方法2:切换为异步版Telegram Bot库

如果使用的是python-telegram-bot库,直接升级到支持异步的版本(v13及以上),使用异步API编写代码,避免同步异步混合调用的问题:

from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes

# 初始化异步Bot应用
application = ApplicationBuilder().token("你的Bot令牌").build()

async def handle_habits(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    profile = await TelegramProfile.objects.aget(chat_id=chat_id)
    user = profile.user
    
    # 直接调用异步send_message方法
    await context.bot.send_message(chat_id=chat_id, text=f'user - {user}')

# 注册命令处理器
application.add_handler(CommandHandler("habits", handle_habits))

# 启动Bot
application.run_polling()

注:原代码中字符串格式错误text=user - {user}'已修正为text=f'user - {user}',使用f-string实现变量插值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 23:50:06