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

Discord Bot反应权限控制求助:需先添加🦵才能添加👍

解决方案

一、实现「先加🦵才能加👍」的反应限制逻辑

修改on_reaction_add事件,在用户添加👍时,检查该用户是否已对同一条消息添加过🦵反应,未添加则移除👍。同时保留原有的仅允许🦵和👍的限制:

@client.event
async def on_reaction_add(reaction, user):
    if client.user == user:
        return
    
    # 仅允许指定的两种表情,其他直接移除
    allowed_emojis = ('🦵', '👍')
    if reaction.emoji not in allowed_emojis:
        await reaction.remove(user)
        return
    
    # 检查添加👍的用户是否已添加过🦵
    if reaction.emoji == '👍':
        has_leg_react = False
        # 遍历消息的所有反应,找到🦵对应的反应项
        for msg_react in reaction.message.reactions:
            if msg_react.emoji == '🦵':
                # 获取该反应的所有用户列表(需用flatten()拉取完整数据)
                react_users = await msg_react.users().flatten()
                if user in react_users:
                    has_leg_react = True
                    break
        # 未找到🦵反应则移除当前的👍
        if not has_leg_react:
            await reaction.remove(user)

二、修复on_reaction_remove事件不触发的问题

事件无响应大概率是未开启Discord所需的Intents,其次是代码中的语法问题(比如中文引号),按以下步骤修复:

1. 初始化客户端时开启必要的Intents

Discord.py v1.5+ 必须显式开启对应Intents才能触发反应类事件,修改客户端初始化代码:

import discord

# 初始化Intents,开启反应、消息、成员相关权限
intents = discord.Intents.default()
intents.reactions = True
intents.messages = True
intents.members = True

# 创建客户端实例(如果用commands.Bot同理)
client = discord.Client(intents=intents)

2. 修正on_reaction_remove代码

替换中文引号,优化频道获取逻辑(可选:用消息所在频道替代硬编码ID):

@client.event
async def on_reaction_remove(reaction, user):
    if client.user == user:
        return
    
    print("1")
    allowed_emojis = ("🦵", "👍")
    if reaction.emoji in allowed_emojis:
        print("2")
        # 方式1:用硬编码的指定频道
        channel = client.get_channel(1245472750164906084)
        # 方式2:用反应所在消息的频道(更灵活)
        # channel = reaction.message.channel
        await channel.send(f"{user.display_name} removed reaction {reaction.emoji}")
        print("3")

补充:处理批量移除反应的情况

如果用户一次性移除所有反应,on_reaction_remove不会触发,需额外监听on_reaction_clear事件:

@client.event
async def on_reaction_clear(message, reactions):
    allowed_emojis = ("🦵", "👍")
    # 筛选出被清空的目标表情
    cleared_targets = [r.emoji for r in reactions if r.emoji in allowed_emojis]
    if cleared_targets:
        channel = client.get_channel(1245472750164906084)
        await channel.send(f"Reactions {', '.join(cleared_targets)} were all removed from this message: {message.jump_url}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:22:12