Wait_For_Reaction() multiple emojis - python

I'm looking to make a command where if the message.author tags a user, the bot will react twice to the message then will wait for the user who was tagged to select either one or the other reaction to choose. Right now everything works except when the user reacts to one or the other emoji, it doesn't do anything. When they react to both emojis, it sends the message for reaction.
if message.content.lower().startswith('!marry'):
user = message.mentions[0]
if message.author == user:
await client.send_message(message.channel, "{} you can't marry yourself dummy ๐Ÿ˜’".format(message.author.mention))
else:
if get_spouse(message.author) != "No One":
await client.send_message(message.channel, "{}, you're already married to {} ๐Ÿ˜’".format(message.author.mention, get_spouse(message.author)))
else:
if (get_spouse(user)) != "No One":
await client.send_message(message.channel, "{} is already married. Get your own spouse. ๐Ÿ˜’".format(user.mention))
else:
marriagemsg = await client.send_message(message.channel, "{} *has proposed to* {} ๐Ÿ’".format(message.author.mention, user.mention))
await client.add_reaction(marriagemsg, "โœ…")
await client.add_reaction(marriagemsg, "โŒ")
while True:
reaction = await client.wait_for_reaction(emoji="โœ…", message=marriagemsg,
check=lambda reaction, user: user == message.mentions[0])
reaction2 = await client.wait_for_reaction(emoji="โŒ", message=marriagemsg,
check=lambda reaction, user: user == message.mentions[0])
if reaction:
await client.send_message(message.channel, "{} **is now married to** {} ๐Ÿคต๐Ÿ‘ฐ".format(message.author.mention, reaction.user.mention))
add_spouse(message.author, user.name)
add_spouse(reaction.user, message.author.name)
else:
if reaction2:
await client.send_message(message.channel, "{} **rejects** {}**'s proposal** โœ‹๐Ÿ™„".format(reaction2.user.mention, message.author.mention))

The multiple wait_for_reaction checks that you are using is causing this. The bot will wait until the user reacts with โœ… on marriagemsg and only then check if the user reacts with โŒ.
Instead of using multiple wait_for_reaction checks, just use one and populate your emojis in a list. You can also use elif instead of else: if.
if message.content.lower().startswith('!marry'):
user = message.mentions[0]
if message.author == user:
await client.send_message(message.channel, "{} you can't marry yourself dummy ๐Ÿ˜’".format(message.author.mention))
else:
if get_spouse(message.author) != "No One":
await client.send_message(message.channel, "{}, you're already married to {} ๐Ÿ˜’".format(message.author.mention, get_spouse(message.author)))
else:
if (get_spouse(user)) != "No One":
await client.send_message(message.channel, "{} is already married. Get your own spouse. ๐Ÿ˜’".format(user.mention))
else:
marriagemsg = await client.send_message(message.channel, "{} *has proposed to* {} ๐Ÿ’".format(message.author.mention, user.mention))
await client.add_reaction(marriagemsg, "โœ…")
await client.add_reaction(marriagemsg, "โŒ")
answer = await client.wait_for_reaction(emoji=["โœ…", "โŒ"], message=marriagemsg,
check=lambda reaction, user: user == message.mentions[0])
if answer.reaction.emoji == "โœ…":
await client.send_message(message.channel, "{} **is now married to** {} ๐Ÿคต๐Ÿ‘ฐ".format(message.author.mention, answer.user.mention))
add_spouse(message.author, user.name)
add_spouse(answer.user, message.author.name)
elif answer.reaction.emoji == "โŒ":
await client.send_message(message.channel, "{} **rejects** {}**'s proposal** โœ‹๐Ÿ™„".format(answer.user.mention, message.author.mention))

Related

Delete channel on reaction | discord.py

I am creating ticket tool for my server. So whenever a user will react to the message a new channel will be created, but I want the bot to send a message in that new channel saying "React below to delete the ticket.". But can I do that without storing msg_id and other data in a global variable?
Code:
#bot.event
async def on_raw_reaction_add(payload):
if payload.member.id != bot.user.id and str(payload.emoji)== u"\U0001F3AB":
msg_id, channel_id, category_id= bot.ticket_configs[payload.guild_id]
if payload.message_id == msg_id:
guild= bot.get_guild(payload.guild_id)
for category in guild.categories:
if category.id == category_id:
break
guild = await bot.fetch_guild(460654239094669332)
channels = guild.text_channels
channel = guild.get_channel(842807548968042536)
duplicate = False
topic = f"<#!{payload.member.id}>'s ticket"
for channel in channels:
if topic == channels.topic:
duplicate = True
break
if duplicate:
return
else:
ticket_num= 1 if len(category.channels) == 0 else int(category.channels[-1].name.split("-")[1]) + 1
ticket_channel= await category.create_text_channel(f"Ticket-{ticket_num}", topic= topic, permission_synced= True)
await ticket_channel.set_permissions(payload.member, read_messages= True, send_messages= True)
print(msg_id)
embed= discord.Embed(title= "New Ticket!!!", description= f"{payload.member.mention} Thank You! for creating this ticket staff will contact you soon. Type **-close** to close the ticket.")
message= await ticket_channel.send(embed=embed)
await message.add_reaction("โŒ")
Help will be really appreciated
You can use bot.wait_for with a simple check
message = await ctx.send("React below to delete the ticket")
def check(reaction, user):
return reaction.message == message and str(reaction) == "โœ…" # you can use another emoji, or don't use it at all
try:
await bot.wait_for("reaction_add", check=check, timeout=60.0) # timeout is optional
except asyncio.TimeoutError:
...
else:
await channel.delete() # where `channel` is the channel to delete

Get emoji from reaction in discord.py

I'm trying to make an 'accept/decline' embed with reactions, but I cannot get with which emoji the user reacted.
message = await guild.owner.send(embed=embed)
await message.add_reaction('โœ”')
await message.add_reaction('โŒ')
def check(reaction, user):
print(f"reacted")
return guild.owner == message.author and str(reaction.emoji) in ["โœ”", "โŒ"] and isinstance(message.channel, discord.DMChannel)
reaction, user = await bot.wait_for('reaction_add', timeout=1000.0, check=check)
if reaction.emoji == "โœ”":
print("tick")
elif reaction.emoji == "โŒ":
print("cross")
I get the
reacted
but I don't get anything in what refers to the cross and tick. Is there any way to get it?
Thanks in advance
Simply do the same you did in the check func, also discord by default doesn't have this reaction โœ” you're looking for โœ….
if str(reaction) == 'โŒ': # or str(reaction.emoji)
print('cross')
elif str(reaction) == 'โœ…':
print('tick')

How to make a Discord.Py random reaction game

How can I make the bot choose a right random answer (as a reaction)
And if the user gets it right send a winner message
if its wrong send a loser message.
redcrew = '<:redcrewmates:776867415514153031>'
bluecrew = '<:bluecrewmates:776867439085617153>'
limecrew = '<:limecrewmates:776867489866711041>'
whitecrew = '<:whitecrewmates:776867529900425217>'
await msg1.add_reaction(redcrew)
await msg1.add_reaction(bluecrew)
await msg1.add_reaction(limecrew)
await msg1.add_reaction(whitecrew)
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) ==
try:
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await ctx.send('Sorry, you took too long to vote!')
else:
await ctx.send('hello')
def setup(bot):
bot.add_cog(games(bot))```
**DONT WORRY ABOUT THE INDENTS**
import random
#bot.command()
async def reaction_game(ctx):
reactions = [
'<:redcrewmates:776867415514153031>',
'<:bluecrewmates:776867439085617153>',
'<:limecrewmates:776867489866711041>',
'<:whitecrewmates:776867529900425217>'
]
winning_reaction = random.choice(reactions)
message = await ctx.send('some message')
for reaction in reactions:
await ctx.add_reaction(reaction)
def check(reaction, user):
return user == ctx.author and str(reaction) == winning_reaction
try:
reaction, user = await bot.wait_for('reaction_add', check=check, timeout=60.0)
await ctx.send('You reacted with the winning emoji')
except asyncio.TimeoutError:
await ctx.send('You took too long to react')
else:
await ctx.send('hello')

Discord.py find who reacted to a message

I'm coding a discord bot and creating a game. I need to get the user that reacted to the message with the specific emoji to add in a list. How can i do that?
(my code below)
#client.command(aliases=['rr'])
async def roletarussa(ctx):
embed = discord.Embed(title="ROLETA RUSSA", description="Reaja com โœ… para participar!")
embed.set_thumbnail(
url="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcRa7rdwxpSOiReyDvnVd6MzqDg33rtQrxhoUw&usqp=CAU")
embed.add_field(name="Sรณ os brabo consegue entrar nesse web desafio ๐Ÿ”ซ๐Ÿค ",
value="Vai logo entra nesse bagaรงa medroso!", inline=False)
embed.set_image(url='https://media1.tenor.com/images/64e0334d77b0976b808147bd160b8534/tenor.gif?itemid=12379724')
message = await ctx.send(embed=embed)
await message.add_reaction("โœ…")
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in ['โœ…']
while True:
try:
reaction, user = await client.wait_for("reaction_add", timeout=60, check=check)
if str(reaction.emoji) == "โœ…":
await ctx.send('{} vai participar'.format(user))
await message.remove_reaction(reaction, user)
else:
await message.remove_reaction(reaction, user)
except asyncio.TimeoutError:
await message.delete()
break
# ending the loop if user doesn't react after x seconds
#client.command()
async def startrr(ctx):
players = []
maxlenght = 6
while len(players) < maxlenght:
rrp = ctx.message.author.mention
players.append(rrp)
players = list(set(players))
else:
await ctx.send('Sem mais vagas para o jogo.')
await ctx.send(players)
I need to get who reacted to the msg and store in 'players' list.

Poll command discord.py

DISCORD.PY
I try to create an command for a poll system and encounter a problem. Command is as follows:
#commands.command(pass_context = True)
async def poll(self, ctx, question, *options: str):
author = ctx.message.author
server = ctx.message.server
if not author.server_permissions.manage_messages: return await self.bot.say(DISCORD_SERVER_ERROR_MSG)
if len(options) <= 1:
await self.bot.say("```Error! A poll must have more than one option.```")
return
if len(options) > 2:
await self.bot.say("```Error! Poll can have no more than two options.```")
return
if len(options) == 2 and options[0] == "yes" and options[1] == "no":
reactions = ['๐Ÿ‘', '๐Ÿ‘Ž']
else:
reactions = ['๐Ÿ‘', '๐Ÿ‘Ž']
description = []
for x, option in enumerate(options):
description += '\n {} {}'.format(reactions[x], option)
embed = discord.Embed(title = question, color = 3553599, description = ''.join(description))
react_message = await self.bot.say(embed = embed)
for reaction in reactions[:len(options)]:
await self.bot.add_reaction(react_message, reaction)
embed.set_footer(text='Poll ID: {}'.format(react_message.id))
await self.bot.edit_message(react_message, embed=embed)
My question is: How can I make the question I ask using the command to have more words. If I use more words now, I read them as options and get an error.
Ex 1: /poll You are human yes no (only read "you" as a question, and the rest are options.)
Ex 2: /poll You are human yes no (that's what I want)
Thank you!
When calling the command, putting a string in quotes will cause it to be treated as one argument:
/poll "You are human" yes no
You can do:
#bot.command()
async def poll(ctx, question, option1=None, option2=None):
if option1==None and option2==None:
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \n{question}```\n**โœ… = Yes**\n**โŽ = No**")
await message.add_reaction('โŽ')
await message.add_reaction('โœ…')
elif option1==None:
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \n{question}```\n**โœ… = {option1}**\n**โŽ = No**")
await message.add_reaction('โŽ')
await message.add_reaction('โœ…')
elif option2==None:
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \n{question}```\n**โœ… = Yes**\n**โŽ = {option2}**")
await message.add_reaction('โŽ')
await message.add_reaction('โœ…')
else:
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \n{question}```\n**โœ… = {option1}**\n**โŽ = {option2}**")
await message.add_reaction('โŽ')
await message.add_reaction('โœ…')
but now you must do /poll hello-everyone text text
if you want to to not have the "-" you must do:
#bot.command()
async def poll(ctx, *, question):
await ctx.channel.purge(limit=1)
message = await ctx.send(f"```New poll: \nโœ… = Yes**\n**โŽ = No**")
await message.add_reaction('โŽ')
await message.add_reaction('โœ…')
But in this one you can't have your own options...
use :
/poll "You are human" yes no
here, "You are human" is one string "yes" "no" are other two strings.
another better way to do it is:
#commands.command(pass_context = True)
async def poll(self, ctx, option1: str, option2: str, *, question):
or, you can use wait_for
#commands.command(pass_context = True)
async def poll(self, ctx, *options: str):
...
question = await self.bot.wait_for('message', check=lambda message: message.author == ctx.author)
...
it is working
#commands.has_permissions(manage_messages=True)
#commands.command(pass_context=True)
async def poll(self, ctx, question, *options: str):
if len(options) > 2:
await ctx.send('```Error! Syntax = [~poll "question" "option1" "option2"] ```')
return
if len(options) == 2 and options[0] == "yes" and options[1] == "no":
reactions = ['๐Ÿ‘', '๐Ÿ‘Ž']
else:
reactions = ['๐Ÿ‘', '๐Ÿ‘Ž']
description = []
for x, option in enumerate(options):
description += '\n {} {}'.format(reactions[x], option)
poll_embed = discord.Embed(title=question, color=0x31FF00, description=''.join(description))
react_message = await ctx.send(embed=poll_embed)
for reaction in reactions[:len(options)]:
await react_message.add_reaction(reaction)
#create a yes/no poll
#bot.command()
#the content will contain the question, which must be answerable with yes or no in order to make sense
async def pollYN(ctx, *, content:str):
print("Creating yes/no poll...")
#create the embed file
embed=discord.Embed(title=f"{content}", description="React to this message with โœ… for yes, โŒ for no.", color=0xd10a07)
#set the author and icon
embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url)
print("Embed created")
#send the embed
message = await ctx.channel.send(embed=embed)
#add the reactions
await message.add_reaction("โœ…")
await message.add_reaction("โŒ")
for your code to treat the text in the user's message as one string, use "content:str" in your command arguments
I know my code isn't very dynamic and pretty but i did that and it's functional.
#client.command()
async def poll(ctx):
options = ['1๏ธโƒฃ Yes Or No', '2๏ธโƒฃ Multiple Choice']
embed = discord.Embed(title="What type of poll you want ?" , description="\n".join(options), color=0x00ff00)
msg_embed = await ctx.send(embed=embed)
reaction = await client.wait_for("reaction_add", check=poll)
if (reaction[0].emoji == '1๏ธโƒฃ'):
user = await client.fetch_user(ctx.author.id)
msg = await user.send("What is your question ?")
question = await client.wait_for("message", check=lambda m: m.author == ctx.author)
answers = ['\n\u2705 Yes\n', '\u274C No']
new_embed = discord.Embed(title="Poll : " + question.content, description="\n".join(answers), color=0x00ff00)
await msg_embed.edit(embed=new_embed)
await msg_embed.remove_reaction('1๏ธโƒฃ', user)
await msg_embed.add_reaction('\N{WHITE HEAVY CHECK MARK}')
await msg_embed.add_reaction('\N{CROSS MARK}')
elif (reaction[0].emoji == '2๏ธโƒฃ'):
user = await client.fetch_user(ctx.author.id)
msg = await user.send("What is your question ?")
question = await client.wait_for("message", check=lambda m: m.author == ctx.author)
msg = await user.send("What are the choices ? (Four compulsory choices, separated by comma)")
choices = await client.wait_for("message", check=lambda m: m.author == ctx.author)
choices = choices.content.split(',')
if (len(choices) > 4):
await msg_embed.delete()
await user.send("You can't have more than four choices")
return
if (len(choices) < 4):
await msg_embed.delete()
await user.send("You can't have less than four choices")
return
answers = ['1๏ธโƒฃ '+ choices[0] + '\n', '2๏ธโƒฃ '+ choices[1] + '\n', '3๏ธโƒฃ '+ choices[2] + '\n', '4๏ธโƒฃ '+ choices[3] + '\n']
new_embed = discord.Embed(title=question.content, description="\n ".join(answers), color=0x00ff00)
await msg_embed.edit(embed=new_embed)
await msg_embed.remove_reaction('2๏ธโƒฃ', user)
await msg_embed.add_reaction('1๏ธโƒฃ')
await msg_embed.add_reaction('2๏ธโƒฃ')
await msg_embed.add_reaction('3๏ธโƒฃ')
await msg_embed.add_reaction('4๏ธโƒฃ')

Categories