Search code examples
pythonpython-3.xdiscord.pycommand

Allowing a discord bot to wait for reactions?


I have been learning how to create a discord bot using Discord.py and I wanted to improve my commands within my bot. One of the ways I wanted to do this was by adding a 'wait' time. This would do the following:

  1. Wait for the user to enter data to the bot through reactions.
  2. Process a response if a reaction is given and a different response if no reactions are given by the user.

My current code simply processes commands and I do not know how to create that 'wait' time. Here is the code below:

```python
@commands.command()
async def hello(a: str):
     await ctx.send(f"hello {a}")
```

Solution

  • wait_for

    The way to detect reactions is to use the wait_for function. This takes the specified action and then waits until the time has elapsed. There is also a check that you can perform to see if the conditions have been satisfied. In the following example I have used add_reaction. Here is the page in the discord.py documentation.

    Below I have attached some code that add's reactions from a list to a message and waits for a reaction. Then the bot adds the user's account name and the index of the reaction into a text file with a separator. For your intended response just change the code in the else statement.

    Code

    import discord
    from discord.ext import commands #<---- Importing Libraries
    import asyncio
    
    
    intents = discord.Intents.default()
    intents.members = True            #<----- All the intents
    intents.reactions = True
    
    bot = commands.Bot(command_prefix='?')
    
    @bot.command(pass_context=True) 
    async def name(ctx):
        file_ = open("Storage/names.txt", "a")
        channel = ctx.channel
        react = ["🇦","🇧","🇨"]    #<----- The reactions being added
        
        mes = await channel.send('Send me that reaction, mate')   #<---- The message with the reactions
        for tmp in react:
            await mes.add_reaction(tmp)   #<---- Adding all of the reactions
    
        def check(reaction, user):
            return user == ctx.author and str(reaction.emoji) in react  #<---- The check performed
    
        try:
            reaction, user = await bot.wait_for('reaction_add', timeout=10.0, check=check) #<--- Waiting for the reaction
        except asyncio.TimeoutError:  #<---- If the user doesn't respond
            await channel.send('👎')
        else:
            i = react.index(str(reaction))
            entry = str(i) + "|" + str(ctx.author) + "\n"   #<------- The response if there is a reaction
            file_.write(entry)
            file_.close()
            await ctx.send("Done!")
    
    bot.run("TOKEN")
    

    Testing

    If the user doesn't respond with a reaction: The Command when the user does not respond with a reaction.

    If the user responds with a reaction:

    The Command when the user does respond with a reaction.