Discord Python Reaction Role - python

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!

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):

Discord.py How to add a role to user in server who DMs the bot?

I have only seen DiscordJS tutorials on this topic.
Right now I have coded only this bit and don't know how to move on.
if isinstance(message.channel, discord.channel.DMChannel) and message.author != client.user:
user_id = message.message.author.id
member = bot.get_user(user_id)
role = '<role_id>'
server = '<server_id>'
await bot.members(server).get_user(user_id).add_roles(role)
else:
return
Obviously this doesn't work. Any help is useful.
Guess this should work.. write a comment if it doesn't
from discord.ext import commands
intents = discord.Intents.members
client = commands.Bot(command_prefix='PREFIX', intents=intents, case_insensitive=True)
#client.event
async def on_message(message):
if isinstance(message.channel, discord.channel.DMChannel) and message.author != client.user:
guild = client.get_guild(SERVER_ID) # Has to be int
member = guild.get_member(message.author.id)
role = guild.get_role(ROLE_ID) # Also has to be int
member.add_roles(role)
else: # If you ain't got any code after this you can delete the else
return
Intents.members
commands.Bot
on_message Event
bot.get_guild
guild.get_member
guild.get_role
member.add_roles

discord reaction bot in python. get_member() in on_raw_reaction_remove() always gets 'none'

I have this python code where my Bot should remove Roles from the user if the user removes his reaction from a Message with the given message ID.
I dont know why, but I always get 'none' and the bot cant remove the role because he cant find the member...
The intents in the discord developer portal are active. I dont know what I've been doing wrong.
Can somebody help me here please?
import discord
from discord import message, ActivityType
from discord.ext import commands
from discord.ext.commands import Cog
from discord.utils import get
from discord import utils
intents = discord.Intents(messages=True, guilds=True, reactions=True, members=True, presences=True)
client = commands.Bot(command_prefix = '$', intents=intents)
class reaction_cog(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_raw_reaction_remove(self, payload):
message_id = payload.message_id
if message_id == 829409323297407027:
guild = self.client.get_guild(payload.guild_id)
user = guild.get_member(payload.user_id)
role = discord.utils.get(guild.roles, name=str(payload.emoji.name))
print(role)
print(user)
if user != None:
user = payload.member
print(user)
if user != None:
await user.remove_roles(role)
EDIT:
Thank you for your help.
that with the roles is not a problem. They are easily recognized. It is recognized which reaction is added and which is removed. Only my user stays at none.
I added a few prints to demonstrate what the code does.
message_id = payload.message_id
if message_id == 829409323297407027:
guild = self.client.get_guild(payload.guild_id
print("remove action starts")
print("Reaction removed on server:")
print(guild)
user = guild.get_member(payload.user_id)
role = discord.utils.get(guild.roles, name=str(payload.emoji.name))
print("Which Role removed:")
print(role)
print("user who removed:")
print(user)
if user is not None:
user = payload.member
print(user)
if role is not None:
await user.remove_roles(role)
This is what I get in the console:
remove action starts
Reaction removed on server:
Danis Server
Which Role removed:
Uni
user who removed:
None
Your code does not make sense to me at some parts. You have to actually define which role you want to remove on reaction. You can do that in different ways.
Take a look at the following code:
#commands.Cog.listener()
async def on_raw_reaction_remove(self, payload):
guild = self.client.get_guild(payload.guild_id)
member = get(guild.members, id=payload.user_id) # Get the member
if payload.message_id == YourMessageID:
if str(payload.emoji) == "YourEmoji":
role = get(payload.member.guild.roles, name='RoleName') # ID also possible
else:
role = get(guild.roles, name=payload.emoji)
if role is not None:
await member.remove_roles(role) # Remove role
You can also add more elif-statements if you want to remove more roles than just one.

I dont get why the reaction role wont do anything?

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

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)

Categories