How to detect user reactions on Discord bot messages

I’m working on a Discord bot for my server and need help with reaction handling. When users run a command, the bot should send a message with reaction options and wait for the user to click one.

Here’s what I have so far:

@bot.command(aliases=['confirmpay'])
async def payment(ctx):
    msg = await ctx.send('Do you want to proceed with payment?')
    check_emoji = '✅'
    await msg.add_reaction(check_emoji)
    cross_emoji = '❌'
    await msg.add_reaction(cross_emoji)
    await ctx.message.delete()
    bot.wait_for("reaction.users()=='✅'", timeout=10.0) #not sure about this part
    await ctx.send('confirmed')

The bot adds the reactions fine but I can’t figure out how to properly detect when someone clicks the checkmark. The wait_for line doesn’t seem right. Can someone show me the correct way to check for user reactions? I’d prefer if you could fix my existing code so I can see exactly what I’m doing wrong.

your wait_for syntax is totally wrong lol. try reaction, user = await bot.wait_for('reaction_add', check=lambda r, u: str(r.emoji) == '✅' and u == ctx.author, timeout=10.0) then handle the response. the check function makes sure its the right emoji and user who reacted

I faced a similar hurdle when developing my bot. The problem lies in your usage of the wait_for method. It requires an event type and a check function instead of a condition string. Your current syntax, bot.wait_for("reaction.users()=='✅'", timeout=10.0), won’t function. Instead, use reaction, user = await bot.wait_for('reaction_add', check=lambda reaction, user: str(reaction.emoji) == '✅' and user == ctx.author and reaction.message == msg, timeout=10.0). This will ensure that only the user who invoked the command can react to the correct message. Don’t forget to include error handling for the TimeoutError to manage scenarios where users might not respond in time.

The issue is with your wait_for method - you’re passing a string when it expects an event type and check function. Here’s your corrected code:

@bot.command(aliases=['confirmpay'])
async def payment(ctx):
    msg = await ctx.send('Do you want to proceed with payment?')
    check_emoji = '✅'
    await msg.add_reaction(check_emoji)
    cross_emoji = '❌'
    await msg.add_reaction(cross_emoji)
    await ctx.message.delete()
    
    def check(reaction, user):
        return user == ctx.author and str(reaction.emoji) in ['✅', '❌'] and reaction.message.id == msg.id
    
    try:
        reaction, user = await bot.wait_for('reaction_add', check=check, timeout=10.0)
        if str(reaction.emoji) == '✅':
            await ctx.send('confirmed')
        else:
            await ctx.send('cancelled')
    except asyncio.TimeoutError:
        await ctx.send('Payment confirmation timed out')

The key changes are using ‘reaction_add’ as the event type and creating a proper check function that validates the user, emoji, and message. Don’t forget to import asyncio for the timeout handling.