Discord Hikari机器人如何每日定时执行async def异步函数?
问题根因
- 插件顶层直接初始化并启动
AsyncIOScheduler时,Lightbulb机器人的事件循环还未完成初始化,Scheduler绑定的事件循环和后续机器人运行使用的循环不是同一个,导致定时任务无法触发。 - 手动调用
asyncio.get_event_loop().run_forever()会永久阻塞当前线程,后续机器人启动的代码完全没有执行机会,自然无法启动机器人。 - 全局导入
bot模块获取实例的方式存在初始化时序问题,可能拿到未完成初始化的机器人实例,导致发消息失败。
修复后的插件代码
import hikari import lightbulb from apscheduler.schedulers.asyncio import AsyncIOScheduler from apscheduler.triggers.cron import CronTrigger daily_plugin = lightbulb.Plugin("Daily") # 仅顶层声明Scheduler,暂不启动 sched = AsyncIOScheduler() async def msg1(): # 直接使用插件绑定的bot实例,无需全局导入bot模块 await daily_plugin.bot.rest.create_message(783996883080708096, "Morning Message") print("Message") # 监听机器人启动完成事件后再启动Scheduler @daily_plugin.listener(hikari.StartedEvent) async def start_scheduler(event: hikari.StartedEvent) -> None: # 按需修改时区,CronTrigger默认使用UTC时区,国内使用需设置为Asia/Shanghai sched.add_job(msg1, CronTrigger(hour=2, minute=0, timezone="Asia/Shanghai")) sched.start() # 插件卸载时停止Scheduler,避免残留任务 def unload(bot: lightbulb.BotApp) -> None: sched.shutdown() def load(bot: lightbulb.BotApp) -> None: bot.add_plugin(daily_plugin)
额外注意事项
- 不需要手动管理事件循环的运行,
BotApp.run()方法会自动启动并管理事件循环的生命周期。 - 如果需要多个定时任务,直接在
start_scheduler函数内添加多个add_job配置即可。
内容的提问来源于stack exchange,提问作者Mentix
相关产品推荐
相关产品推荐

