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 nowmessageCreate
- the collector's
filter
is inside theoptions
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: