Anchith Acharya
Anchith Acharya

Reputation: 442

Waiting for reaction in background in Discord Python

I have this bot that sends a particular message to the channel whenever a particular user's name is mentioned (using on_message()). And if I get tired of it and want it to stop, I just react to whatever it sent with a thumbs down within 2 minutes, and it stops.

Now, I also have another command that can take in that person's name as an argument, like .command @person_name. My problem is that, when I call the command with that specific person's name, the bot first posts the reaction message (which is fine), and then waits for two full minutes for the reaction, before it times out and moves on to the command body. How can I make the waitfor() function run in the background?

Here's a generalized gist of my code:

async def on_message(message):
    if "person_name" in message.content:
        await message.channel.send("sample reaction message")
        await fun()                                    #check for reaction

    ...                                                #other things
    await bot.process_commands(message)

async def fun(message):
    content = message.content
    channel = message.channel

    global VARIABLE                                   #this variable decides whether the bot should react to the person's name

    def check(reaction,user):
        return user.id == bot.owner_id and str(reaction.emoji) == '👎'

    try: reaction,user = await bot.wait_for('reaction_add',timeout = (60 * 2),check=check)
    except asyncio.TimeoutError: pass
    else:
        if str(reaction.emoji) == '👎':
            VARIABLE = False                           #disable the reaction message
            await channel.send(" Okay, I'll stop.")

Upvotes: 0

Views: 1558

Answers (2)

Kingslayer47
Kingslayer47

Reputation: 493

Since you are using the check function

 def check(reaction,user):
        return user.id == bot.owner_id and str(reaction.emoji) == '👎'

and confirming if this reaction '👎' was added you don't need this if statement later

if str(reaction.emoji) == '👎':

--------------------------------UPDATE------------------------------------

If you still need to verify an emoji

try:
    reaction_check = await bot.wait_for('reaction_add',check=check,timeout=15)
    emoji = f"{reaction_check}"
    emoji = emoji[emoji.find("(<Reaction emoji=")+len("(<Reaction emoji="):emoji.find("me")]
except:
    emoji = '✅'
if emoji.find('👎') != -1:
    print("code")

**

  • UPDATE 2

**

try:
        reaction_check = await bot.wait_for('reaction_add',check=check,timeout=15)
# since **`reaction_check`** yeilds a tuple
        emoji = reaction_check[0] #yeilds the emoji that was used in reaction
    except:
        emoji = '✅'
    if str(emoji) == '👎':
        print("code")

Upvotes: 1

0rdinal
0rdinal

Reputation: 661

Using the on_reaction_add event will allow you to do this. I'd advise against using global variables though. The event will trigger whenever someone reacts to a cached message. You will want to use on_raw_reaction_add if you want this to work even after a bot restart.

Add this function to your bot:

async def on_reaction_add(reaction, user):
    if bot.is_owner(user) and str(reaction.emoji) == "👎":
        VARIABLE = False

Upvotes: 1

Related Questions