Checks For Reactions Discord.py - discord.py

So I want to make a text game that edits the character every time the author who called the command reacts. My code so far for adding reactions:
#client.command()
async def test(ctx):
msg = await ctx.send('Hi')
up = '⬆'
down = '⬇'
left = '⬅'
right = '➡'
await msg.add_reaction(up)
await msg.add_reaction(down)
await msg.add_reaction(left)
await msg.add_reaction(right)
This adds the up arrow, down arrow, left arrow, and right arrow to the message "Hi". I want to see if someone clicked on the arrow and if that someone is the author of the command. I have no idea how to get if the author of the command clicked on the arrow reaction. Any help would be appreciated.

If you're waiting for a reaction, use wait_for() with the reaction_add event as the positional argument.
To limit it to the invoker, you can create a check and pass it into the check kwarg of wait_for(). The check would take in two arguments and you only need to compare if ctx.author is the same as the check author.
There is an example for wait_for() in the documentation
References: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html?highlight=wait_for#discord.ext.commands.Bot.wait_for

Related

Multiple SlashOptions Nextcord

I am trying to to create a command that that allows a user to select multiple options and then put them in an embed. So far I have been able to do this with one option but I want to do it with more as well. Is there a way to add multiple SlashOptions to a slash command and if so how might it be done. Thank you for all your help.
Here is what I currently have
async def announce(interaction: Interaction, buysell:str = SlashOption(
name="bto-stc",
choices={"BTO": "BTO", "STC": "STC"}),
stock:str,):
embed = nextcord.Embed(description=f"**Options Entry**", color=0x00FF00)
embed.add_field(name=f"** [🎟️] Contract:** *{buysell}* *{stock}*", value="⠀", inline=False)
await interaction.response.send_message(embed=embed, ephemeral=False)```
Here is what I would like the end product to look like.
https://i.stack.imgur.com/9SmIK.png
Your stock argument must be before your choices argument as for Python this argument is and optional argument and you can't have required arguments before optionals ones.
Also if you don't want your buysell argument to be optional you need to add a required argument set to True in your SlashOption object. And in your case you can also replace the choices argument in the SlashOptionobject by a list as the choices and the data you want from them are the same.
Example:
async def announce(interaction: Interaction, stock:str, buysell:str = SlashOption(
name="bto-stc",
choices=["BTO", "STC"],
required=True)):
embed = nextcord.Embed(description=f"**Options Entry**", color=0x00FF00)
embed.add_field(name=f"** [🎟️] Contract:** *{buysell}* *{stock}*", value="⠀", inline=False)
await interaction.response.send_message(embed=embed, ephemeral=False)

trying to make a choose command (like pls choose)

I've been trying to code a choose command like how dank memer has one but without the slash commands but the problem is i dont have that much coding knowledge to make the bot choose beetween 2 things so i did a code like this:
#bot.command(pass_context=True)
async def choose(ctx, *, message1, message2):
possible_responses = [
f"i choose {message1}",
f"i choose {message2}",
]
await ctx.send(random.choice(possible_responses) + " ")
the code worked but it only send "i choose" so how can i make my bot choose beetween 2 words and send the answer?
This is a very simple way of doing it,
#bot.command()
async def choose(ctx, option1, option2, option3):
choices = [option1, option2, option3]
await ctx.send(f"I choose, {random.choice(choices)}")

How can i get this condition to work properly | Discord.py

the intention was to when -rickroll is used and the bot is pinged it should say no u if not | update-> the user is the one who has to be pinged.
the it should send a gif and say (#the pinged) has been rickrolled lol
if user.id != 878176818564317184:
await ctx.send('https://tenor.com/view/rick-astley-rick-roll-dancing-dance-moves-gif-14097983')
await ctx.send(user)
await ctx.send('has been rickrolled lol')
else:
await ctx.send('No u')```
i don't know what is wrong with your code since you didn't post any information so i wrote this:
#bot.event
async def on_message(message):
if message.author == bot.user:
return
#refering to the message sent in discord and chaning it to lower case
msg = message.content.lower().replace(' ', '')
if msg.startswith('!help'):
if message.author.id != 878176818564317184:
await message.channel.send('''https://tenor.com/view/rick-astley-rick-roll-dancing-dance-moves-gif-14097983''')
await message.channel.send(f'''{message.author.mention} you have been rickrolled lol''')
else:
await message.channel.send('No u')
Supposing ctx is the first parameter of the discord.py on_message event, then the variable ctx is an instance of the discord.message.Message class which contains no method called send, thus ctx.send(user) is not going to work.
Assuming you want your bot to respond in the same text channel the message was sent to, you can take advantage of the channel attribute from the Message class, which contains a send method that will allow you to send messages.
Therefore a possible solution would be:
await ctx.channel.send("Your message")
A different but less usual approach would consist on the usage of the Message.reply method. It would be like this:
await ctx.reply("Hey, I'm replying to your msg!")
The biggest difference between the two would be that the second uses Discord's reply feature, hence the user who sent the message in first place would be pinged.
You can find this and more information in the official documentation of the library.
Please read https://stackoverflow.com/help/how-to-ask before posting another question, it will make easier for others to understand the problem you ran into and help you.

Replying to a message with a embed (Discord.py)

i'm having a problem where i can't reply to a message with an embed.
is this even possible? I'm guessing it is and im just doing it horribly wrong.
My error - TypeError: object method can't be used in 'await' expression
if message.content.startswith('!test'):
await message.reply
embedVar = discord.Embed(description=".order", color=0x7289da)
embedVar.add_field(name='test', value='test')
await message.channel.send(embed=embedVar)
Looking at the discord.py API Reference, it should be possible. Note that Message.reply() is a method, not an attribute. The documentation describes the method:
A shortcut method to abc.Messageable.send() to reply to the Message.
The method takes positional argument content and keywords arguments kwargs, which correspond to the keyword arguments of the TextChannel.send() method. Since embed is one of the keyword arguments, it is one of reply() as well.
if message.content.startswith('!test'):
embed = discord.Embed(description=".order", color=0x7289da)
embed.add_field(name="test", value="test")
await message.reply(embed)
On a side note, I suggest using the discord.ext.commands framework instead of using on_message() and string methods.
You are not using the reply function correctly. You cannot have it by itself, as you have done with await message.reply in your code.
# on_message event, the way you have done it
if message.content.startswith('!test'):
await message.reply("This is a test!")
# or if you prefer the commands extension (recommended)
#bot.command()
async def test(ctx):
await ctx.reply("This is a test!")
# you can also make it so it doesn't mention the author
await ctx.reply("This is a test!", mention_author=False)
# Note that both of the code in the commands example can be used in your on_message event
# as long as you remember to change ctx to message
The above code has been tested as seen in the image below.
As for replying with embeds, I have found that if the bot is only replying with an embed, it may not mention the author.
embed = discord.Embed(description="This is a test", color=0x123456)
await message.reply(embed=embed)
The above code works as seen in the image below.
Try this :
embed=discord.Embed(title="Tile",
description="Desc", color=0x00ff00)
embed.add_field(name="Fiel1", value="hi", inline=False)
embed.add_field(name="Field2", value="hi2", inline=False)
await self.bot.say(embed=embed)
`

Discord python how can I get all the banned users?

I was looking at the API Reference and I found fetch_ban(user). How can I check if the user is banned from the server, I was reading that it returns the the BanEntry, and get a boolean? Can I use member as well or I need to get the user?
Thank you for any reply.
Tip: Always link what you're talking about.
fetch_ban
BanEntry (discord.py source code)
If you go through the source code you will very quickly find this in the first lines:
BanEntry = namedtuple('BanEntry', 'reason user')
Returned is a BanEntry object if the user is banned, otherwise it returns a NotFound Exception.
So to check if a user is banned just do:
async def is_banned(guild, user):
try:
entry = await guild.fetch_ban(user)
except discord.NotFound:
return False
return True
This will also work with members, as they are basically user objects with a bit of extra.
BanEntry is a named tuple (if you need a refresher on those here).
if you wanna command that sending list of banned users
async def banlist(self, ctx):
bans = await ctx.guild.bans()
loop = [f"{u[1]} ({u[1].id})" for u in bans]
_list = "\r\n".join([f"[{str(num).zfill(2)}] {data}" for num, data in enumerate(loop, start=1)])
await ctx.send(f"```ini\n{_list}```")
it gives list like this
[01] 尸仁长仈乃冂仨#0529 (269800030300033098)
[02] Yako#1001 (294113773333557952)
[03] Ping#9216 (46804048093530418)
[04] Vasky#6978 (494069478291921344)

Resources