Discord.py Bot deleting bot message too - python

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.

Related

Discord.py delete only the latest message by reaction

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.

I'm trying to get my discord bot to wait for the user to send another message after they did the original command

Sorry if the title didn't make sense, I'm making a discord bot and I'm trying to make a little 8 ball command. What I'm trying to make the bot do is that after the user type "$8ball" the bot will say "What's your question?" Then wait for the user to type out their question and then respond with the array of responses I've made for it.
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith("$8Ball"):
await message.channel.send("What is your question?")
(that's all the code I have so far)
Try this. question will be what the user inputted. It waits for a message in the same channel as the orginal command and by the same user who did the command
#client.event
async def on_message(message, author):
if message.content.startswith('$8Ball'):
channel = message.channel
author = message.author
await channel.send('What is your question?')
def check(m):
return m.author == author and m.channel == channel
msg = await client.wait_for('message', check=check)
question = msg.content
Tell me how it goes :D
You can try to store the id of the user and react to the next message of this user.

How do I make it so my discord bot only take inputs from the person that started the command

#client.command()
async def submitcluetest(ctx):
await ctx.send(f"{ctx.author.mention}Check your dms!")
await ctx.author.send('Submit your answer here, all lowercase. Do not reveal this to anyone else if you got it right, everyone who solves it gets a special role :smirk:')
message = await client.wait_for('message')
if message.content == 'twopeople':
await ctx.send('correct answer')
else
await ctx.send('try again')
This is my code right now. The problem is that once someone starts the command and tries to input their answer, someone else could type something and interrupt them. I would like message.content only be detected by the user. I tried using message.author.content or author.message.content but that still wouldn't work.
Inorder to check the author sent a message or someone sent a message you can create a function which returns True if author sent a message or return False if someone sent a message. Just pass the new function you created as parameter in the client.wait_for function so that your bot wait till the author sends the message in the channel. You can also specify a timeout parameter which make the bot to know how much much time it should wait in seconds
You can understand this in the below example
#client.command()
async def submitcluetest(ctx):
def check(m):
return m.author == ctx.author and m.channel == ctx.channel
await ctx.send(f"{ctx.author.mention}Check your dms!")
await ctx.author.send('Submit your answer here, all lowercase. Do not reveal this to anyone else if you got it right, everyone who solves it gets a special role :smirk:')
try:
message = await client.wait_for('message', timeout=120, check=check)
except asyncio.TimeoutError:
await ctx.send("You didn't entered in time.Please answer at next time!")
return
else:
if message.content == 'twopeople':
await ctx.send('correct answer')
else
await ctx.send('try again')
Use a lambda expression for the check.
message = await self.client.wait_for('message', check=lambda m: m.author == ctx.author)

Waiting for command author's reaction to edit to the help category page

message=await ctx.send(f"{ctx.author.mention}, after reacting to an emoji below the message will be edited to your choosen category)
await message.add_reaction('📜')
await message.add_reaction('🔧')
await message.add_reaction('🔨')
await message.add_reaction('🔥')
message = await client.wait_for('on_reaction_add', timeout= 10, check=lambda message: message.author == ctx.author)
if message.reaction_add == '📜':
await ctx.send("You reacted!")
Im making a command to use the help page and it edits the pre-existing help message to the category the user chooses that corresponds to the emoji they reacted for.
I have used a way that has no checks which annoys other people if they happen to react with those emojis to another message, is there are way to make a check similar to what I have already done or close to, where the message of help can be edited to the page the user wants and only works if they used the command specifically for the author that can use the emojis?
To condense this a little bit, I will use only two of the provided reactions.
#client.command()
async def test(ctx):
message = await ctx.send("Message that's getting reactions")
paper = '📜' # for the sake of "I'd rather not copy and paste these emojis a lot"
hammer = '🔨'
await message.add_reaction(paper)
await message.add_reaction(hammer)
def check(reaction, user):#checking for reactions and user
return user == ctx.author and str(reaction.emoji) in [paper, hammer]
# in this case, the message author and the reaction emojis paper and hammer
try:
reaction, user = await client.wait_for("reaction_add", timeout = 3, check=check)
# waiting for a reaction to be added
if str(reaction.emoji) == paper:
await ctx.send("You reacted!")
if str(reaction.emoji) == hammer:
await message.edit(content="Another reaction!")# this is for editing the message sent
except: # Timeout error-handling
await message.edit(content="Run command to use again!")
If you'd like, you could also include while True so the user doesn't have to constantly execute the command.
Working test as seen in the image below:
References:
discord.Client.wait_for
discord.Message.edit
How to loop with a reaction embed menu (SO)
reaction, user = await client.wait_for('reaction_add', timeout=10.0, check...)
If you read the docs about on_reaction_add, you'll see that it takes reaction and user arguments.
To edit the message:
message = reaction.message
await message.edit(content='new content!')

bot accepting user input via DM?

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"]))

Categories

Resources