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')
Related
I watched a tutorial on how to get Input from users in Discord.py. The bot however, does not respond to the input given to it.
The bot sends the "This is a bot test. Type (YES/NO)" message. But when I type "yes" or "no" it does not respond.
#client.command()
async def bot(ctx):
await ctx.channel.send("This is a bot test. Type (YES/NO)")
try:
message = await bot.wait_for("message", check=lambda m: m.author == ctx.author and m.channel == ctx.channel, timeout=30.0)
except asyncio.TimeoutError:
await ctx.channel.send("I have been ignored")
else:
if message.content.lower() == "yes":
await ctx.channel.send("The test was succesfull!")
elif message.content.lower() == "no":
await ctx.channel.send("Thank you for your response")
else:
await ctx.channel.send("I cannot understand you")
You're decorating with client but calling bot in your function.
Change
#client.command()
async def bot(ctx):
await ctx.channel.send("This is a bot test. Type (YES/NO)")
try:
message = await bot.wait_for("message", check=lambda m: m.author == ctx.author and m.channel == ctx.channel, timeout=30.0)
To
#client.command()
async def bot(ctx):
await ctx.channel.send("This is a bot test. Type (YES/NO)")
try:
message = await client.wait_for("message", check=lambda m: m.author == ctx.author and m.channel == ctx.channel, timeout=30.0)
embed = discord.Embed(title = "Currently Playing", colour = discord.Colour.blue())
embed.add_field(name = "Song", value = title, inline = False)
embed.add_field(name = "Length", value = str(datetime.timedelta(seconds = length)), inline = False)
embed.add_field(name = "Link", value = url, inline = False)
msg = await ctx.send(embed=embed)
await msg.add_reaction("\u23F8")
await msg.add_reaction("\u25B6")
await msg.add_reaction("\u23F9")
while True:
try:
reaction, user = await client.wait_for("reaction_add", check=lambda reaction, user: user.id == ctx.author.id and reaction.message.id == msg.id and reaction.emoji in ["\u23F8", "\u25B6", "\u23F9"], timeout = length)
except asyncio.TimeoutError:
return await msg.clear_reactions()
async def process():
if reaction.emoji == "\u23F8":
await msg.remove_reaction(reaction.emoji, ctx.author)
ctx.voice_client.pause()
elif reaction.emoji == "\u25B6":
await msg.remove_reaction(reaction.emoji, ctx.author)
ctx.voice_client.resume()
elif reaction.emoji == "\u23F9":
await msg.remove_reaction(reaction.emoji, ctx.author)
ctx.voice_client.stop()
asyncio.create_task(process())
Here I have a snippet of code from a play command, its supposed to send a message after a song is requested, the message has reactions that pause, play or stop when reacted to by a user. Additionally the bot automatically deletes the reaction immediately after it is hit so that the reactions can be used more than once by the same user.
Currently the code works well, the only problem is the reactions only respond to the person that originally invoked the play command and not anyone else in the server. The cause of this is evident, its due to the user: user.id == ctx.author.id in the wait_for causing it to only wait for reactions from the author, and the await msg.remove_reaction(reaction.emoji, ctx.author) which will cause it to only remove reactions added by the author. When I try to remove the user: user.id == ctx.author.id the play command stops working entirely. The remove_reaction requires a member argument, when I try to replace ctx.author with user while the user: user.id == ctx.author.id is removed it does the same thing, and with the user: user.id == ctx.author.id it has no effect as user is defined as author. Any help is appreciated.
I have a problem with discord.py.
I want to do something like this:
msg = await ctx.author.send('message')
await msg.add_reaction('✅')
await msg.add_reaction('❎')
def check(reaction, user):
return user != bot.user and reaction.message.id == choice.id and reaction.emoji in ['✅', '❎']
r, u = await bot.wait_for('reaction_add', check=check)
result = r.emoji == '✅'
But it doesn't work and when I try this:
def check(reaction, user):
print(user.name)
return user != bot.user and reaction.message.id == choice.id and reaction.emoji in ['✅', '❎']
I have the name of the bot in the console, and when I try to click on a reaction nothing is printed, so I think bot.wait_for() works one time?
I hope you'll understand. Thanks for your time.
In your check, you had reaction.message.id == choice.id, and I'm not sure what choice is. This should work:
message = await ctx.author.send("message")
await message.add_reaction("✅")
await message.add_reaction("❎")
def check(reaction, user):
return user == ctx.author and reaction.message == message and reaction.emoji in ["✅", "❎"]
response = await client.wait_for("reaction_add", check=check)
result = response[0].emoji == "✅"
Like the bot won't read any other reactions of messages but only of a specific message.
will adding reaction.message == msgg into this code helps the trick?
(I don't know whether that function even exists and I did test that too but doesn't work for me)
reaction, user = await client.wait_for("reaction_add")
if user == members.user and str(reaction.emoji) == "✔️":
await members.user.send("your answer is ✔️")
else:
return
You would check if the reaction.message.content is the same as the message you desire.
reaction, user = await client.wait_for("reaction_add")
if reaction.message.content == "<desired message>":
if user == members.user and str(reaction.emoji) == "✔️":
await members.user.send("your answer is ✔️")
else:
return
You can use the on_reaction_add function for this, and then check if the message the user is reacting to is the desired one.
#client.event
async def on_reaction_add(reaction, user):
if user.bot:
return
my_message_id = 1234567
if reaction.message.id == my_message_id
await message.channel.send("Your answer is ✔️")
else:
return
This works fine with the check parameter of the wait_for Function:
reaction, user = await client.wait_for("reaction_add", check=lambda m: m.id == MESSAGE_ID)
if user == members.user and str(reaction.emoji) == "✔️":
await members.user.send("your answer is ✔️")
else:
return
(Idk if the lambda m and m.id works for reactions, you would have to test this out)
so right now I'm trying to create a type of application bot and right now the check I used for the bot doesn't allow the user to move onto the next question. There is no traceback so it's something with the check I defined.
#commands.command()
#commands.has_role("Realm OP")
async def block(self, ctx, user: discord.User):
DMchannel = await ctx.author.create_dm()
channel = ctx.message.channel
author = ctx.message.author
mentions = [role.mention for role in ctx.message.author.roles if role.mentionable]
channel2 = str(channel.name)
channel = channel2.split('-')
if len(channel2) == 2: # #real-emoji
realm, emoji = channel
else: # #realm-name-emoji
realm, emoji = channel[0], channel[-1]
realmName = realm.replace("-" , " ")
realmName1 = realmName.lower()
rolelist = []
print(realmName1)
a = solve(realmName1)
print(a)
realmName2 = str(a) + " OP"
print(realmName2)
check_role = discord.utils.get(ctx.guild.roles, name= realmName2)
if check_role not in ctx.author.roles:
return await ctx.send('You do not own this channel')
else:
await ctx.send("You own this channel!")
def check(m):
return m.channel == channel and m.author != self.bot.user
await DMchannel.send("Please fill out the questions in order to block the user!")
await DMchannel.send("User's Gamertag: (If you don't know, try using the >search command to see if they have any previous records!) ")
blocka1 = await self.bot.wait_for('message', check=check)
await DMchannel.send("Reason for block:")
blocka2 = await self.bot.wait_for('message', check=check)
Right now the bot doesn't do anything after the user responds to the first question and there is no traceback.
Any help or suggestions would help greatly!
Your check isn't returning anything. It's supposed to return either True or False. This means your wait_for will never end (as the check never returns True), so it will never ask the next question.
def check(m):
return m.channel == channel and m.author != self.bot.user
EDIT:
Your channel is the ctx.channel, while your bot waits for answers in DM. Assuming you answer your bot in DM as well, this means your check will never pass, as m.channel never equals channel.
def check(m):
return m.guild is None and m.author == ctx.author
This checks if a message was sent in DM (Guild is None), and if it was a DM by the original author.