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

Py-Cord中dmuser命令重复执行3次,为何发送3次DM并记录?

Py-Cord命令重复执行3次的排查方案

问题描述

我编写了一个Py-Cord命令,用于匿名向用户发送私信并记录交互,但该命令会重复执行3次——发送3条私信、生成3条记录,而预期应该仅执行一次。代码如下:

@bot.command(name="dmuser", description="Send an anonymous DM to a user")
@guild_only()
async def dmuser(ctx, user: discord.Option(discord.Member, "Who to send the DM to?"), msg):
    if ctx.author.id in blocked_users_dmuser:
        await ctx.respond("Hm, it seems like you don't have permission to run this. Please contact TheMineCommander#5367 or use /support if you believe this is an error.", ephemeral=True)
        return
    elif user not in ctx.guild.members:
        await ctx.respond("This user is not in your guild.", ephemeral=True)
        return
    else:
        dmchannel = await bot.create_dm(user)
        uuid = random.choices(string.ascii_lowercase + string.digits, k=20)
        uuid = ''.join(uuid)
        msg = msg.replace("\n", "\n")
        await dmchannel.send(f"You got an anonymous DM from **{ctx.guild}**!\n--\n```\n{msg}\n```\n--\nIf you would like to report this message, please contact TheMineCommander#5367.\nThe message UUID is `{uuid}`.")
        async with aiohttp.ClientSession() as session:
            webhook = discord.Webhook.from_url('https://discord.com/api/webhooks/1091580748131217519/URL CUT OUT FOR SECURITY', session=session)
            await webhook.send(f"Author: {ctx.author.id}, {ctx.author.name}\nFrom server: {ctx.guild.name}, {ctx.guild.id}\nRecipient: {user},\nUUID: {uuid}\n\n\n```\n{msg}\n```")
        await ctx.respond("Sent DM!", ephemeral=True)

可能的原因及解决办法

  • 命令重复注册:检查代码是否多次加载了该命令(比如同一个文件被重复import,或者bot.start()被调用了多次)。Py-Cord会为每个注册的命令实例触发一次执行,重复注册直接导致多次执行。解决:确保命令只被注册一次,bot.start()只调用一次。
  • Discord API重试机制:网络波动时,Discord可能会多次发送命令触发的事件,导致bot重复响应。解决:添加幂等性校验——比如用ctx.interaction.id作为唯一标识,维护一个已处理请求的集合,执行前先检查该ID是否已经处理过,避免重复执行。
  • 多Bot实例:确认代码只初始化了一个Bot对象,如果不小心创建了多个实例并启动,每个实例都会响应命令。解决:全局只保留一个bot实例,检查代码中是否有重复初始化的逻辑。
  • 热重载工具干扰:如果使用了热重载工具(比如discord.ext.commands.reload),可能会导致命令被重复注册。解决:关闭热重载,重启bot后测试。

临时修复示例(添加幂等校验)

可以在命令开头加入简单的幂等校验,避免重复执行:

# 全局维护已处理的请求ID集合(重启后清空,长期可用数据库/Redis替代)
processed_interactions = set()

@bot.command(name="dmuser", description="Send an anonymous DM to a user")
@guild_only()
async def dmuser(ctx, user: discord.Option(discord.Member, "Who to send the DM to?"), msg):
    # 校验是否已处理过该请求
    if ctx.interaction.id in processed_interactions:
        return
    processed_interactions.add(ctx.interaction.id)
    
    # 原有的命令逻辑...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:37:32