I dont get why the reaction role wont do anything? - python

I've been trying to set up a bot that gives a new user who joined my discord server the role "mietzekatze" when he reacts with ":white_check_mark:" to a message. It's like a type of verification or approval. So I found a solution on how to do that, but it does not work. I tried different things, but it won't work. It doesn't return any error, it just wont do, what it's supposed to. Please help, I'm losing my mind.
#client.event
async def on_reaction_add(reaction, member):
Channel = client.get_channel('828667703966433331')
if reaction.message.channel.id != Channel:
return
if reaction.emoji == ":white_check_mark:":
Role = discord.utils.get(member.guild.roles, name="mietzekatze")
await member.add_roles(Role)

I would use a different event here called on_raw_reaction_add. For that you also need payload. You can read the docs for that here.
Re-written your code would look like this:
#client.event
async def on_raw_reaction_add(payload):
guild = client.get_guild(payload.guild_id) # Get the guild
if payload.channel_id == Channel_ID_here: # If the defined channel is correct
if str(payload.emoji) == "✅":
role = get(payload.member.guild.roles, name='mietzekatze') # Or id='RoleID'
else:
role = get(guild.roles, name=payload.emoji)
if role is not None:
await payload.member.add_roles(role) # Add the role
print("Added role") # Check if the role was added
You can use as many if str(payload.emoji) == "YourEmoji": events as you want, just pass them under the other event(s).
Note that you have to pass the ID of a channel/guild without ' '

You have to check for channel's id
if reaction.message.channel.id != Channel.id:
return

Related

Trying to have my discord bot add roles from a reaction to a message

I'm having an issue where my bot wont give the respected role when a user reacts to the message correctly
#client.event
async def on_raw_reaction_add(payload):
# Get the user who added the reaction
guild = client.get_guild(payload.guild_id)
reacting_user = guild.get_member(payload.user_id)
# Get the message object for the reaction
channel = guild.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
# MESSAGE_ID defined in config file
if message == MESSAGE_ID:
if str(payload.emoji) == '👍':
role = discord.utils.get(reacting_user.guild.roles, id=1056801648355324034)
await reacting_user.add_roles(role)
elif str(payload.emoji) == '👎':
role = discord.utils.get(reacting_user.guild.roles, id=1056801755670777946)
await reacting_user.add_roles(role)
I've tried using on_raw_reaction_add but I've have no success
Your if condition is badly structured here. Check if payload.message_id == 1234
if payload.message_id == 1234567:
#stuffs
Also make sure that your intents are on.
Other issue could be the type conversation of MESSAGE_ID that you are pulling from config.ini (im guessing)
try doing:
if payload.message_id == int(MESSAGE_ID):

How to get a reaction from a single message, and not any message with the same emojii

I'm trying to assign a role to a member once they react to a message (more specifically once agreeing to rules)
What I currently have works fine:
#client.event
async def on_ready():
cid = client.get_guild(#################) # need this to fetch roles
channel = client.get_channel(#################)
role = discord.utils.get(cid.roles, name="member") #fetch server roles
message = await channel.send("React if you agree, and gain access to the server")
await message.add_reaction('☑️') # add message and reaction
reaction, user = await client.wait_for('reaction_add', check=lambda reaction, user: reaction.emoji == '☑️') # check for reaction
await user.add_roles(role) # assign role when reacted
The problem is that, you can react with the emoji on any message and it will still give you the role.
How can I make it so that only that message counts. And no other?
I was hoping for maybe something like message.wait_for() (which doesn't seem to exist)
I would think I could fetch the id of the message then somehow compare that to the id of the message the reaction is attached to and compare that. But I have no idea how that could be done.
user and reaction don't seem to return anything of use
You should define a check function to verify that the reaction was added to the correct message.
def check(reaction, user):
return reaction.message.id == message.id and str(reaction.emoji) == '☑️'
reaction, user = await client.wait_for('reaction_add', check=check) # check for reaction
Sources
wait_for

Discord Python Reaction Role

I want that my bot add the role "User" to a user who react with a heart. But it doesn't work.
My code:
#client.event
async def on_reaction_add(reaction, user):
if reaction.emoji == "❤️":
user = discord.utils.get(user.server.roles, name="User")
await user.add_roles(user)
I hope you can help me :)
I would use a different event here called on_raw_reaction_add. You can find the documentation for it here.
With that new event you would have to rewrite your code a bit and add/remove some things.
Your new code:
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(command_prefix="YourPrefix", intents=intents) #Import Intents
#client.event
async def on_raw_reaction_add(payload):
guild = client.get_guild(payload.guild_id) # Get guild
member = get(guild.members, id=payload.user_id) # Get the member out of the guild
# The channel ID should be an integer:
if payload.channel_id == 812510632360149066: # Only channel where it will work
if str(payload.emoji) == "❌": # Your emoji
role = get(payload.member.guild.roles, id=YourRoleID) # Role ID
else:
role = get(guild.roles, name=payload.emoji)
if role is not None: # If role exists
await payload.member.add_roles(role)
print(f"Added {role}")
What did we do?
Use payload
Used the role ID instead of the name so you can always change that
Limited the reaction to one channel, in all the others it will not work
Turned the emoji into a str
Make sure to turn your Intents in the DDPortal on and import them!

Assign discord role when user reacts to message in certain channel

I want a user to be assigned a role when they choose a certain reaction in my welcome-and-roles discord channel. I've looked everywhere and can't find code in python that works with the most up-to-date version of discord.py. Here is what I have so far:
import discord
client = discord.Client()
TOKEN = os.getenv('METABOT_DISCORD_TOKEN')
#client.event
async def on_reaction_add(reaction, user):
role_channel_id = '700895165665247325'
if reaction.message.channel.id != role_channel_id:
return
if str(reaction.emoji) == "<:WarThunder:745425772944162907>":
await client.add_roles(user, name='War Thunder')
print("Server Running")
client.run(TOKEN)
Use on_raw_reaction_add instead of on_reaction_add, As on_reaction_add will only work if the message is in bot's cache while on_raw_reaction_add will work regardless of the state of the internal message cache.
All the IDS, Role IDs, Channel IDs, Message IDs..., are INTEGER not STRING, that is a reason why your code not works, as its comparing INT with STR.
Also you need to get the role, you can't just pass in the name of the role
Below is the working code
#client.event
async def on_raw_reaction_add(payload):
if payload.channel_id == 123131 and payload.message_id == 12121212: #channel and message IDs should be integer:
if str(payload.emoji) == "<:WarThunder:745425772944162907>":
role = discord.utils.get(payload.member.guild.roles, name='War Thunder')
await payload.member.add_roles(role)
Edit: For on_raw_reaction_remove
#client.event
async def on_raw_reaction_remove(payload):
if payload.channel_id == 123131 and payload.message_id == 12121212: #channel and message IDs should be integer:
if str(payload.emoji) == "<:WarThunder:745425772944162907>":
#we can't use payload.member as its not a thing for on_raw_reaction_remove
guild = bot.get_guild(payload.guild_id)
member = guild.get_member(payload.user_id)
role = discord.utils.get(guild.roles, name='War Thunder')
await member.add_roles(role)

How do you add roles in discord.py?

I am trying to add a role to someone but when I do the
client.add_roles(member, role)
I have tried everything I could think of with the code it just gives me that message, I have looked at several other questions around looking for the answer but everyone says to do that command that I have tried but it wont work.
#client.command(pass_context=True)
#commands.has_role('Unverified')
async def verify(ctx, nickname):
gmember = ctx.message.author #This is the looking for the memeber
role = discord.utils.get(gmember.server.roles, name='Guild Member')
channel = client.get_channel(401160140864094209)
await gmember.edit(nick=f"{nickname}")
await ctx.channel.purge(limit=1)
r = requests.get("This is the link to the API but it shows my key and everything so not going to put it here but it works in other commands")
#if nickname in role:
# await ctx.send(f"You have already verified your account.")
if nickname.encode() in r.content:
await channel.send(f'#here ``{nickname}`` is in the guild.')
await client.add_roles(gmember, role)
else:
await gmember.kick()
Instance of Bot has no add_roles member pylint (no-member)
await gmember.add_roles(role)
You can read more here

Categories