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

Discord机器人多on_reaction_add事件冲突问题解决咨询

问题

我做了一个可用的Discord机器人,添加命令时遇到问题:创建了多个on_reaction_add函数,但无法同时生效。尝试改函数名比如on_react_add也没用,始终只能运行其中一个。以下是两个相关的on_reaction_add事件代码,怎么让两者都正常工作?

第一个无法生效的on_reaction_add:

@client.event
async def reaction_add(reaction, user):
    await bot_events.on_reaction_add(reaction, user)

bot_events.on_reaction_add代码:

async def on_reaction_add(reaction, user):

    if user.bot:
        return
    if user.id not in players:
        return
    emoji = reaction.emoji
    await reaction.remove(user)

    if reaction.message != players[user.id]['game']:
        return

    if emoji == "⬅️":
        players[user.id]['dir'] = "left"
    if emoji == "➡️":
        players[user.id]['dir'] = "right"
    if emoji == "⬇️":
        players[user.id]['dir'] = "down"
    if emoji == "⬆️":
        players[user.id]['dir'] = "up"

另一个on_reaction_add:

@client.event
async def on_reaction_add(reaction, user):
    global h_movement
    global rotation_pos
    if user != client.user:
        msg = reaction.message
        if str(reaction.emoji) == "▶": #Play button pressed
            print('User pressed play')
            await reset_game()
            await msg.remove_reaction("❌", client.user) #Remove delete
            embed = discord.Embed(description=format_board_as_str(), color=embed_colour)
            await msg.remove_reaction("▶", user)
            await msg.remove_reaction("▶", client.user)
            await msg.edit(embed=embed)
            await msg.add_reaction("⬅") #Left
            await msg.add_reaction("⬇") #Down
            await msg.add_reaction("➡") #Right
            await msg.add_reaction("🔃") #Rotate
            await msg.add_reaction("❌") #Stop game
            starting_shape = get_random_shape()
            await run_game(msg, starting_shape)

        if str(reaction.emoji) == "⬅": #Left button pressed
            print('Left button pressed')
            h_movement = -1 #move 1 left
            await msg.remove_reaction("⬅", user)
        if str(reaction.emoji) == "➡": #Right button pressed
            print('Right button pressed')
            h_movement = 1 #move +1 right
            await msg.remove_reaction("➡", user)
        if str(reaction.emoji) == "⬇": #Down button pressed
            print('Down button pressed')
            global down_pressed
            down_pressed = True
            await msg.remove_reaction("⬇", user)
        if str(reaction.emoji) == "🔃": #Rotate clockwise button pressed
            print('Rotate clockwise button pressed')
            global rotate_clockwise
            rotate_clockwise = True
            if rotation_pos < 3:
                rotation_pos += 1
            else:
                rotation_pos = 0 #go back to original pos
            await msg.remove_reaction("🔃", user)
        if str(reaction.emoji) == "❌": 
            await reset_game()
            await msg.delete()
        if str(reaction.emoji) == "🔴":
            await message.edit(content="")
解决方案

discord.py中,同一个事件只能保留一个用@client.event装饰的处理函数——后面装饰的会直接覆盖前面的,所以你之前的两个on_reaction_add只会运行最后定义的那个。要让两个逻辑都生效,有两种可行方法:

方法1:合并逻辑到同一个事件处理函数

把两个on_reaction_add里的逻辑整合到一个函数中,依次执行:

@client.event
async def on_reaction_add(reaction, user):
    # 先处理方向控制的逻辑
    await bot_events.on_reaction_add(reaction, user)
    
    # 再处理俄罗斯方块的操作逻辑
    global h_movement, rotation_pos, down_pressed, rotate_clockwise
    if user != client.user:
        msg = reaction.message
        if str(reaction.emoji) == "▶": #Play button pressed
            print('User pressed play')
            await reset_game()
            await msg.remove_reaction("❌", client.user) #Remove delete
            embed = discord.Embed(description=format_board_as_str(), color=embed_colour)
            await msg.remove_reaction("▶", user)
            await msg.remove_reaction("▶", client.user)
            await msg.edit(embed=embed)
            await msg.add_reaction("⬅") #Left
            await msg.add_reaction("⬇") #Down
            await msg.add_reaction("➡") #Right
            await msg.add_reaction("🔃") #Rotate
            await msg.add_reaction("❌") #Stop game
            starting_shape = get_random_shape()
            await run_game(msg, starting_shape)

        if str(reaction.emoji) == "⬅": #Left button pressed
            print('Left button pressed')
            h_movement = -1 #move 1 left
            await msg.remove_reaction("⬅", user)
        if str(reaction.emoji) == "➡": #Right button pressed
            print('Right button pressed')
            h_movement = 1 #move +1 right
            await msg.remove_reaction("➡", user)
        if str(reaction.emoji) == "⬇": #Down button pressed
            print('Down button pressed')
            down_pressed = True
            await msg.remove_reaction("⬇", user)
        if str(reaction.emoji) == "🔃": #Rotate clockwise button pressed
            print('Rotate clockwise button pressed')
            rotate_clockwise = True
            if rotation_pos < 3:
                rotation_pos += 1
            else:
                rotation_pos = 0 #go back to original pos
            await msg.remove_reaction("🔃", user)
        if str(reaction.emoji) == "❌": 
            await reset_game()
            await msg.delete()
        if str(reaction.emoji) == "🔴":
            await msg.edit(content="") # 原代码此处用了未定义的message,修正为msg

方法2:使用add_listener注册多个事件处理函数

discord.py允许用client.add_listener()方法注册多个同一事件的处理函数,这样两个逻辑都会被触发:

首先修改第一个函数的注册方式:

# 定义方向控制的事件处理函数
async def handle_game_direction_reaction(reaction, user):
    await bot_events.on_reaction_add(reaction, user)

# 将函数注册为on_reaction_add事件的监听器
client.add_listener(handle_game_direction_reaction, "on_reaction_add")

然后保留第二个函数的逻辑,也用add_listener注册(或者继续用@client.event,不冲突):

# 定义俄罗斯方块操作的事件处理函数
async def handle_tetris_reaction(reaction, user):
    global h_movement, rotation_pos
    if user != client.user:
        msg = reaction.message
        # 以下逻辑和原代码完全一致...

# 注册为监听器
client.add_listener(handle_tetris_reaction, "on_reaction_add")

这样两个监听器都会在on_reaction_add事件触发时被调用执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:45:32