Search code examples
async-awaitdiscord.jsmessage

How to make a bot send a message to a specific channel after receiving a reaction from a certain message


So I'm trying to develop a bot for a very small project (I'm not a programmer or anything, just need to do this one thing). All I need it to do is to collect reactions from a specific message I sent and send another message to a channel as soon as it detects a reaction. The message would contain the reactor's tag and some text. I would need it to be activelly collecting reactions all the time, without any limit. I tried looking through the documentation but I don't really know how to implement the .awaitmessageReactions or whatever it's called. Can you help me out?


Solution

  • You can use method createReactionCollector for this. But when bot go down, this collector will stop.

    const Discord = require('discord.js');
    const bot = new Discord.Client();
    let targetChannelId = '1232132132131231';
    bot.on('ready', () => {
        console.log(`${bot.user.tag} is ready on ${bot.guilds.cache.size} servers!`);
    });
    
    bot.on('message', (message) => {
        if (message.content === 'test') {
            message.channel.send(`i\`m await of reactions on this message`).then((msg) => {
                const filter = (reaction, user) => !user.bot;
                const collector = msg.createReactionCollector(filter);
                collector.on('collect', (reaction, user) => {
                    let channel = message.guild.channels.cache.get(targetChannelId);
                    if (channel) {
                        let embed = new Discord.MessageEmbed();
                        embed.setAuthor(
                            user.tag,
                            user.displayAvatarURL({
                                dynamic: true,
                                format: 'png',
                            }),
                        );
                    }
                    embed.setDescription(`${user} (${user.tag}) has react a: ${reaction.emoji}`);
                    channel.send(embed);
                });
                collector.on('end', (reaction, reactionCollector) => {
                    msg.reactions.removeAll();
                });
            });
        }
    });
    
    bot.login('token');
    

    Or you can use emitter messageReactionAdd and handle reaction on specific message.

    const Discord = require('discord.js')
    const token = require('./token.json').token
    const bot = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
    
    bot.once('ready', () => {
        console.log(`${bot.user.tag} is ready on ${bot.guilds.cache.size} guilds`)
    })
    
    let targetChannelId = '668497133011337224'
    
    bot.on('messageReactionAdd', async (reaction, user) => {
        if (reaction.partial) {
            // If the message this reaction belongs to was removed the fetching might result in an API error, which we need to handle
            try {
                await reaction.fetch();
            } catch (error) {
                console.log('Something went wrong when fetching the message: ', error);
                // Return as `reaction.message.author` may be undefined/null
                return;
            }
        }
    
        if (reaction.message.id === '730000158745559122') {
            let channel = reaction.message.guild.channels.cache.get(targetChannelId);
            console.log(reaction.emoji)
            if (channel) {
                let embed = new Discord.MessageEmbed();
                embed.setAuthor(
                    user.tag,
                    user.displayAvatarURL({
                        dynamic: true,
                        format: 'png',
                    }),
                );
                embed.setDescription(`${user} has react a: ${reaction.emoji}`);
                channel.send(embed);
            }
        }
    });
    
    bot.login(token)