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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:39:37