Using Discord.js, my dice-roller bot registers duplicate reactions on multiple messages. How can I limit reaction handling to only one message?
bot.on('messageCreate', msg => {
if (!msg.content.startsWith('!')) return;
const parts = msg.content.slice(1).split(' ');
if (parts[0].toLowerCase() === 'dice') {
DiceModule.roll(msg, parts);
}
});
module.exports = {
roll: async (msg, args) => {
const targetChannel = 'UNIQUE_CHANNEL_ID';
let result = rollDice(args[1]);
const sent = await msg.channel.send(result);
sent.react('♻️');
bot.on('reactionAdd', async (reaction, user) => {
if (user.bot) return;
if (reaction.message.channel.id !== targetChannel) return;
if (reaction.emoji.name === '♻️') {
let newResult = rollDice(args[1]);
await msg.channel.send(newResult);
reaction.users.remove(user);
}
});
}
};
function rollDice(diceStr) {
// Simulate dice rolling logic
return `Rolled: ${Math.floor(Math.random() * 6) + 1}`;
}
Based on my experience, the issue stems from attaching the reaction listener to the entire client rather than to a specific message context. This means that every reaction across different messages gets processed, and that isn’t ideal for a dice-roller bot where you only intend to handle one reaction per dice roll. I resolved it by using a ReactionCollector on the sent message so that only reactions added to that specific message trigger an action. This also simplifies cleanup, as the collector can be disposed of after a reaction is received, ensuring no duplicate responses occur on subsequent messages.
I found that narrowing down the reaction handling to only process events for the intended message can simplify things a lot. Instead of attaching the reaction listener at a global level, you can check that the message ID of the reaction matches the ID of the dice roll message. This eliminates unwanted handlers triggering for other messages. In my project, this involved adding a simple condition in the event callback and subsequently removing or disabling the listener once the reaction was processed. This method not only targets the correct message but also helps prevent side effects from lingering event listeners.