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

手动调用正常但调度器调用崩溃的Aiogram Telegram机器人问题

解决aiogram中APScheduler定时任务无法获取Bot实例的问题

问题核心在于:aiogram依赖ContextVar(即报错中的instance_Bot)存储Bot实例,但APScheduler的定时任务运行在独立的异步上下文环境中,不会自动继承aiogram的上下文信息,导致调用依赖上下文的函数时触发LookupError。以下是几种可行的解决方案:

方法1:手动将Bot实例绑定到定时任务上下文

在定时任务执行目标函数前,手动将Bot实例注入aiogram的上下文变量中:

from aiogram.utils.context import ContextInstanceMixin
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from aiogram import Bot

# 全局Bot实例(确保仅初始化一次)
bot = Bot(token="YOUR_TELEGRAM_BOT_TOKEN")

async def send_text():
    # 原函数逻辑,无需修改
    users = get_all_bot_users()  # 假设这是获取所有用户ID的函数
    for user_id in users:
        await bot.send_message(user_id, "随机消息内容+当日节日提示")

async def scheduled_send_text():
    # 手动绑定Bot实例到当前上下文
    ContextInstanceMixin.set_current(bot)
    await send_text()

# 初始化并启动调度器
scheduler = AsyncIOScheduler(timezone="Asia/Shanghai")
scheduler.add_job(scheduled_send_text, "cron", hour=19, minute=10)
scheduler.start()

方法2:修改send_text函数,显式接收Bot参数

彻底摆脱上下文依赖,让函数直接接收Bot实例作为参数:

from aiogram import Bot
from apscheduler.schedulers.asyncio import AsyncIOScheduler

bot = Bot(token="YOUR_TELEGRAM_BOT_TOKEN")

# 修改函数,显式传入Bot实例
async def send_text(bot: Bot):
    users = get_all_bot_users()
    for user_id in users:
        await bot.send_message(user_id, "随机消息内容+当日节日提示")

# 定时任务直接传入Bot实例
async def scheduled_task():
    await send_text(bot)

scheduler = AsyncIOScheduler(timezone="Asia/Shanghai")
scheduler.add_job(scheduled_task, "cron", hour=19, minute=10)
scheduler.start()

方法3:利用Dispatcher上下文(若项目使用Dispatcher)

如果项目基于Dispatcher开发,可以通过bot.context()上下文管理器确保Bot实例被正确识别:

from aiogram import Bot, Dispatcher
from apscheduler.schedulers.asyncio import AsyncIOScheduler

bot = Bot(token="YOUR_TELEGRAM_BOT_TOKEN")
dp = Dispatcher(bot)

async def send_text():
    users = get_all_bot_users()
    for user_id in users:
        await bot.send_message(user_id, "随机消息内容+当日节日提示")

async def scheduled_send_text():
    async with bot.context():
        await send_text()

scheduler = AsyncIOScheduler(timezone="Asia/Shanghai")
scheduler.add_job(scheduled_send_text, "cron", hour=19, minute=10)
scheduler.start()

注意事项

  • 确保Bot实例全局唯一,避免重复初始化导致的上下文冲突
  • 定时任务的异步循环需与aiogram的事件循环保持一致(直接使用项目默认的asyncio循环即可)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:55:01