1
votes

I want the user to answer a "yes or no" question using reactions. Here is my code below.

var emojiArray = ['????', '????', '????', '✅', '❌'];

client.on('message', (negotiate) => {
    const listen = negotiate.content; 
    const userID = negotiate.author.id;
    var prefix = '!';
    var negotiating = false; 
    let mention = negotiate.mentions.user.first();
    if(listen.toUpperCase().startsWith(prefix + 'negotiate with '.toUpperCase()) && (mention)) {
        negotiate.channel.send(`<@${mention.id}>, do you want to negotiate with ` + `<@${userID}>`)
        .then(r => r.react(emojiArray[3], emojiArray[4]));
        negotiating = true;
    }
    if(negotiating == true && listen === 'y') {
        negotiate.channel.send('Please type in the amount and then the item you are negotiating.');
    } else return; 
})

As you can see, the code above allows the user to tag someone and negotiate with them (the negotiating part doesn't matter). When the user tags someone else, it asks them if they want to negotiate with the user that tagged them. If the user says yes, they negotiate.

I want to do this in a cleaner way using reactions in discord. Is there any way to just add a yes or no reaction emoji and the user will have to click yes or no in order to confirm?

2

2 Answers

1
votes

First of all, you kinda messed up while getting the user object of the mentioned user, so just so you know it's negotiate.mentions.users.first()!

While wanting to request user input through reactions, we'd usually want to use either one of the following:

  • awaitReactions()
  • createReactionCollector

Since I personally prefer awaitReactions(), here's a quick explanation on how to use it:

awaitReactions is a message object extension and creates a reaction collector over the message that we pick. In addition, this feature also comes with the option of adding a filter to it. Here's the filter I usually like to use:

const filter = (reaction, user) => {
   return emojiArray.includes(reaction.emoji.name) && user.id === mention.id;
   // The first thing we wanna do is make sure the reaction is one of our desired emojis!
   // The second thing we wanna do is make sure the user who reacted is the mentioned user.
};

From there on, we could very simply implement our filter in our awaitReactions() function as so:

 message.awaitReactions(filter, {
     max: 1, // Accepts only one reaction
     time: 30000, // Will not work after 30 seconds
     errors: ['time'] // Will display an error if using .catch()
 })
 .then(collected => { // the reaction object the user reacted with
     const reaction = collected.first();
     // Your code here! You can now use the 'reaction' variable in order to check certain if statements such as:
     if (reaction.emoji.name === '🔥') console.log(`${user.username} reacted with Fire emoji!`)

Finally, your code should look like this:

const filter = (reaction, user) => {
   return emojiArray.includes(reaction.emoji.name) && user.id === mention.id;
};
message.awaitReactions(filter, {
     max: 1,
     time: 30000, 
     errors: ['time'] 
 })

 .then(collected => {
     const reaction = collected.first();
     if (reaction.emoji.name === '🔥') console.log(`${user.username} reacted with Fire emoji!`)
0
votes

you should use a ReactionCollector:

var emojiArray = ['🔥', '👍', '👎', '✅', '❌'];
const yesEmoji = '✅';
const noEmoji = '❌';

client.on('message', (negotiate) => {
    const listen = negotiate.content; 
    const userID = negotiate.author.id;
    var prefix = '!';
    var negotiating = false; 
    let mention = negotiate.mentions.user.first();

    if(listen.toUpperCase().startsWith(prefix + 'negotiate with '.toUpperCase()) && (mention)) {
        negotiate.channel.send(`<@${mention.id}>, do you want to negotiate with ` + `<@${userID}>`)
        .then(async (m) => {
            await m.react(yesEmoji);
            await m.react(noEmoji);
            // we want to get an answer from the mentioned user
            const filter = (reaction, user) => user.id === mention.id;
            const collector = negotiate.createReactionCollector(filter);
            collector.on('collect', (reaction) => {
                 if (reaction.emoji.name === yesEmoji) {
                      negotiate.channel.send('The mentioned user is okay to negotiate with you!');
                      // add your negotiate code here
                 } else {
                      negotiate.channel.send('The mentioned user is not okay to negotiate with you...');
                 }
            });
        });
        negotiating = true;
    }

})

This allows you to listen for new reactions added to a message. Here is the documentation: https://discord.js.org/#/docs/main/stable/class/Message?scrollTo=createReactionCollector