Skip to content
Advertisement

How to Make a Discord Bot Asynchronously Wait for Reactions on Multiple Messages?

tl;dr How can my bot asynchronously wait for reactions on multiple messages?


I’m adding a rock-paper-scissors (rps) command to my Discord bot. Users can invoke the command can be invoked by entering .rps along with an optional parameter, specifying a user to play with.

JavaScript

When invoked, the bot will direct-message (DM) the user who invoked it and the target user (from the parameter). The two users then react to their DM with either ✊, 🖐, or ✌️.

Now I’m trying to get this working asynchronously. Specifically, the bot will send DMs to both users (asynchronously) and wait for their reactions (asynchronously). A step-by-step scenario:

JavaScript

(See also: Note 1)

Since the goal is to listen to wait for reactions from multiple messages, I tried creating two separate threads/pools. Here were three attempts:

  • multiprocessing.pool.ThreadPool
  • multiprocessing.Pool
  • concurrent.futures.ProcessPoolExecutor

Unfortunately, all three didn’t work out. (Maybe I implemented something incorrectly?)

The following code shows the command function (rps), a helper function (rps_dm_helper), and the three (unsuccessful) attempts. The attempts all make use of different helper functions, but the underlying logic is the same. The first attempt has been uncommented for convenience.

JavaScript

Note

1 Contrast the asynchronous scenario to a non-asynchronous one:

JavaScript

This wasn’t too hard to implement:

JavaScript

But IMHO, the non-async makes for bad UX. :-)

Advertisement

Answer

You should be able to use asyncio.gather to schedule multiple coroutines to execute concurrently. Awaiting gather waits for all of them to finish and returns their results as a list.

JavaScript
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement