Search code examples
pythondiscord.pyrolesemoji

Add role when react to emoji discord.py


im trying to add a role when the user react to this emojis but i cant get

Setup Roles


@bot.command()
async def roles(ctx):
    global IDMessage
    reaction   = await ctx.reply("Select your Game" + '\n' + '\n' + "- Valorant πŸ¦Έβ€β™€οΈ" '\n' + "- World of Warcraft βš”" + '\n' + "- League of Legends πŸ§™β€β™€οΈ" + '\n' + "- Cs:Go πŸ”«")
    

    await reaction.add_reaction('πŸ¦Έβ€β™€οΈ')
    await reaction.add_reaction('βš”')
    await reaction.add_reaction('πŸ§™β€β™€οΈ')
    await reaction.add_reaction('πŸ”«')
    
    IDMessage = reaction.message_id

And this is the part of the code that doesnt work for me

Add role on reaction

@bot.event
async def on_reaction_add(reaction, user):
  ChID = '920320584032870424'
  if reaction.message.channel.id != ChID:
    return
  if reaction.emoji == "πŸ¦Έβ€β™€οΈ":
    Valorant = discord.utils.get(user.server.roles, name="Valorant")
    await bot.add_roles(user, Valorant)

Solution

  • There are some issues here. Instead of on_reaction_add, use on_raw_reaction_add. Most bots use the latter instead of the former. Why you may ask? Because, on_reaction_add only works for messages in bot's cache.

    So every message sent after your bot can read messages is stored in a dictionary or list (this is what a cache is). By default the limit of caching is 1000 messages.

    So if you ever restarted your bot, the message will never be in cache, and thus the event won't trigger.

    Another issue is that you are comparing a string (ChID) variable and an integer (reaction.message.channel.id), they can never be equal so if reaction.message.channel.id != ChID will always return True and thus won't do anything (as you return for that condition being True).

    Third issue is that bot.add_roles does not exist. add_roles is a method of discord.Member object.

    Fourth issue is, Member.server is not a thing, Member.guild is

    So your updated code will be like:

    @bot.event
    async def on_raw_reaction_add(payload: discord.RawReactionActionEvent):
      ChID = 920320584032870424
      if payload.channel.id != ChID:
        return
      if str(payload.emoji) == "πŸ¦Έβ€β™€οΈ":
        valorant = discord.utils.get(payload.member.guild.roles, name="Valorant")
        await payload.member.add_roles(valorant)
    

    Also my personal advice of not using global there are very rare few cases where you would actually require this keyword

    But it is highly unlikely for you to use this in a bot made with discord.py lib

    More on this: