I am trying to create a command wherein if you react on the embed, the bot sends something back. If I add this code to a cog, it won't work. If possible, can you tell me why?
#bot.command(aliases=['test','t'])
async def Test(self, ctx):
TestEmbed = discord.Embed(title="Definition", description="This is just a test embed", color=11027200)
TestEmbed.add_field(name="\u200b", value="▹❁❁▹❁◃❁❁◃",inline=False)
emojis = ['⬅️','➡️']
TestEmbedAdd = await ctx.send(embed=TestEmbed)
for emoji in emojis:
await TestEmbedAdd.add_reaction(emoji)
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in ['⬅️', '➡️']
try:
reaction, user = await bot.wait_for('reaction_add', timeout=5, check=check)
if reaction.emoji == '➡️':
await ctx.send("Reaction 2!")
elif reaction.emoji == '⬅️':
await ctx.send("Reaction 1!")
except asyncio.TimeoutError:
await ctx.send("Time is out!")
With the help of the people in the comment section, I have found the problem with my code. I had to change bot.command into commands.command. (I've tried both bot and command, and it still works splendidly). The other crucial thing I had to add was "self" under bot.wait_for. Without the self, the command wouldn't work. Thank you so much for the help.
#commands.command(aliases=['test','t'])
async def Testing(self, ctx):
TestEmbed = discord.Embed(title="Definition", description="This is just a test embed", color=11027200)
TestEmbed.add_field(name="\u200b", value="▹❁❁▹❁◃❁❁◃",inline=False)
emojis = ['⬅️','➡️']
TestEmbedAdd = await ctx.send(embed=TestEmbed)
for emoji in emojis:
await TestEmbedAdd.add_reaction(emoji)
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in ['⬅️', '➡️']
try:
reaction, user = await self.bot.wait_for('reaction_add', timeout=5, check=check)
if reaction.emoji == '➡️':
await ctx.send("Reaction 2!")
elif reaction.emoji == '⬅️':
await ctx.send("Reaction 1!")
except asyncio.TimeoutError:
await ctx.send("Time is out!")
you need #commands.command instead of #bot.command
Related
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
So basically i was making a modmail system and the problem was we wanted the person who dmed the bot has to react to ✅ if he reacts then the bot has to reply him "OK"
but the code was not working so what is the problem how to fix it?
import discord
import asyncio
client = discord.Client()
#client.event
async def on_message(message):
# empty_array = []
# modmail_channel = discord.utils.get(client.get_all_channels(), name="mod-mail")
if message.author == client.user:
return
if str(message.channel.type) == "private":
embed = discord.Embed(title='Confirmation',
color=0x03d692)
embed.add_field(name="You're sending this message to **The Dynamic Legends**", value="React with :white_check_mark: to confirm." + "\nTo cancel this request, react with :x:.", inline=False)
confirmation_msg = await message.author.send(embed=embed)
await confirmation_msg.add_reaction('✅')
await confirmation_msg.add_reaction('❌')
sent_users = []
sent_users.append(message.author.name)
try:
print('Working')
def check1(reaction, user):
return user == client.user and user!='Mod Mail Humara#5439' and str(reaction.emoji) == '✅'
reaction, user = await client.wait_for("reaction_add", timeout=30.0, check=check1)
# print(reaction, user)
if str(reaction.emoji) == '✅':
message.author.send('yes)
client.run('TOKEN')
There's a logic problem in the check func
return user == client.user
It simply doesn't make sense, instead of == use != and don't put the user!='Mod Mail Humara#5439' part
Your check func fixed:
def check1(reaction, user):
return user != client.user and str(reaction.emoji) == '✅'
Also message.author.send is a coroutine, so you need to await it
await message.author.send("whatever")
Your code:
#client.event
async def on_message(message):
if message.author == client.user:
return
if isinstance(message.channel, discord.DMChannel):
embed = discord.Embed(title='Confirmation', color=0x03d692)
embed.add_field(name="You're sending this message to **The Dynamic Legends**", value="React with :white_check_mark: to confirm." + "\nTo cancel this request, react with :x:.", inline=False)
confirmation_msg = await message.author.send(embed=embed)
await confirmation_msg.add_reaction('✅')
await confirmation_msg.add_reaction('❌')
sent_users = []
sent_users.append(message.author.name)
try:
def check1(reaction, user):
return user != client.user and str(reaction.emoji) == '✅'
reaction, user = await client.wait_for("reaction_add", timeout=30.0, check=check1)
if str(reaction.emoji) == '✅':
await message.author.send('yes')
except Exception as e:
pass
I'm creating a "delete faction" command for my faction bot which asks the user to confirm that they want to delete their faction using reactions. My code is as follows:
embed = discord.Embed(
title=":warning: Are you sure?",
colour=discord.Colour.purple(),
description=f"Are you sure you want to delete **{name_capital}**? "
f"*Your members will lose their roles and so will you.*"
)
txt = await ctx.send(embed=embed)
await txt.add_reaction("✅")
await txt.add_reaction("❌")
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) == "✅" or "❌"
try:
reaction, user = await self.client.wait_for('reaction_add', timeout=8.0, check=check)
except asyncio.TimeoutError:
embed = discord.Embed(
title=":x: Deletion cancelled",
colour=discord.Colour.purple(),
description="Message timed out"
)
await txt.delete()
await ctx.send(embed=embed)
else:
if reaction.emoji == "❌":
await txt.delete()
elif reaction.emoji == "✅":
pass # delete faction code
The command works for the most part. But, it also works for other users who react to the message, despite me stating that not to happen in the check function.
What is wrong and how can I fix it?
Just a guess, but your check function could be malformed. Should be like this:
def check(reaction, user):
return user == ctx.author and (str(reaction.emoji) == "✅" or "❌")
I'm doin a command that checks if a user is a bot or a normal user
#client.command()
async def maybebot(ctx, user: discord.Member):
embed = discord.Embed(title="Cheks if a user is a bot", description="Let's find out!")
if user.bot == True:
embed.add_field(name="And..", value="It is!")
if user.bot == False:
embed.add_field(name="And...", value="It's not!")
await ctx.send(embed=embed)
This is not working, no traceback, no error. What i should do?
#client.command()
async def maybebot(ctx, user: discord.Member):
embed = discord.Embed(title="Checks if a user is a bot", description="Let's find out!")
if user.bot:
embed.add_field(name="And...", value="It is!")
else:
embed.add_field(name="And...", value="It's not!")
await ctx.send(embed=embed)
In my discord bot I have some code that asks the user for input a couple of times in one command, Is there a way to have another bot command when triggered stops the current command or even forces the bot to stop running and restart entirely? Here is some of my smaller code, I would like to keep the same formatting and everything, just a command to break out of that command.
#client.command()
#commands.has_any_role("Betauri Members")
async def wsadd(ctx):
async def get_input_of_type(func):
global sentdex_guild
while True:
try:
msg = await client.wait_for('message', check=check)
return func(msg.content)
except ValueError:
continue
def check(m):
return m.content == m.content and m.channel == channel and m.author == ctx.author
channel = ctx.channel
await channel.send('type your ign, example...')
await channel.send('aaaafireball')
await channel.send('(dont retype $wslist)')
name = await get_input_of_type(str)
name = name+':'
await channel.send('type bs mods, example...')
await channel.send('bs: battery10,delta4,tw1,barrier1')
bs = await get_input_of_type(str)
await channel.send('type first support ship mods, example...')
await channel.send('miner: tw1,genesis1')
sup1 = await get_input_of_type(str)
await channel.send('type second support ship mods, example...')
await channel.send('trans: tw1,dispatch1')
sup2 = await get_input_of_type(str)
You can write your check such that it raises an exception instead of returning a falsy value when it sees certain kinds of messages:
class AbortWait(Exception):
pass
def check(m):
if m.content == 'abort':
raise AbortWait
return m.content == m.content and m.channel == channel and m.author == ctx.author
You can also handle the error in the error handler if you want special behaviour after the command has ended
#wsadd.error
async def wadd_error(ctx, error):
if isinstance(error, commands.CommandInvokeError) and isinstance(error.original, AbortWait):
await ctx.send("Command aborted")
else:
raise error
Hmm ..
What about an if statment after each step to check if the user wants to exit or not ?
Just like :
if(user_input.upper() == "QUIT"):
return