discord.js How do you make a reaction collector

Solution 1:

Instead of awaitReactions, you could also use createReactionCollector which is probably easier to use and its collector.on() listeners are more readable than awaitReactions's then() and catch() methods.

You won't need to use message.reactions.cache.get('👍').count to check the number of reactions, as the end event fires when you reached the maximum and you can send a message inside that.

Also, in your filter, you don't need to check if user.id === message.author.id as you will want to accept reactions from other users. However, you can check if !user.bot to make sure that you won't count the bot's reaction. You can also remove the time option if you don't want to limit the time your bot collects reactions.

Another error was that you called .awaitReactions() on the message itself not the sentMessage.

Check out the working code below:

// v12
client.on('message', async (message) => {
  if (message.author.bot || !message.content.startsWith(prefix)) return;

  const args = message.content.slice(prefix.length).split(/ +/);
  const command = args.shift().toLowerCase();
  const MAX_REACTIONS = 2;

  if (command === 'react') {
    try {
      // send a message and wait for it to be sent
      const sentMessage = await message.channel.send('React to this!');

      // react to the sent message
      await sentMessage.react('👍');

      // set up a filter to only collect reactions with the 👍 emoji
      // and don't count the bot's reaction
      const filter = (reaction, user) => reaction.emoji.name === '👍' && !user.bot;

      // set up the collecrtor with the MAX_REACTIONS
      const collector = sentMessage.createReactionCollector(filter, {
        max: MAX_REACTIONS,
      });

      collector.on('collect', (reaction) => {
        // in case you want to do something when someone reacts with 👍
        console.log(`Collected a new ${reaction.emoji.name} reaction`);
      });

      // fires when the time limit or the max is reached
      collector.on('end', (collected, reason) => {
        // reactions are no longer collected
        // if the 👍 emoji is clicked the MAX_REACTIONS times
        if (reason === 'limit')
          return message.channel.send(`We've just reached the maximum of ${MAX_REACTIONS} reactions.`);
      });
    } catch (error) {
      // "handle" errors
      console.log(error);
    }
  }
});

If you're using discord.js v13, there are a couple of changes:

  • you'll need to add the GUILD_MESSAGE_REACTIONS intents
  • the message event is now messageCreate
  • the collector's filter is inside the options object
// v13
const { Client, Intents } = require('discord.js');

const client = new Client({
  intents: [
    Intents.FLAGS.GUILDS,
    Intents.FLAGS.GUILD_MESSAGES,
    Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
  ],
});
const prefix = '!';

client.on('messageCreate', async (message) => {
  if (message.author.bot || !message.content.startsWith(prefix)) return;

  const args = message.content.slice(prefix.length).split(/ +/);
  const command = args.shift().toLowerCase();
  const MAX_REACTIONS = 2;

  if (command === 'react') {
    try {
      // send a message and wait for it to be sent
      const sentMessage = await message.channel.send('React to this!');

      // react to the sent message
      await sentMessage.react('👍');

      // set up a filter to only collect reactions with the 👍 emoji
      // and don't count the bot's reaction
      const filter = (reaction, user) => reaction.emoji.name === '👍' && !user.bot;

      // set up the collecrtor with the MAX_REACTIONS
      const collector = sentMessage.createReactionCollector({
        filter,
        max: MAX_REACTIONS,
      });

      collector.on('collect', (reaction) => {
        // in case you want to do something when someone reacts with 👍
        console.log(`Collected a new ${reaction.emoji.name} reaction`);
      });

      // fires when the time limit or the max is reached
      collector.on('end', (collected, reason) => {
        // reactions are no longer collected
        // if the 👍 emoji is clicked the MAX_REACTIONS times
        if (reason === 'limit')
          return message.channel.send(`We've just reached the maximum of ${MAX_REACTIONS} reactions.`);
      });
    } catch (error) {
      // "handle" errors
      console.log(error);
    }
  }
});

And the result:

enter image description here