Search code examples
pythondiscordnextcord

Reaction Role with nextcord


On my Nextcord bot, I want to add a reaction role system. I've tried this code:

@commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
    message_id = payload.message_id
    if message_id == 930812411097796618:
        guild_id = payload.guild_id
        guild = nextcord.utils.find(lambda g: g.id == guild_id, self.bot.guilds)
        if payload.emoji.name == "tada":
            role = nextcord.utils.get(guild.roles, id=896417683153752104)
        elif payload.emoji.name == "nut_and_bolt":
            role = nextcord.utils.get(guild.roles, id=896417735473528832)
        elif payload.emoji.name == "microphone":
            role = nextcord.utils.get(guild.roles, id=896417789458403368)
        elif payload.emoji.name == "part_alternation_mark":
            role = nextcord.utils.get(guild.roles, id=896417886724313128)
        elif payload.emoji.name == "desktop":
            role = nextcord.utils.get(guild.roles, id=896397761770053682)
        elif payload.emoji.name == "screwdriver":
            role = nextcord.utils.get(guild.roles, id=896397839784083496)
        elif payload.emoji.name == "wrench":
            role = nextcord.utils.get(guild.roles, id=896398445487726613)
        elif payload.emoji.name == "elephant":
            role = nextcord.utils.get(guild.roles, id=922184344238444596)
        elif payload.emoji.name == "gem":
            role = nextcord.utils.get(guild.roles, id=896398489376944138)
        elif payload.emoji.name == "mobile_phone":
            role = nextcord.utils.get(guild.roles, id=896398561179226133)
        elif payload.emoji.name == "bird":
            role = nextcord.utils.get(guild.roles, id=896398605873729547)
        elif payload.emoji.name == "floppy_disk":
            role = nextcord.utils.get(guild.roles, id=896398741605584936)
        elif payload.emoji.name == "hash":
            role = nextcord.utils.get(guild.roles, id=896398802204913664)
        elif payload.emoji.name == "snake":
            role = nextcord.utils.get(guild.roles, id=896398888817283113)
        else:
            channel = self.bot.get_channel(930598926174781460)
            embed = nextcord.Embed(title="An error occured")
            await channel.send(embed=embed)

        if role is not None:
            member = nextcord.utils.find(lambda m: m.id == payload.user_id, guild.members)
            if member is not None:
                await member.add_roles(role)
            else:
                channel = self.bot.get_channel(930598926174781460)
                embed = nextcord.Embed(title="An error occured")
                await channel.send(embed=embed)
        else:
            channel = self.bot.get_channel(930598926174781460)
            embed = nextcord.Embed(title="None")
            await channel.send(embed=embed)

I followed this YouTube tutorial (I did changed discord for nextcord), but it seems to don't work. This is my console after executing the code:

output

I don't know what does it means, so I can't fix my problem.


Solution

  • Note that when the payload.emoji.name does not equal any of the ones listed, this code is run:

            else:
                channel = self.bot.get_channel(930598926174781460)
                embed = nextcord.Embed(title="An error occured")
                await channel.send(embed=embed)
    

    You then try to run the following code, which references the name "role":

    if role is not None:
    

    However, if the payload.emoji.name does not equal any of the ones listed, role does not get bound, and you get an error from trying to use a variable which does not exist.

    Solution

    You can solve this by adding a return statement to the block above, like so:

            else:
                channel = self.bot.get_channel(930598926174781460)
                embed = nextcord.Embed(title="An error occured")
                await channel.send(embed=embed)
                return
    

    This will stop the function when no role is set before trying to use role, so it should resolve the error.

    You also need to edit the names of the emojis, or else payload.emoji.name will not match any of them, as they use the unicode version of the emoji and not discord's name for the emoji.

    For example, instead of using "nut_and_bolt", you should use "🔩" instead. payload.emoji.name

    How to get unicode emoji from emoji name


    As an aside, you can improve your code by using

    role = guild.get_role(role_id=your_role_id)
    

    instead of

    role = nextcord.utils.get(guild.roles, id=your_role_id)
    

    Likewise, you can use

    member = guild.get_member(user_id=payload.user_id)
    

    instead of

    member = nextcord.utils.find(lambda m: m.id == payload.user_id, guild.members)
    

    and finally,

    guild = self.bot.get_guild(id=payload.guild_id)
    

    instead of

    guild = nextcord.utils.find(lambda g: g.id == guild_id, self.bot.guilds)