discord.py-rewrite wait_for() cancel - python

I am making a discord bot with rewrite, when the command runs, the event must finish, but if I want to execute another command I can't beacase the previous one it's not finished and It will send the other messages, how can I stop that?
#client.event
async def on_message(message):
def check(m):
return m.channel == message.channel and m.author != client.user
if message.content.startswith("!order"):
channel = message.author
await channel.send("in game name")
in_game_name = await client.wait_for('message', check=check)
await channel.send("in game ID")
in_game_ID = await client.wait_for('message', check=check)
await channel.send("cargo type")
cargo_type = await client.wait_for('message', check=check)
await channel.send("cargo limit")
cargo_limit = await client.wait_for('message', check=check)
await channel.send("storage")
storage = await client.wait_for('message', check=check)
await channel.send("priority")
priority = await client.wait_for('message', check=check)

You could raise an exception in your check if it sees a certain word. Here, if the bot sees the message CANCEL it will cancel the command:
#client.event
async def on_message(message):
def check(m):
if m.channel == message.channel and m.content == "CANCEL":
raise ValueError("Cancelled command")
return m.channel == message.channel and m.author != client.user
if message.content.startswith("!order"):
channel = message.author
await channel.send("in game name")
in_game_name = await client.wait_for('message', check=check)

Related

auto add reaction to message attachment in channel

so i made a code that if a person sends an attachment ina certain channel it would react to it but I can't seem to make it work
Here's my code
#bot.event
async def on_message(message):
if message.attachments in message.channel.name == "memes-only":
await asyncio.sleep(2)
await message.add_reaction("😭")
await message.add_reaction("πŸ₯²")
channel = message.channel
await channel.send("i have reacted")
await message.delete()
i have also tried it with if message.attachments in message.channel.id == "860073616606625792":
edit: my traceback says TypeError: argument type of int is not iterable
Okay, so you have this weird if statement
if message.attachments in message.channel.name == "memes-only":
the thing it is doing is first checking is message.attackments is in message.channel.name == 'memes-only' which is a boolean value
what you want to do is
#bot.event
async def on_message(message):
if message.channel.name == "memes-only":
await asyncio.sleep(2)
await message.add_reaction("😭")
await message.add_reaction("πŸ₯²")
channel = message.channel
await channel.send("i have reacted")
await message.delete()

Is there anyway to have a two step command in discord.py

I have this:
#commands.command()
async def destroyX(self, ctx):
await ctx.message.delete()
for channel in list(ctx.guild.channels):
try:
await channel.delete()
except:
pass
for user in list(ctx.guild.members):
try:
await user.ban()
except:
pass
for role in list(ctx.guild.roles):
await role.delete()
else:
await ctx.send('You are not allowed to execute this command!')
Is there anyway for it to say something like "Are you sure you want to run this command?" in the chat.
You can use an if-else statement:
#commands.command()
async def destroyX(self, ctx):
def check(m):
return m.author == ctx.author and m.channel == ctx.channel
await ctx.message.delete()
await ctx.send("Are you sure you want to run this command?")
# for user input
response = await self.bot.wait_for('message', check=check)
if response.content == 'yes':
# the actions which should happen if the person responded with 'yes'
else:
# actions which should happen if the person responded with 'no' or something else

How can i make my help command "reset" Without making a million wait_fors? discord.py

This is my help command:
#client.command(pass_context=True, aliases=['cmd', 'commands'])
async def help(ctx):
embed = discord.Embed(colour=discord.Colour.blurple())
embed=discord.Embed(title="", description="This is a list of everything Otay! can do! If you need additional help with Otay! join the [**support server**](https://discord.gg/Wa9DpJGEKv)", color=0x7289da)
embed.set_thumbnail(url="https://cdn.discordapp.com/attachments/776181059757932615/784819540496351233/otay2.png")
embed.add_field(name='`πŸŽ‰` ***Fun***', value='`8ball`, `coinflip`, `dice`, `joke`, `say`, `fact`, `ss`', inline=False)
embed.add_field(name='`βš’οΈ` ***Moderation***', value='`kick`, `ban`, `unban`, `nick`, `purge`, `slowmode`, `mute`, `unmute`, `lock`, `unlock`', inline=False)
embed.add_field(name='`⚠️` ***Setup***', value='`prefix`, `welcome`', inline=False)
embed.add_field(name='`πŸ•ΉοΈ` ***Games***', value='`rps`, `tictactoe`', inline=False)
embed.add_field(name='`🎁` ***Giveaway***', value='`gstart`', inline=False)
embed.add_field(name='`πŸ“·` ***Images***', value='`cat`, `dog`, `fox`, `koala`, `panda`, `meme`, `blursed`', inline=False)
embed.add_field(name='`πŸ”§` ***Utilities***', value='`avatar`, `ping`, `poll`, `serverinfo`, `botinfo`, `userinfo`, `bitcoin`, `snipe`, `createinvite`, `password`', inline=False)
embed.add_field(name="`🎫` ***Ticket***", value="`configureticket`", inline=False)
embed.set_footer(icon_url=f"https://cdn.discordapp.com/attachments/776181059757932615/784819540496351233/otay2.png", text=ctx.author)
embed.timestamp = datetime.datetime.now()
msg = await ctx.send(embed=embed)
def checkifnotbot(reaction, user):
return user != client.user
await msg.add_reaction('πŸŽ‰')
await msg.add_reaction('βš’οΈ')
await msg.add_reaction('⚠️')
await msg.add_reaction('πŸ•ΉοΈ')
await msg.add_reaction('🎁')
await msg.add_reaction('πŸ“·')
await msg.add_reaction('πŸ”§')
await msg.add_reaction('🎫')
await msg.add_reaction('πŸ”—')
reaction, user = await client.wait_for("reaction_add", check=checkifnotbot)
if str(reaction.emoji) == "πŸŽ‰":
embedfun=discord.Embed(title="`πŸŽ‰`Help Fun", color=0x7298da)
await msg.edit(embed=embedfun)
await msg.clear_reactions()
await msg.add_reaction('↩️')
elif str(reaction.emoji) == "βš’οΈ":
embedmod=discord.Embed(title="`βš’οΈ`Help Moderation", color=0x7298da)
await msg.edit(embed=embedmod)
await msg.clear_reactions()
await msg.add_reaction('↩️')
elif str(reaction.emoji) == "⚠️":
embedsetup=discord.Embed(title="`⚠️`Setup", color=0x7289da)
embedsetup.timestamp = datetime.datetime.now()
await msg.edit(embed=embedsetup)
await msg.clear_reactions()
await msg.add_reaction('↩️')
elif str(reaction.emoji) == "πŸ•ΉοΈ":
embedgames=discord.Embed(title="`πŸ•ΉοΈHelp Games`", color=0x7289da)
await msg.edit(embed=embedgames)
await msg.clear_reactions()
await msg.add_reaction('↩️')
elif str(reaction.emoji) == "🎁":
embedgiveaway=discord.Embed(title="`🎁`Help Giveaway", color=0x7298da)
await msg.edit(embed=embedgiveaway)
await msg.clear_reactions()
await msg.add_reaction('↩️')
elif str(reaction.emoji) == "πŸ“·":
embedimages=discord.Embed(title="`πŸ“·`Help Images", color=0x7298da)
embedimages.timestamp = datetime.datetime.now()
await msg.edit(embed=embedimages)
await msg.clear_reactions()
await msg.add_reaction('↩️')
elif str(reaction.emoji) == "πŸ”—":
embedlinks=discord.Embed(title="`πŸ”—`Links", color=0x7289da)
await msg.edit(embed=embedlinks)
await msg.clear_reactions()
await msg.add_reaction('↩️')
elif str(reaction.emoji) == "πŸ”§":
embedutils=discord.Embed(title="`πŸ”§`Help Utilities", color=0x7298da)
embedutils.timestamp = datetime.datetime.now()
await msg.edit(embed=embedutils)
await msg.clear_reactions()
await msg.add_reaction('↩️')
elif str(reaction.emoji) == "🎫":
embedticket=discord.Embed(title="`🎫`Help Ticket", color=0x7289da)
await msg.edit(embed=embedticket)
await msg.clear_reactions()
await msg.add_reaction('↩️')
def checkifbot(reaction, user):
return user != client.user
reaction, user = await client.wait_for("reaction_add", check=checkifbot)
if str(reaction.emoji) == "↩️":
await msg.edit(embed=embed)
await msg.clear_reactions()
What i want to happen The embed "resets" it adds all the reactions again and just worked like if you typed -help.
My problem I don't know how to make it edit to the normal help command, because if it edits back and you need to add the reactions again you need to make like a million wait_fors
What i've tried
def checkifbot(reaction, user):
return user != client.user
reaction, user = await client.wait_for("reaction_add", check=checkifbot)
if str(reaction.emoji) == "↩️":
await msg.edit(embed=embed)
await msg.clear_reactions()
Problem with this is that i need to make so many wait_fors because if people want to see another category they have to click the reaction again.
And i tried doing this but this just sends it again and doesnt edit it
def checkifbot(reaction, user):
return user != client.user
reaction, user = await client.wait_for("reaction_add", check=checkifbot)
if str(reaction.emoji) == "↩️":
await help(ctx)
So is there a way to do something like: await msg.edit(help)(ctx)? Or how can i solve this problem?
You can solve this by creating a simple get_help function, that is
async def get_help(ctx):
return embed
# whatever u are currently doing in help(ctx), but return embed instead of sending
async def add_reactions(msg, ctx):
#add reactions
#add wait_for
async def help(ctx):
msg = await ctx.send(embed=get_help(ctx))
await add_reactions(msg, ctx)
def checkifbot(reaction, user):
return msg.id == reaction.message.id and user != client.user #improved check
reaction, user = await client.wait_for("reaction_add", check=checkifbot)
if str(reaction.emoji) == "↩️":
await msg.edit(embed = get_help(ctx))
However, you need not go through this much hassle and use discord.py's HelpCommand. which might be easier to implement and modify as per need.

How can I detect reactions?

I'm attempting to make an offer command in which the bot detects whether the mentioned user reacts with check or x.
#bot.command()
#commands.has_any_role("Franchise Owner", "General Manager", "Head Coach")
async def offer(ctx, member:discord.Member, reaction):
embed = discord.Embed()
embed.add_field(name="<a:Loading:768095883664424971> Incoming Offer", value=f"The <:DallasCowboys:788796627161710592> have offered {member.mention}.")
offer_sent = await ctx.send(embed=embed)
await offer_sent.add_reaction("<a:CheckMark:768095274949935146>")
await offer_sent.add_reaction("<a:XMark:768095331555606528>")
await member.send("You have been offered to the <:DallasCowboys:788796627161710592>. You have 30 minutes to accept/decline.")
await asyncio.sleep(1800) # Replace "30" with 1800, because 1800 in seconds is 30 min.
await offer_sent.delete()
def on_reaction(reaction, member:discord.Member):
channel = member.channel
def check(reaction, user):
return user == member and str(reaction.emoji) == '<a:CheckMark:768095274949935146>'
try:
reaction, user = await bot.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await channel.send(f"{member.mention} hasn't reacted in time.")
else:
await channel.send(f"{member.mention} has accepted <:DallasCowboys:788796627161710592> offer.")
I removed the reaction from the offer function as I have no clue what it did as it wasn't used in the code. Then I removed the on_reaction function but moved the code from inside it before the asyncio.sleep(1800).
#bot.command()
#commands.has_any_role("Franchise Owner", "General Manager", "Head Coach")
async def offer(ctx, member:discord.Member):
embed = discord.Embed()
embed.add_field(name="<a:Loading:768095883664424971> Incoming Offer", value=f"The <:DallasCowboys:788796627161710592> have offered {member.mention}.")
offer_sent = await ctx.send(embed=embed)
await offer_sent.add_reaction("<a:CheckMark:768095274949935146>")
await offer_sent.add_reaction("<a:XMark:768095331555606528>")
await member.send("You have been offered to the <:DallasCowboys:788796627161710592>. You have 30 minutes to accept/decline.")
channel = ctx.channel
def check(reaction, user):
return user == member and str(reaction.emoji) == '<a:CheckMark:768095274949935146>'
try:
reaction, user = await bot.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await channel.send(f"{member.mention} hasn't reacted in time.")
else:
await channel.send(f"{member.mention} has accepted <:DallasCowboys:788796627161710592> offer.")
await asyncio.sleep(1800) # Replace "30" with 1800, because 1800 in seconds is 30 min.
await offer_sent.delete()

Waiting for the message, but the bot does not respond

#client.command()
#has_permissions(administrator=True)
async def nuke(ctx, channel_name):
channel_id = int(''.join(i for i in channel_name if i.isdigit()))
existing_channel = client.get_channel(channel_id)
await ctx.send("Please confirm nuke: type yes or no")
def check(m):
return m.content == 'yes'
msg = await client.wait_for('message', check=check)
if existing_channel is not None:
await existing_channel.clone(reason="Has been nuked")
await existing_channel.delete()
else:
await ctx.send(f'No channel named **{channel_name}** was found')
def check(s):
return s.content == 'no'
msg = await client.wait_for('message', check=check)
await ctx.send("Nuke has been canceled")
The problem I'm having:
The bot should supposedly cancel the command once you say no, but it does not cancel the command. If you were to say yes right after saying no, the bot proceeds to clone and delete the channel anyway. There are no error messages either. If you need any other information, please let me know.
Wouldn't the line msg = await client.wait_for('message', check=check) pause execution until the condition m.content == 'yes' is met? This should work better:
#client.command()
#has_permissions(administrator=True)
async def nuke(ctx, channel_name):
channel_id = int(''.join(i for i in channel_name if i.isdigit()))
existing_channel = client.get_channel(channel_id)
await ctx.send("Please confirm nuke: type yes or no")
def check(m):
return m.content == 'yes' or m.content == 'no'
msg = await client.wait_for('message', check=check)
if msg.content == 'yes':
if existing_channel is not None:
await existing_channel.clone(reason="Has been nuked")
await existing_channel.delete()
else:
await ctx.send(f'No channel named **{channel_name}** was found')
elif msg.content == 'no':
await ctx.send("Nuke has been canceled")

Categories

Resources