i want to delete a message by reacting with a trash emoji. My only problem is, that all messages by the one person get deleted when reacting.
So first it looks like this:
https://i.stack.imgur.com/JBBWh.png
And after reacting to the second "trash" emoji, all four message are deleted.
Thank you! :)
#client.event
async def on_message(message):
if not (message.author.bot):
embed = discord.Embed(title="Points earned!", description="+1 Points")
msg = await message.channel.send(embed=embed)
await message.add_reaction("🗑️")
channel = message.channel
def check(reaction, user):
return user == message.author and str(reaction.emoji) == '🗑️'
try:
reaction, user = await client.wait_for('reaction_add', check=check)
except asyncio.TimeoutError:
await channel.send("This shouldnt happen")
else:
await msg.delete()
await message.delete()
You never checked for the correct message. When you react to one of them, it triggers the checks for both messages and both are deleted. What you want is this:
def check(reaction, user):
return user == message.author and str(reaction.emoji) == '🗑️' and reaction.message.id == message.id
This checks that the message you were reacting to is equal to the original message.
This way, the reaction will only trigger for the message that it reacted to.
Related
I'm trying to make a bot that uses emoji to change the embed message like owo or some kind of music bot pls show me how
I'm just a guy who is interested in coding and just begin making a bot
You could catch the on_reaction_add event.
#bot.event
async def on_reaction_add(reaction, user):
if (message.author.id == bot.user.id) and (str(reaction.message.id) == "id-of-message-to-be-edited"):
reaction.message.edit(embed=Embed(title="new embed content"))
Or if you're using this in the flow of a command or a pre-called event, use discord.Client.wait_for.
#bot.command()
async def foo(ctx):
await ctx.send('Say hello by reaction with 👍!')
def check(reaction, user):
return user == message.author and str(reaction.emoji) == '👍'
try:
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await channel.send('Bye 👎')
else:
await channel.send('Hello 👍')
I am developing a little reaction roles bot in discord.py - for this I am trying to use the .wait_for() function with the "reaction_add" parameter. The problem is that I need to get the emoji from the reaction, which is not working as an error is shown:
AttributeError: 'tuple' object has no attribute 'user'
Seemingly there is something wrong with the way I am trying to get the emoji, but I couldn't find the proper way to get the emoji.
interaction = await client.wait_for('reaction_add')
if interaction.emoji == "🚨":
await interaction.user.add_roles(role)
emoji = "🚨"
message = await ctx.send("Test")
await message.add_reaction(emoji)
reaction, user = await bot.wait_for("reaction_add")
if user != bot.user:
if reaction.emoji == emoji:
await user.add_roles(user, role)
or
emoji = "🚨"
def check(reaction, user):
return user == ctx.message.author and reaction.emoji == emoji
message = await ctx.send("Test")
await message.add_reaction(emoji)
reaction, user = await bot.wait_for("reaction_add", check=check)
await bot.add_roles(user, role)
I'm writing a simple script that exec if a simplified string is written in a channel, after that the user message gets deleted.
Or if the user send a message that is not one of the strings it to be deleted too.
However, even the bot message gets deleted too which are theses
await message.channel.send(badr.mention)
await message.channel.send(expired)
and
await message.channel.send(author.mention)
await message.channel.send(WL_message)
which is not what I'm aiming for I want only the member's message to get deleted not the bots.
if (message.channel.id == 897508930744381491):
author = message.author
content = message.content
expire = '||!WL xdxdxd||', '||!WL 432-234-4312-fas2||'
Valied= '||!WL Furball2244||', '||!WL 432-234-4www312-32242||', 'Furball2244', '!WL Furball2244'
if message.content.startswith(expire):
await message.delete()
badr = author
expired= "This code is expired, contact an admin in <#899289942897860659>, there is a chance they can add you manually"
await message.channel.send(badr.mention)
await message.channel.send(expired)
if message.content.startswith(Valied):
ROLE = "Role55555"
WL_message='Congratulations, now you have access to <#930074601436905522>, you enter your information there.'
await message.channel.send(author.mention)
await message.channel.send(WL_message)
role = get(message.guild.roles, name=ROLE)
await author.add_roles(role)
else: await message.delete()
Is there a trick around it?
To my understanding, you want to delete the message the user sends, in which you would use
await ctx.message.delete()
You need to wait for author to send message
def check(m):
return message.author == oldmsg.author #To make sure it is the only message author is getting
msg = await self.bot.wait_for('message', timeout=60.0, check=check)
if message.content == "your codes":
# do stuff
await message.delete()
This way you can delete the next message from the user right away. make sure you save the command author in a global dictionary or something!
elif message.author.id == 930374951935021096:
return
else:
await message.delete()
seems like just adding an elif solves the problem, regardless thank you for your reply.
#client.command(name='verify')
async def verify(ctx, channel: discord.TextChannel):
msg = await channel.send('React to this message')
await msg.add_reaction('😍')
#client.event
async def on_raw_reaction_add(payload):
print('payload message.id ' + str(payload.message_id))
print('messages.id ' + str(msg.id)
Can someone explain how will this will work
You do not put events inside commands, you can use client.wait_for
#client.command()
async def verify(ctx, channel: discord.TextChannel):
msg = await channel.send("React to this message")
await msg.add_reaction('😍')
def check(reaction, user):
return user == ctx.author and reaction.message == msg
# Waiting for the reaction
reaction, user = await client.wait_for("reaction_add", check=check)
print(f"{ctx.author} reacted")
Reference:
wait_for
There are 2 ways of doing that in a simple way
First way (not recommended if you want it to work forever once you run the command. But if you want it like that, then choose this)
#bot.command() # since you are using client, replace bot with client
async def verify(ctx): # I left out "channel" because I don't know what you want to do with it
# Same thing as you did
msg = await ctx.send("React to this message")
await msg.add_reaction("😍")
# Waiting for someone to react
def check(payload):
return payload.message_id == msg.id # This will check if the message reacted on is the same as the bot's message, if you want it to be the user as well, replace this line with "return payload.message_id == msg.id and payload.user_id == ctx.author.id"
payload = await bot.wait_for("raw_reaction_add", check=check) # You can add a timeout like this: "payload = await bot.wait_for("raw_reaction_add", check=check, timeout=int)"
if str(payload.emoji) == "😍":
print(f"{payload.member} reacted")
Second way (harder but useful if you want to run the command once, but if your bot turns off, it'll reset, so have some sort of save file to save verify_msg)
# This list is going to have all the verification messages
verify_msg = []
#bot.event
async def on_raw_reaction_add(payload):
global verify_msg
# check if the message id match to one of the messages' in the list
for msg in verify_msg:
if payload.message_id in msg.id: # success
if str(payload.emoji) == "😍":
print(f"{payload.member} reacted")
return # exit from the command (you can replace it with "break" if you want to continue)
#bot.command()
async def verify(ctx):
global verify_msg
msg = await ctx.send("React to this message")
await msg.add_reaction("😍")
# add the message to the list
verify_msg.append(msg)
References:
await bot.wait_for
payload
message
Testing out moving some of my setup modules to DMs instead of in a server channel, as if I do it in a channel, people can easily get a bit confused with responses even though I have the bot set to ignore anyone but the original command author
I've tried the usual wait_for handler, but I can't seem to get the bot to catch the input via dm
#commands.command(name="dmstats")
async def stat_dm(self, ctx):
member = ctx.author
stat_list = await self.get_stat_vals(ctx, member)
reply = await ctx.author.send("What value do you want?")
await self.bot.wait_for('message')
if reply.content.lower() == "strength":
await ctx.author.send("Your strength is: {}".format(stat_list["strength"]))
Expected that when I [p]dmstats and trigger the command, the bot will DM me and prompt me, which it does, however its not catching my response
If you want to only accept messages from that user in a DM channel, you can record the channel that you sent the message to the user in, and then apss that as part of a check to wait_for
#commands.command(name="dmstats")
async def stat_dm(self, ctx):
stat_list = await self.get_stat_vals(ctx, member)
msg = await ctx.author.send("What value do you want?")
def check(message):
return message.author == ctx.author and message.channel == msg.channel
reply = await self.bot.wait_for('message', check=check)
if reply.content.lower() == "strength":
await ctx.author.send("Your strength is: {}".format(stat_list["strength"]))