Discord py detect reactions - python

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.

Related

How can I delete messages sent by a specific user within a specific channel using Discord.py

Hopefully this isn't a duplicate post but I've searched around and can't find anything on how to do this specifically.
I'm trying to create a Discord bot which can delete messages sent by a specific author, in a specific channel, but also checks previously sent messages.
At the moment I have the below, which adds new messages from chosen user to a list, checks if they're duplicates and if they are, deletes them.
I want to know:
A: How can I make this bot Channel specific
B: Can I have this program check old messages in that channel too and also delete them if they're duplicates?
Thanks in advance for any help and if any further info required, please let me know.
import discord
TOKEN = ('MY_TOKEN_LIVES_HERE')
client = discord.Client()
messagesSeen = []
#client.event
async def on_message(message):
if "News_Bot" in str(message.author):
if message.content in messagesSeen:
await message.delete()
else:
messagesSeen.append(message.content)
client.run(TOKEN)
Yes you can do both of those things. Since you are using on_message event you can just use message.channel to also check that channel for previously sent messages. I would also advise to change news_bot to the ID of the bot. The thing is one you implement this and clear the channel history for those messages, it won't be necessary anymore as the bot will catch the messages as soon as they are sent. So the message history is kind of a one time thing, which you can just create a cmd and run it in that channel.
messagesSeen = []
#client.event
async def on_message(message):
if 1234345 is message.author.id:
if message.content in messagesSeen:
await message.delete()
async for message in message.channel.history(limit=100):
if message.content in messagesSeen:
await message.delete()
else:
messagesSeen.append(message.content)

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 my Bot Ignore messages from people with a certain role? (Discord.py)

How can I make my Discord.py bot ignore messages from people that have a certain role?
I have recently added a feature that to my Discord.py bot.
#client.event
async def on_message(message):
if message.content == "Blocked Word":
await message.delete()
I want it so that if someone such has myself, has a certain role the bot will not delete the message.
Any help would be appreciated!
Here is some simple code, that might answer your question:
This builds on #Joshua Nixon's answer
#client.event()
async def on_message(message):
if 'role' in [role.name for role in message.author.roles]: #checks if the specified role is in the user's roles
#do something
else:
#do something else

Discord.py Adding Reactions For Poll

I've got this code for my bot, I'm trying to make a !poll command. In theory, I'll type !poll (question), and then the bot will send my questions as an embed, and under that embed, add a thumbsup and thumbsdown reaction so people can vote. However, I just cannot work out how to make it add the reaction, no matter how hard I try and research. Here's the code:
#commands.has_permissions(administrator=True)
async def poll (ctx, *, message):
embed=discord.Embed(title="New Poll!", description = message, color=0xff0000)
await ctx.send(embed=embed)
So what do I now need to add to my code so it can add a 👍 and 👎 reaction to the embed? Thanks.
Messageable.send returns a discord.Message instance, you then simply .add_reaction()
message = await ctx.send(embed=embed)
await message.add_reaction('👍')
await message.add_reaction('👎')
Reference:
Messageable.send
Message.add_reaction

discord.py bot isn't answering when mentioned from phone app

I made recently a discord bot for small server with friends. It is designed to answer when mentioned, depending on user asking. But the problem is, when someone mention bot from a phone app, bot is just not responding. What could be the problem?
Code:
import discord
from discord.ext import commands
from discord.ext.commands import Bot
import asyncio
bot = commands.Bot(command_prefix = '=')
reaction = "🤡"
#bot.event
async def on_ready():
print('Bot is ready.')
#bot.listen()
async def on_message(message):
if str(message.author) in ["USER#ID"]:
await message.add_reaction(emoji=reaction)
#bot.listen()
async def on_message(message):
mention = f'<#!{BOT-DEV-ID}>'
if mention in message.content:
if str(message.author) in ["user1#id"]:
await message.channel.send("Answer1")
else:
await message.channel.send("Answer2")
bot.run("TOKEN")
One thing to keep in mind is that if you have multiple functions with the same name, it will only ever call on the last one. In your case, you have two on_message functions. The use of listeners is right, you just need to tell it what to listen for, and call the function something else. As your code is now, it would never add "🤡" since that function is defined first and overwritten when bot reaches the 2nd on_message function.
The message object contains a lot of information that we can use. Link to docs
message.mentions gives a list of all users that have been mentioned in the message.
#bot.listen("on_message") # Call the function something else, but make it listen to "on_message" events
async def function1(message):
reaction = "🤡"
if str(message.author.id) in ["user_id"]:
await message.add_reaction(emoji=reaction)
#bot.listen("on_message")
async def function2(message):
if bot.user in message.mentions: # Checks if bot is in list of mentioned users
if str(message.author.id) in ["user_id"]: # message.author != message.author.id
await message.channel.send("Answer1")
else:
await message.channel.send("Answer2")
If you don't want the bot to react if multiple users are mentioned, you can add this first:
if len(message.mentions)==1:
A good tip during debugging is to use print() So that you can see in the terminal what your bot is actually working with.
if you print(message.author) you will see username#discriminator, not user_id

Categories