Reputation: 73
I've been trying to solve this for a couple days with no solution. I want my discord bot to be able to buy digital items, and to buy them I have made a confirmation message and a system where you react to confirm with a 60 seconds timeout with a code I found online.
The problem with that code is it doesnt take into account the message the user reacted, so for example if the user sends two messages and confirms one, they both get executed, also, I can't add another icon like a cancel one. It is pretty important since this is an important function for the bot to work.
Also, making a on_reaction_add function is not viable since I would like my bot to run in various servers and channels at the same time with diferent users sending commands.
@client.event
async def on_message(message):
channel = message.channel
embedVar2 = discord.Embed(title="Item buying", description="<@"+ str(message.author.id) +"> Are you sure you want to buy " + str(conditions[1]) + " quantity of " + str(conditions[0]), color = 0x9A9B9D)
embedVar2.add_field(name="\u200b", value= "It will cost $" + str(price) + " you will have $" + str(endbal) + " remaining \nReact with ✅ to confirm", inline=False)
await confirm_message.add_reaction("✅") #add a reaction for the user to understand he has to react
def check(reaction, user): #checks if user has reacted
return user == message.author and str(reaction.emoji) == '✅'
try: #waits if it doest get timeout error
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check) #calls for function check defined prev
except asyncio.TimeoutError: #if timeout throws error:
embedVar5 = discord.Embed(title="Money transfer", description="<@"+ str(message.author.id) +"> Are you sure you want to buy " + str(conditions[1]) + " quantity of " + str(conditions[0]), color = 0xFF0A26)
embedVar5.add_field(name="\u200b", value= "It would have cost $" + str(price) + " you would have had $" + str(endbal) + " remaining \nTransaction canceled", inline=False)
await confirm_message.edit(embed = embedVar5) #message edit to canceled
return
else: #if user reacted before timeout
embedVar4 = discord.Embed(title="Money transfer", description="<@"+ str(message.author.id) +"> Are you sure you want to buy " + str(conditions[1]) + " quantity of " + str(conditions[0]), color = 0x77FF87)
embedVar4.add_field(name="\u200b", value= "It will cost $" + str(price) + " you now have $" + str(endbal) + " remaining \nTransaction confirmed", inline=False)
await confirm_message.edit(embed = embedVar4) #message edit to confirmed
Thanks in advance, Noel.
Upvotes: 0
Views: 132
Reputation: 2613
To make this message specific, simply add and reaction.message == message
in check
:
def check(reaction, user): #checks if user has reacted
return user == message.author and str(reaction.emoji) == '✅' and reaction.message == message
If you also want to have a cancel reaction, you should modify check
to also allow cancel reactions:
def check(reaction, user): #checks if user has reacted
return user == message.author and str(reaction.emoji) in ['✅','Your cancel reaction here'] and reaction.message == confirm_message
and then check with which reaction the user reacted and do stuff depending on which reaction was used:
try:
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check) #calls for function check defined prev
except asyncio.TimeoutError:
embedVar5 = discord.Embed(title="Money transfer", description="<@"+ str(message.author.id) +"> Are you sure you want to buy " + str(conditions[1]) + " quantity of " + str(conditions[0]), color = 0xFF0A26)
embedVar5.add_field(name="\u200b", value= "It would have cost $" + str(price) + " you would have had $" + str(endbal) + " remaining \nTransaction canceled", inline=False)
await confirm_message.edit(embed = embedVar5)
return
else:
if str(reaction.emoji) == '✅':
embedVar4 = discord.Embed(title="Money transfer", description="<@"+ str(message.author.id) +"> Are you sure you want to buy " + str(conditions[1]) + " quantity of " + str(conditions[0]), color = 0x77FF87)
embedVar4.add_field(name="\u200b", value= "It will cost $" + str(price) + " you now have $" + str(endbal) + " remaining \nTransaction confirmed", inline=False)
await confirm_message.edit(embed = embedVar4)
elif str(reaction.emoji) == 'Your cancel emoji here':
await confirm_message.edit(embed = embedVar5) #execute the same code you executed on TimeoutError
return
References:
Upvotes: 2