In our last article, we explored how we can use Collectors to prompt a user for additional input. Reaction Collectors work in a similar way, but collect Reactions or Emojis to a particular message. This technique is used in a lot of bots where input might need to be gathered from multiple people, such as a voting system.
Creating a Reaction Collector
In this example, we’re going to add a basic reaction collector to respond to two possible reactions: 👍 and 👎. Depending on the reaction, our bot will respond in different ways. Add the following code to your message handler;
if (msg.content.startsWith('!react')) {
// Use a promise to wait for the question to reach Discord first
msg.channel.send('Which emoji do you prefer?').then((question) => {
// Have our bot guide the user by reacting with the correct reactions
question.react('👍');
question.react('👎');
// Set a filter to ONLY grab those reactions & discard the reactions from the bot
const filter = (reaction, user) => {
return ['👍', '👎'].includes(reaction.emoji.name) && !user.bot;
};
// Create the collector
const collector = question.createReactionCollector(filter, {
max: 1,
time: 15000
});
collector.on('end', (collected, reason) => {
if (reason === 'time') {
msg.reply('Ran out of time ☹...');
} else {
// Grab the first reaction in the array
let userReaction = collected.array()[0];
// Grab the name of the reaction (which is the emoji itself)
let emoji = userReaction._emoji.name;
// Handle accordingly
if (emoji === '👍') {
msg.reply('Glad your reaction is 👍!');
} else if (emoji === '👎') {
msg.reply('Sorry your reaction is 👎');
} else {
// This should be filtered out, but handle it just in case
msg.reply(`I dont understand ${emoji}...`);
}
}
});
});
}
There are a few things you’ll notice about this code. The first is that instead of replying directly to the user, we’re sending messages directly into the channel. Sending a message to the channel actually returns a Promise
so we can chain another function with the output of the promise, which contains info about the message we just sent.
Once the promise returns, we can take that message and react to it directly. Then we create a reaction collector with createReactionCollector
with a filter and options just like we did for the standard collector. We handle the end
event pretty much like we did with the standard collector as well. Here are the results;
In the next article, we’ll put everything we’ve learned so far into creating a command that allows users to create surveys!