Get the user who reacted discord.py - python

#client.event
async def on_raw_reaction_add(payload):
#the embedded msg that was sent
global msg
message_id1 = payload.message_id
#checks if the message that was sent is the message the reaction was added to
if message_id1 == msg.id:
..code..
I also told the bot to add reactions (all the reactions from 1 to 9) to the message but when I said:
if payload.emoji.name == '1️⃣':
..code..
it did whatever the code said after that but I want it to ignore the bot's reaction and just take user reaction and later on I want it to only use 2 user's reactions (the ones who called the function).
Is there some kind of syntax that checks the id or username of the people who reacted so I can add it to the if statement at the start?

The payload is the type: RawReactionActionEvent, which has the attributes of member. You can do,
if payload.member.id == bot.user.id:
return

Related

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 py detect reactions

I am only trying to learn how to "read" the reaction on a message the same bot sends. I've been stuck for days. I looked it up but the only tutorials I find are with a specific message for roles. I don't care about that, I won't use a single message for the whole server, so there is no way I can get the ID for the message. I only want the bot to send a message, then the user reacts and the bot writes "you reacted with [emoji]".
I found some questions on this site, but they only managed to confuse me even more. Still, this is what I barely managed to make.
#bot.command()
async def react(ctx):
await ctx.send("React to me!")
#bot.event
async def on_reaction_add(reaction, user):
await channel.send("{}, you responded with {}".format(user, reaction))
There is actually a good example of this already in the documentation, you can find it here:
wait_for
But to simplify the whole thing a bit, here is a sample code:
#bot.command()
async def react(ctx):
def check(reaction, user): # Our check for the reaction
return user == ctx.message.author # We check that only the authors reaction counts
await ctx.send("Please react to the message!") # Message to react to
reaction = await bot.wait_for("reaction_add", check=check) # Wait for a reaction
await ctx.send(f"You reacted with: {reaction[0]}") # With [0] we only display the emoji
Here is how it looks like:
Without reaction[0] you would only get unnecessary information. [0] shows you only the first digit, in this case Reaction emoji.

How do I DM a user when a reaction is added to a message?

Combining a user reacting with sending them a DM has had me stumped.
My project works by having an embed that has a reaction added at the bottom and when the user clicks the emoji then it will DM the user a set of instructions (for now I'm just using the word 'Test').
Here is what I have so far:
#client.event
async def on_message(message):
if message.content.startswith('.add'):
embed = discord.Embed(title="Embed Title", color=0x6610f2)
embed.add_field(name="__**Steps to get DM'd:**__", value="""
• Step 1
• Step 2
• Step 3
• Step 4
• Step 5
""")
msg = await message.channel.send(embed=embed)
await msg.add_reaction('\U0001F91D')
#client.event
async def on_raw_reaction_add(payload):
if payload.user_id == client.user.id:
return
if str(payload.emoji) == '\U0001F91D':
channel = await client.fetch_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
await message.author.send('Test')
I'm just not sure how to get the user's ID outside of the on_message() function because the only way I know how to make the on_reaction_add work is in its own client event. I'm not even sure if I'm handling the DM user aspect correctly.
Using the async version of Discord.py
In your payload, you should already get a discord.Member object you can work with. Try something like
#client.event
async def on_raw_reaction_add(payload):
if str(payload.emoji) == "\U0001F91D":
member = payload.member
await member.send('This is a DM to you!')
Because your code does not check for the message id, a reaction to ANY message (not just the one you sent) will lead to a response. To prevent this, you can check whether payload.message_id matches the id of your bot's message (which you could store somewhere when sending the message).
You also tried to prevent a response to the initial reaction of your bot. Instead of checking for payload.user_id, I would suggest
if member.bot:
return
which prevents a response to any bot reacting to your message, including your own.

How do I make a bot respond to a specific reaction? Discord.py

I am trying to add a giveaway function to my discord bot but the reroll function I am trying to make does not work. When the giveaway ends it sends a message that says who won the giveaway. This is what I have defined as reroll. Then I make the bot wait and see if someone has added a 'x' reaction to this message. I am trying to make it so that if someone has added an 'x' reaction then it will redo the winner choice in the giveaway. I hope to also make this function repeat if multiple winners are invalid. But I am not exactly sure how I would make a bot respond specifically to a specific reaction on a message.
reroll = await channel.send(f'Congratulations! {winner.mention} won {prize}!')
if reroll.reactions == '❌':
winner2 = random.choice(users)
await channel.send(f'Congratulations! {winner2.mention} won {prize}!')
According to the discord documentation, we can check on_reaction_add(reaction, user).
Called when a message has a reaction added to it. Similar to
on_message_edit(), if the message is not found in the internal message
cache, then this event will not be called. Consider using
on_raw_reaction_add() instead.
With that you can basically check for the message
async def on_reaction_add(reaction, user):
if 'Congratulations!' in reaction.message.content and reaction.emoji == '❌':
# do stuff
You can access the Message being reacted via Reaction.message

How do you check if a specific user reacts to a specific message [discord.py]

I've looked at similar questions but none of the answers worked for me. I'm working on a bot where you type in (prefix)suggest (suggestion) and then it sends a message asking if you are sure you want to send the suggestion. If they react to that message with the reaction that the bot has added (check mark) then it sends the suggestion to a channel.
In short, how do I create a trigger where if a specific person reacts to a specific message with a specific emoji then it sends the output?
To make it reaction check message specific you need to use reaction.message == message in the check function.
Here's the full example based on Libby's answer.
message = await ctx.send("Are you sure you want to submit this suggestion?")
await message.add_reaction("✅")
confirmation = await bot.wait_for("reaction_add", check=check)
channel = bot.get_channel(channel_id) # Put suggestion channel ID here.
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in ["✅"] and reaction.message == message
if confirmation:
await channel.send(suggestion)
You can use the wait_for function to make the bot wait until the author reacts with the checkmark.
First, do a check to ensure that the bot sends the suggestion to the suggestion channel only if the message author reacts with a checkmark:
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in ["✅"]
Then put the code that sends the confirmation message and has the wait_for function:
message = await ctx.send("Are you sure you want to submit this suggestion?")
await message.add_reaction("✅")
confirmation = await bot.wait_for("reaction_add", check=check)
channel = bot.get_channel(channel_id) # Put suggestion channel ID here.
Finally, put the code that tells the bot what to do once the message author reacts:
if confirmation:
await channel.send(suggestion)

Categories