discord.py:如何仅允许原触发用户通过反应删除消息及原消息
实现Discord机器人仅允许原用户删除自动回复消息
需求:当机器人根据关键词自动回复消息后,仅允许触发回复的原用户通过点击❌表情,同时删除原消息和机器人的回复消息。
方案一:全局反应事件+关联信息存储
通过维护一个字典记录机器人消息与原消息、原作者的关联,在全局反应事件中校验权限并执行删除。
import discord from discord import Client # 初始化客户端,确保开启所需intents intents = discord.Intents.default() intents.message_content = True intents.reactions = True client = Client(intents=intents) # 存储机器人消息ID -> (原作者ID, 原消息ID) msg_association = {} @client.event async def on_reaction_add(reaction, user): # 跳过机器人自身的反应 if user.bot: return # 只处理机器人发送的消息 if reaction.message.author.id != client.user.id: return msg_id = reaction.message.id # 检查当前消息是否有对应的关联记录 if msg_id not in msg_association: return original_author_id, original_msg_id = msg_association[msg_id] # 校验表情和用户权限 if reaction.emoji == "❌" and user.id == original_author_id: # 获取原消息并删除 original_msg = await reaction.message.channel.fetch_message(original_msg_id) await original_msg.delete() await reaction.message.delete() # 清理关联记录 del msg_association[msg_id] @client.event async def on_message(message): if message.author.bot: return msg = "" # 替换为你的关键词判断逻辑,示例: # if "触发关键词" in message.content.lower(): # msg = "机器人自动回复内容" if msg: new_msg = await message.channel.send(msg) await new_msg.add_reaction("❌") # 记录关联信息 msg_association[new_msg.id] = (message.author.id, message.id) await client.process_commands(message) # 替换为你的机器人token client.run("YOUR_BOT_TOKEN")
方案二:使用wait_for监听单条消息反应
无需全局事件,在发送回复后直接监听该消息的反应,逻辑更简洁,资源占用更低。
import discord from discord import Client, Reaction, User intents = discord.Intents.default() intents.message_content = True intents.reactions = True client = Client(intents=intents) @client.event async def on_message(message): if message.author.bot: return msg = "" # 替换为你的关键词判断逻辑 # if "触发关键词" in message.content.lower(): # msg = "机器人自动回复内容" if msg: new_msg = await message.channel.send(msg) await new_msg.add_reaction("❌") # 定义反应校验条件:仅原作者的❌反应 def reaction_check(reaction: Reaction, user: User): return (reaction.message.id == new_msg.id and reaction.emoji == "❌" and user.id == message.author.id and not user.bot) try: # 等待反应,超时时间可自定义(示例为10分钟) await client.wait_for('reaction_add', timeout=600.0, check=reaction_check) except TimeoutError: # 超时后移除表情,也可留空不处理 await new_msg.clear_reactions() else: # 同时删除两条消息 await message.delete() await new_msg.delete() await client.process_commands(message) client.run("YOUR_BOT_TOKEN")
方案对比
- 方案一:适合需要长期保留删除权限的场景,即使机器人重启后(若做持久化存储)仍能处理旧消息,但需维护关联字典,定期清理过期记录避免内存占用过高。
- 方案二:仅针对单条回复消息监听反应,逻辑更清晰,资源消耗小,但超时后将失去删除权限,适合短期有效删除需求。
注意事项
- 必须开启机器人的
message_content和reactionsintents,否则无法接收消息内容和反应事件。 - 方案一若需持久化关联数据,可将字典内容存入数据库或本地文件,重启后加载。
- 方案二中的超时时间可根据需求调整,设置为
None则永不超时(不推荐,会持续占用资源)。
内容的提问来源于stack exchange,提问作者mdssi
相关产品推荐
相关产品推荐

