A Guide to Discord Bots

Awaiting Messages & Reactions

I want the user to confirm that he wants to execute a part of code.
Thankfully, we have channel.awaitMessages() and message.awaitReactions().
This is just an example but can be used in many other ways!
Be creative ^.^

Awaiting Messages

client.on('message', message => {
    // Command handler, seen previously
    switch (command) {
            case 'shutdown': {
                    message.reply('The bot will now shut down.\n'
                            + 'Confirm with `yes` or deny with `no`.');

                    // First argument is a filter function - which is made of conditions
                    // m is a 'Message' object
                    message.channel.awaitMessages(m => m.author.id == message.author.id,
                            {max: 1, time: 30000}).then(collected => {
                                    // only accept messages by the user who sent the command
                                    // accept only 1 message, and return the promise after 30000ms = 30s

                                    // first (and, in this case, only) message of the collection
                                    if (collected.first().content.toLowerCase() == 'yes') {
                                            message.reply('Shutting down...');
                                            client.destroy();
                                    }

                                    else
                                            message.reply('Operation canceled.');      
                            }).catch(() => {
                                    message.reply('No answer after 30 seconds, operation canceled.');
                            });
                    break;
            }  
    }
});

Awaiting Reactions

client.on('message', message => {
    // Command handler, seen previously
    switch (command) {
            case 'shutdown': {
                    message.reply('The bot will now shut down.\n'
                            + 'Confirm with a thumb up or deny with a thumb down.');

                    // Reacts so the user only have to click the emojis
                    message.react('👍').then(r => {
                            message.react('👎');
                    });

                    // First argument is a filter function
                    message.awaitReactions((reaction, user) => user.id == message.author.id && (reaction.emoji.name == '👍' || reaction.emoji.name == '👎'),
                            { max: 1, time: 30000 }).then(collected => {
                                    if (collected.first().emoji.name == '👍') {
                                            message.reply('Shutting down...');
                                            client.destroy();
                                    }
                                    else
                                            message.reply('Operation canceled.');
                            }).catch(() => {
                                    message.reply('No reaction after 30 seconds, operation canceled');
                            });

                    break;
            }  
    }
});

The Reaction object.
To get emoji's name, you can use the emoji with \ before it, on any Discord text channel.
\:thumbsup: \:thumbsdown: will output 👍 👎.
Note: this doesn't always work, so you could use console.log(collected.first().emoji.name) to get the name instead.

Why not use events instead?

For this example, it could be harder to use client.on('message'), and you should know how to use it by now. BUT we could use client.on('messageReactionAdd') for other cases.
Let's take another example: we have a unique message that users can react to, to get (or remove) a role.

// We'll call it 'reaction' for short, but it is actually a 'MessageReaction' object
client.on('messageReactionAdd', (reaction, user) => {
        let message = reaction.message, emoji = reaction.emoji;

        if (emoji.name == '✅') {
                // We don't have the member, but only the user...
                // Thanks to the previous part, we know how to fetch it
                message.guild.fetchMember(user.id).then(member => {
                        member.addRole('role_id');
                });
        }

        else if (emoji.name == '❎') {
                message.guild.fetchMember(user.id).then(member => {
                        member.removeRole('role_id');
                });
        }

        // Remove the user's reaction
        reaction.remove(user);
});

The messageReactionAdd event, the MessageReaction object.

Done!... Restart the bot, and you can now cl- oh. It stopped working.
Discord.js caches messages when they are created only.
If it already exists, and it's not in cache, we have to fetch it using channel.fetchMessage() (or fetchMessages() if we're working with multiple messages).

client.on('ready', () => {
        client.guilds.get('guild_id').channels.get('channel_id').fetchMessage('message_id');
        /* We could use .then() here but we don't need the returning promise in this case
           This will just cache the specified message, to make sure
           that 'messageReactionAdd' will always get called */
});

// Same code as above
client.on('messageReactionAdd', (reaction, user) => {
        let message = reaction.message, emoji = reaction.emoji;

        if (emoji.name == '✅') {
                // We don't have the member, but only the user...
                // Thanks to the previous part, we know how to fetch it
                message.guild.fetchMember(user.id).then(member => {
                        member.addRole('role_id');
                });
        }

        else if (emoji.name == '❎') {
                message.guild.fetchMember(user.id).then(member => {
                        member.removeRole('role_id');
                });
        }

        // Remove the user's reaction
        reaction.remove(user);
});

results matching ""

    No results matching ""