Discord机器人工作日定时发Embed用schedule报错:协程未await
问题解决:schedule库调用Discord异步任务的RuntimeWarning及工作日调度实现
错误原因
schedule是同步调度库,任务执行逻辑为同步调用传入函数。但Discord.py的消息发送(包括Embed)属于异步协程(async函数),直接把协程函数传给schedule.do()时,schedule只会调用函数得到协程对象,不会自动await执行,因此触发RuntimeWarning: coroutine was never awaited,任务实际并未运行。
解决方案
继续使用schedule库的话,需要通过同步包装函数调用异步协程,同时在任务内加入工作日判断逻辑,跳过周六周日。
步骤1:编写异步发送消息函数
import discord import asyncio import schedule import datetime # 替换为你的目标频道ID CHANNEL_ID = 1234567890 async def send_workday_embed(): # 获取目标频道 channel = bot.get_channel(CHANNEL_ID) if not channel: print("未找到指定频道") return # 构建Embed消息 embed = discord.Embed( title="工作日通知", description="这是仅在工作日发送的Embed消息", color=discord.Color.blue() ) await channel.send(embed=embed)
步骤2:编写同步包装函数(含工作日判断)
def job_wrapper(): # 判断当前是否为工作日:weekday()返回0=周一,4=周五,5=周六,6=周日 today = datetime.datetime.today().weekday() if today >= 5: print("今日为周末,跳过任务") return # 用asyncio.run执行异步协程 asyncio.run(send_workday_embed())
步骤3:配置schedule调度并嵌入Discord Bot循环
# 设置每日23:18执行任务 schedule.every().day.at("23:18").do(job_wrapper) # 启动schedule的检查循环(需在Discord Bot的异步环境中运行) async def schedule_check_loop(): while True: schedule.run_pending() await asyncio.sleep(60) # 每分钟检查一次任务是否到点 # Bot就绪时启动调度循环 @bot.event async def on_ready(): print(f"已登录为 {bot.user}") # 后台启动schedule检查任务 bot.loop.create_task(schedule_check_loop()) # 运行Bot(替换为你的Bot启动方式) bot.run("YOUR_BOT_TOKEN")
关键说明
- 同步包装函数
job_wrapper负责:判断工作日、调用asyncio.run()执行异步发送逻辑,让schedule可以正常调用同步函数。 schedule_check_loop是异步循环,定期调用schedule.run_pending()检查任务是否到点,避免阻塞Discord Bot的主事件循环。
内容的提问来源于stack exchange,提问作者Daniel Knox
相关产品推荐
相关产品推荐

