Discord.py每日零点调度异步函数失效问题求助
问题分析与解决
你的定时任务未执行的核心原因是**client.run()是阻塞调用**,它会持续运行直到机器人关闭,因此后续的send.start()永远不会被触发执行。
修正方案
将任务启动逻辑调整到client.run()之前,或者更规范地在on_ready事件中启动任务(避免机器人重连时重复启动)。
方法1:调整启动顺序
if __name__ == '__main__': send.start() # 先启动定时任务 client.run(os.getenv('TOKEN'))
方法2:在on_ready事件中启动(推荐)
@client.event async def on_ready(): print(f'Logged in as {client.user}') # 确保任务仅启动一次 if not send.is_running(): send.start() if __name__ == '__main__': client.run(os.getenv('TOKEN'))
其他注意事项
- 补充必要的模块导入:你的
before_send函数用到了datetime和timedelta,需要添加导入语句:from datetime import datetime, timedelta - 时区与等待时间优化:
datetime.now()使用本地时区,若机器人服务器时区非UTC,建议改用datetime.utcnow()并调整目标时间;同时等待时间应使用total_seconds()而非seconds,避免丢失天数部分的计时,也可以直接用Discord.py提供的discord.utils.sleep_until()简化逻辑。 - 增加频道存在判断:发送消息前先校验频道是否存在,避免因频道ID错误或权限问题导致任务中断。
完整修正示例代码
import discord from discord.ext import tasks from datetime import datetime, timedelta from dotenv import load_dotenv import os load_dotenv() client = discord.Client(intents=discord.Intents.all()) updays = [0] @tasks.loop(hours=24) async def send(): updays[0] += 1 channel = client.get_channel(XXXXXXXXXXXXXXXXX) if channel: await channel.send(f"It has been {updays[0]} days.") @send.before_loop async def before_send(): hour, minute = 0, 0 await client.wait_until_ready() now = datetime.now() future = datetime(now.year, now.month, now.day, hour, minute) if now >= future: future += timedelta(days=1) await discord.utils.sleep_until(future) @client.event async def on_ready(): print(f'Logged in as {client.user}') if not send.is_running(): send.start() if __name__ == '__main__': client.run(os.getenv('TOKEN'))
内容的提问来源于stack exchange,提问作者Aharon K
相关产品推荐
相关产品推荐

