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

使用discord.py开发提醒命令出现_asyncio.Future不可下标错误

问题原因与修复方案

核心报错原因

你使用的是异步MongoDB驱动(如Motor),collection.find({}).to_list()为异步方法,未添加await关键字时返回的是_asyncio.Future对象而非实际查询结果列表,遍历该对象时自然无法通过下标读取属性,触发对应报错。

其余隐藏问题

  • 额外的集合包装与冗余时间解析:你将reminder['time']用{}包裹会生成集合对象,且你存入数据库的time字段本身就是datetime类型,无需转字符串再用strptime二次解析。
  • 实例属性引用错误:类初始化存储的是self.bot,你后续调用self.client.get_guild不存在,会触发属性错误。
  • 时间解析逻辑错误:int(time[0])仅支持个位数时长输入,输入如10h时只会取第一位的1计算,结果完全不符合预期。
  • 未删除到期提醒:触发后的提醒未从数据库删除,会导致每次定时任务执行都重复给用户发消息。

修正后代码

from datetime import datetime, timedelta
import discord
from discord.ext import commands, tasks
# 确保你用的是异步Motor驱动的collection实例

class remind(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.reminder_task.start()

    def cog_unload(self):
        self.reminder_task.cancel()

    @tasks.loop(minutes=1.0)
    async def reminder_task(self):
        # 加await获取实际查询结果
        data = await collection.find({}).to_list(length=None)
        now = datetime.now()
        for reminder in data:
            # 直接取datetime类型的time字段,无需转义解析
            remind_time = reminder['time']
            if now >= remind_time:
                # 用self.bot替代不存在的self.client
                guild = self.bot.get_guild(reminder['GuildID'])
                if guild:
                    member = guild.get_member(reminder['author_id'])
                    if member:
                        try:
                            await member.send(f"Reminder: `{reminder['msg']}`")
                        except:
                            # 处理用户关闭DM的情况
                            pass
                # 提醒触发后从数据库删除对应记录,避免重复发送
                await collection.delete_one({"_id": reminder['_id']})

    @slash_commands.command(name="remind", description="create a reminder!", options=[Option("time", "time until I remind you", Type.STRING, required=True), Option("reminder", "what should I remind you about?", Type.STRING, required=True)], guild_ids=bonbot_support)
    async def remind(self, ctx, time, reminder):
        if ctx.author.bot:
            return
        time_conversion = {"s": 1, "m": 60, "h": 3600, "d": 86400, "w": 604800}
        # 修正时间解析逻辑,取除最后一位外的所有字符转int
        try:
            remindseconds = int(time[:-1]) * time_conversion[time[-1].lower()]
        except:
            await ctx.send("时间格式错误,示例:10m、2h、3d", ephemeral=True)
            return
        remindertime = datetime.now() + timedelta(seconds=remindseconds)
        author_id = ctx.author.id
        guild_id = ctx.guild.id

        rem_info = {"author_id": author_id, "GuildID": guild_id, "time": remindertime, "msg": reminder}
        await collection.insert_one(rem_info)
        await ctx.send(f'Reminder was set! 我会在{remindertime.strftime("%Y-%m-%d %H:%M")}提醒你', ephemeral=True)


def setup(bot):
    bot.add_cog(remind(bot))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:06:10