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

Discord机器人定时提醒功能失效问题求助

问题排查与修复方案

核心问题分析

  • 上下文未定义: check_notes函数里的await ctx.send(embed=embed)完全错误,这个后台任务没有ctx对象,直接调用会抛出异常,导致提醒无法发送。
  • 任务未启动: 代码里没有启动check_notes这个后台循环任务,机器人根本不会定时检查待发送的提醒。
  • 过时API调用: author.avatar_url是discord.py旧版本的写法,新版本已废弃,会引发属性错误。
  • 时区不一致: 使用datetime.now()(本地时间)处理时间,若机器人运行时区和用户输入时区不同,会导致时间判断错误。

修复后的完整代码

import discord
from discord.ext import commands
import datetime
import asyncio

bot = commands.Bot(command_prefix="!", intents=discord.Intents.all())  # 确保启用必要的Intents
notes = {}

@bot.command()
async def note(ctx, time_str: str, *, message):
    try:
        # 使用UTC时间统一处理,避免时区问题
        time = datetime.datetime.strptime(time_str, "%y.%m.%d %H:%M").replace(tzinfo=datetime.timezone.utc)
        now = datetime.datetime.now(datetime.timezone.utc)
        if time <= now:
            await ctx.send("你选择的是过去的时间,请设置未来的时间。")
            return
        notes[time] = {"author_id": ctx.author.id, "channel_id": ctx.channel.id, "message": message}
        await ctx.send(f"提醒已保存,时间:{time.strftime('%y.%m.%d %H:%M')} (UTC)")
    except ValueError:
        await ctx.send("时间格式错误,请使用 'yy.mm.dd HH:MM' 格式(24小时制)。")

async def check_notes(): 
    await bot.wait_until_ready()
    while not bot.is_closed():
        now = datetime.datetime.now(datetime.timezone.utc)
        for time, note in list(notes.items()):
            if time <= now:
                # 通过ID获取用户和频道,避免上下文丢失
                author = bot.get_user(note["author_id"])
                channel = bot.get_channel(note["channel_id"])
                if author and channel:
                    embed = discord.Embed(
                        title="提醒!",
                        description=f"{author.mention}, 你的提醒:\n{note['message']}",
                        color=discord.Color.blue()
                    )
                    embed.set_thumbnail(url=author.avatar.url if author.avatar else author.default_avatar.url)
                    try:
                        await channel.send(embed=embed)
                    except discord.Forbidden:
                        # 处理无法发送消息的情况(比如频道权限不足)
                        pass
                del notes[time]
        await asyncio.sleep(60)

@bot.command()
async def my_notes(ctx):
    embed = discord.Embed()
    embed.set_author(name="🌌 | 你的提醒", icon_url=ctx.author.avatar.url if ctx.author.avatar else ctx.author.default_avatar.url)
    user_notes = [(t, n) for t, n in notes.items() if n["author_id"] == ctx.author.id]
    if not user_notes:
        embed.description = ":calendar: 你目前没有任何提醒。"
    else:
        note_list = "\n".join([f"• **{t.strftime('%y.%m.%d %H:%M')} (UTC)**: {n['message']}" for t, n in user_notes])
        embed.description = f":calendar: | 你的提醒列表:\n{note_list}"
    await ctx.send(embed=embed)

# 启动后台任务
bot.loop.create_task(check_notes())

bot.run("你的机器人令牌")

关键修复说明

  1. 上下文问题解决: 不再依赖ctx存储提醒,而是保存用户ID和频道ID,在发送时通过bot.get_user()和bot.get_channel()获取对象,确保后台任务能正常发送消息。
  2. 启动后台任务: 添加bot.loop.create_task(check_notes()),让机器人启动时自动运行定时检查任务。
  3. API更新: 替换author.avatar_url为author.avatar.url,并添加默认头像 fallback,避免头像不存在时出错。
  4. 时区统一: 全部使用UTC时间处理,消除时区差异导致的时间判断错误,同时在提示中明确标注UTC时区。
  5. 错误处理: 添加发送消息时的权限错误捕获,避免因权限问题导致任务崩溃。

内容的提问来源于stack exchange,提问作者Domi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:12:13