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

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")

方案对比

  • 方案一:适合需要长期保留删除权限的场景,即使机器人重启后(若做持久化存储)仍能处理旧消息,但需维护关联字典,定期清理过期记录避免内存占用过高。
  • 方案二:仅针对单条回复消息监听反应,逻辑更清晰,资源消耗小,但超时后将失去删除权限,适合短期有效删除需求。

注意事项

  1. 必须开启机器人的message_content和reactions intents,否则无法接收消息内容和反应事件。
  2. 方案一若需持久化关联数据,可将字典内容存入数据库或本地文件,重启后加载。
  3. 方案二中的超时时间可根据需求调整,设置为None则永不超时(不推荐,会持续占用资源)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:35:07