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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:20:42