Programming a Discord bot in Python- Can't figure out how to set up reaction roles (part 2)

Viewed 169

I asked a question about reaction roles earlier, that problem got solved but now I have another problem. Here's my code:

@client.event
async def on_raw_reaction_add(payload):
  message_id = payload.message_id
  if message_id == 800172672860291132:
    guild_id = payload.guild_id
    guild = discord.utils.find(lambda g : g.id == guild_id, client.guilds)
    
    role = None
    if payload.emoji.name == '':
      role = discord.utils.get(guild.roles, name='Red')
    elif payload.emoji.name == '':
      role = discord.utils.get(guild.roles, name='Orange')
    elif payload.emoji.name == '':
      role = discord.utils.get(guild.roles, name='Yellow')
      
    if role is not None:
      member = payload.member
      if member is not None:
        await member.add_roles(role)
        print("done")
      else:
        print("Member not found")
    
    else:
      print("Role not found")


@client.event
async def on_raw_reaction_remove(payload):
  message_id = payload.message_id
  if message_id == 800172672860291132:
    guild_id = payload.guild_id
    guild = discord.utils.find(lambda g : g.id == guild_id, client.guilds)
    
    role = None
    if payload.emoji.name == '':
      role = discord.utils.get(guild.roles, name='Red')
    elif payload.emoji.name == '':
      role = discord.utils.get(guild.roles, name='Orange')
    elif payload.emoji.name == '':
      role = discord.utils.get(guild.roles, name='Yellow')
    
    if role is not None:
      member = payload.member
      if member is not None:
        await member.remove_roles(role)
        print("done")
      else:
        print("Member not found")
    
    else:
      print("Role not found")

The bot hands out roles just fine, but when a reaction is removed, it does not remove the role & says "Member not found". If you look at my code you'll see that means Member is still None. And like I said, the part that gives roles is working fine. Not sure what to do, any tips?

2 Answers

I advise you to read the docs on the reaction event payload, it says that the member value is only available if event_type is REACTION_ADD.

As to how to solve your problem, you can use the on_reaction_remove(reaction, user) which has the user as a value.

As backup for cache-issues you could keep a list of members that have the role and check the reactions for the missing member when you get the on_raw_reaction_remove(payload) event

on_raw_reaction_remove does not give you a member object the same way on_raw_reaction_add does. However they both have one thing in common, user_id. Find your member through payload.user_id

Code as used on my testing bot:

@client.vent
async def on_raw_reaction_remove(payload):
    message_id = payload.message_id
    if message_id == 800172672860291132:
        guild_id = payload.guild_id
        guild = client.get_guild(guild_id)
        
        role = None
        if payload.emoji.name == '':
            role = discord.utils.get(guild.roles, name='Red')
        elif payload.emoji.name == '':
            role = discord.utils.get(guild.roles, name='Orange')
        elif payload.emoji.name == '':
            role = discord.utils.get(guild.roles, name='Yellow')
        
        if role is not None:
            member = discord.utils.find(lambda m: m.id == payload.user_id, guild.members)
            if member is not None:
                await member.remove_roles(role)
                print("done")
            else:
                print("Member not found") 
        else:
            print("Role not found")
Related