如何修复discord.py中Snipe命令显示其他Guild删除消息的问题?
解决Snipe命令跨服务器显示删除消息的问题
我明白你的问题所在啦——你现在用的全局变量会让所有服务器共享同一条删除消息的记录,所以切换服务器执行snipe时,就会拿到其他服务器的内容。咱们把代码改成按服务器隔离存储就能解决这个问题,具体改动如下:
问题根源
你的snipe_message_content和snipe_message_author是全局变量,不管哪个服务器删除消息,都会覆盖这两个变量的值。这就导致所有服务器共用同一组数据,自然会出现串台的情况。
修改后的代码
import asyncio import discord # 用字典存储每个服务器的snipe数据,键为服务器ID,值包含消息内容、作者和超时任务 snipe_data = {} @client.event async def on_message_delete(message): # 跳过DM频道(如果不需要支持DM可以去掉这个判断) if not message.guild: return guild_id = message.guild.id # 如果当前服务器已有未过期的snipe记录,先取消之前的超时任务 if guild_id in snipe_data: snipe_data[guild_id]["timeout_task"].cancel() # 存储当前删除的消息数据 snipe_data[guild_id] = { "content": message.content, "author": message.author.name, # 创建新的超时任务,60秒后清空该服务器的snipe记录 "timeout_task": asyncio.create_task(clear_snipe(guild_id)) } async def clear_snipe(guild_id): await asyncio.sleep(60) # 确保该服务器的记录还存在时再删除 if guild_id in snipe_data: del snipe_data[guild_id] @client.command() async def snipe(ctx): # 处理DM频道的情况 if not ctx.guild: await ctx.send("Snipe命令只能在服务器中使用哦!") return guild_id = ctx.guild.id snipe_info = snipe_data.get(guild_id) if not snipe_info: await ctx.send("Nothing to snipe is found here!") else: embed = discord.Embed(description=f"{snipe_info['content']}", color=ctx.author.color) embed.set_footer(text=f"Requested By {ctx.author.name}#{ctx.author.discriminator}") embed.set_author(name=f"Sniped the message deleted by : {snipe_info['author']}") await ctx.send(embed=embed)
关键改动说明
- 按服务器隔离存储:用
snipe_data字典替代全局变量,每个服务器的ID作为唯一键,确保不同服务器的删除消息数据完全独立。 - 独立的超时机制:每个服务器的snipe记录都有自己的超时任务,新消息删除时会取消之前的超时任务,避免提前清空最新的记录。
- 规范的命令参数:把命令参数从
message改成ctx(discord.py的标准上下文对象),能更方便地获取服务器ID、作者信息等上下文数据。 - DM频道处理:新增了对DM频道的判断,避免在无服务器环境下出错(如果不需要可以删掉相关逻辑)。
这样修改后,每个服务器的snipe命令只会显示当前服务器内最近删除的消息,不会再串台啦!
内容的提问来源于stack exchange,提问作者ChaoticNebula
相关产品推荐
相关产品推荐

