添加对嵌入有反应的用户

时间:2020-07-24 17:06:51

标签: node.js discord.js

尝试制作一个机器人,使用户单击反应时,不一致的ID进入一个嵌入字段,如果他们取消单击或单击另一个表情符号,则最终进入该字段。这将用于有投票权的机器人,一旦有一定数量的用户单击“是”或“否”,将决定是否接受用户或拒绝用户。有帮助吗?

exports.run = async (client, message, args) => {
  message.delete({ timeout: 100 });
  if (!args[0]) return message.reply('You need to supply the question');

  let embed = new Discord.MessageEmbed()
    .setTitle(args.join(' '))
    .setDescription('Poll created by ' + message.author.tag)
    .addField('Status', 'Voting is currently open.')
    .setColor('#ffd700')
    .attachFiles(new Discord.MessageAttachment('https://i.imgur.com/QUmbq9o.png', 'thumbnail.png'))
    .setThumbnail('attachment://thumbnail.png')
    .setFooter('Bot created by James (Rock)₇₇₇');

  message.channel.send(embed).then(async msg => {
    await msg.react('?');
    await msg.react('?');
    await msg.react('?');
    await msg.react('?️');

    const threshold = 6;

    async function stop(result) {
      collector.stop();

      const newEmbed = new Discord.MessageEmbed(msg.embeds[0]);

      newEmbed.title = newEmbed.title + ' [CLOSED]';
      newEmbed.fields[0] = { name: 'Status', value: 'Voting is now closed.\n' + result };
      newEmbed.setThumbnail('attachment://thumbnail.png');
      await msg.edit(newEmbed);

      msg.reactions.removeAll();
    }

    async function update() {
      const newEmbed = new Discord.MessageEmbed(embed);

      const userYes = (votes['?'].size === 0)? '-' : [...votes['?']];
      const userNo = (votes['?'].size === 0)? '-' : [...votes['?']];
      const userUnsure = (votes['?'].size === 0)? '-' : [...votes['?']];

      newEmbed.addFields(
        { name: `User Yes (${votes['?'].size}/${threshold})`, value: userYes, inline: true },
        { name: `User No (${votes['?'].size}/${threshold})`, value: userNo, inline: true },
        { name: 'User Unsure', value: userUnsure, inline: true }
      );

      await msg.edit(newEmbed);

      if (votes['?'].size >= threshold) {
        await stop('This answer is good enough to get accepted and an upvote.');
        // do something
      } else if (votes['?'].size >= threshold) {
        await stop('This answer is not good enough to get accepted and an upvote.');
        // do something
      }
    }

    const votes = {
      '?': new Set(),
      '?': new Set(),
      '?': new Set(),
      '?️': new Set()
    };

    update();

    const collector = msg.createReactionCollector((reaction, user) => !user.bot , { dispose: true });

    collector.on('collect', async (reaction, user) => {
      if (['?', '?', '?', '?️'].includes(reaction.emoji.name)) {
        const userReactions = msg.reactions.cache.filter(reaction => reaction.users.cache.has(user.id));

        for (const userReaction of userReactions.values()) {
          if (userReaction.emoji.name !== reaction.emoji.name || reaction.emoji.name === '?️') {
            userReaction.users.remove(user.id);
            votes[userReaction.emoji.name].delete(user);
          }
        }

        votes[reaction.emoji.name].add(user);
      } else {
        reaction.remove();
      }

      update();
    });

    collector.on('remove', (reaction, user) => {
      votes[reaction.emoji.name].delete(user);

      update();
    });
  });

};

module.exports.help = {
  name: "poll"
}

3 个答案:

答案 0 :(得分:0)

您可以从discord.js指南中阅读关于反应收集器的this页,它告诉您您需要了解的所有内容。您可以阅读this,以获取有关.createReactionCollector()方法的更多信息。

一旦创建了反应收集器,就有多种方法可以满足您的需求,但我相信最简单的方法如下:

message.channel.send('your_message_here')
  .then(async function(message) {
    await message.react('?');
    await message.react('?');
    await message.react('?‍');

    const filter = (reaction, user) => {
      return ['?', '?', '?‍'].includes(reaction.emoji.name) && user.id === ogauthor
    }
    
    const collector = message.createReactionCollector(filter)
    
    collector.on('collect', (reaction, user) => {
      async function collect() {
        if (!user.bot) {
          if (reaction.emoji.name === '?') {
            //code here
          }
          //repeat this for the rest of your reactions
          reaction.users.remove(user.id) //you can remove the reaction once they react to it and their name is added.
        }
      }
      collect()
    });
  })

一个问题是它将永远运行,因此您应该为其添加一个计时器。

答案 1 :(得分:0)

我对您的代码进行了少许修改,并添加了代码以跟踪投票,编辑嵌入内容并检查投票何时达到阈值。

演示

Discord embed demonstration

代码

message.delete({ timeout: 100 });
if (!args[0]) return message.reply('You need to supply the question');

let embed = new Discord.MessageEmbed()
  .setTitle(args.join(' '))
  .setDescription('Poll created by ' + message.author.tag)
  .addField('Status', 'Voting is currently open.')
  .setColor('#ffd700')
  .attachFiles(new Discord.MessageAttachment('https://i.imgur.com/QUmbq9o.png', 'thumbnail.png'))
  .setThumbnail('attachment://thumbnail.png')
  .setFooter('Bot created by James (Rock)₇₇₇');

message.channel.send(embed).then(async msg => {
  await msg.react('?');
  await msg.react('?');
  await msg.react('?');
  await msg.react('?️');

  const threshold = 1;

  async function stop(result) {
    collector.stop();

    const newEmbed = new Discord.MessageEmbed(msg.embeds[0]);

    newEmbed.title = newEmbed.title + ' [CLOSED]';
    newEmbed.fields[0] = { name: 'Status', value: 'Voting is now closed.\n' + result };
    newEmbed.setThumbnail('attachment://thumbnail.png');
    await msg.edit(newEmbed);

    msg.reactions.removeAll();
  }

  async function update() {
    const newEmbed = new Discord.MessageEmbed(embed);

    const userYes = (votes['?'].size === 0)? '-' : [...votes['?']];
    const userNo = (votes['?'].size === 0)? '-' : [...votes['?']];
    const userUnsure = (votes['?'].size === 0)? '-' : [...votes['?']];

    newEmbed.addFields(
      { name: `User Yes (${votes['?'].size}/${threshold})`, value: userYes, inline: true },
      { name: `User No (${votes['?'].size}/${threshold})`, value: userNo, inline: true },
      { name: 'User Unsure', value: userUnsure, inline: true }
    );

    await msg.edit(newEmbed);

    if (votes['?'].size >= threshold) {
      await stop('This answer is good enough to get accepted and an upvote.');
      // do something
    } else if (votes['?'].size >= threshold) {
      await stop('This answer is not good enough to get accepted and an upvote.');
      // do something
    }
  }

  const votes = {
    '?': new Set(),
    '?': new Set(),
    '?': new Set(),
    '?️': new Set()
  };

  update();

  const collector = msg.createReactionCollector((reaction, user) => !user.bot , { dispose: true });

  collector.on('collect', async (reaction, user) => {
    if (['?', '?', '?', '?️'].includes(reaction.emoji.name)) {
      const userReactions = msg.reactions.cache.filter(reaction => reaction.users.cache.has(user.id));

      for (const userReaction of userReactions.values()) {
        if (userReaction.emoji.name !== reaction.emoji.name || reaction.emoji.name === '?️') {
          userReaction.users.remove(user.id);
          votes[userReaction.emoji.name].delete(user);
        }
      }

      votes[reaction.emoji.name].add(user);
    } else {
      reaction.remove();
    }

    update();
  });

  collector.on('remove', (reaction, user) => {
    votes[reaction.emoji.name].delete(user);

    update();
  });
});

答案 2 :(得分:0)

在这种情况下,您可以使用Reaction Collectors听取反应并根据反应列出它们。

我已经编写了以下代码,它可以按预期工作:

enter image description here

message.delete({ timeout: 100 });
if (!args[0]) return message.reply('You need to supply the question');

let embed = new Discord.MessageEmbed()
   .setTitle(args.join(' '))
   .setDescription('Poll created by ' + message.author.tag)
   .setColor('#ffd700')
   .setThumbnail("https://i.imgur.com/QUmbq9o.png")
   .addFields({name: "User Yes", value: 'None'}, {name: "User No", value: 'None'}, {name: "User Hum", value: 'None'})
   .setFooter("Bot created by James (Rock)₇₇₇");


message.channel.send(embed).then(async msg => {
    await msg.react('?');
    await msg.react('?');
    await msg.react('?');
    const filter = (reaction, user) => {
        return ["?", "?", "?"].includes(reaction.emoji.name);
    };

    const collector = await msg.createReactionCollector(filter);

    collector.on('collect', (reaction, user) => {

      const reactionsList = ["?", "?", "?"];
      const fieldTitle = ["User Yes", "User No", "User Hum"];

      var reactions = reaction.message.reactions.cache.array();

      for(var reactionID in reactions) {
        for (var i = 0; i < reactionsList.length; i++) {
          if(reactionsList[i] === reaction.emoji.name){
            let fieldDescription = user.id + "\n";
             var users = reactions[reactionID].users.cache.array();
             for(var userID in users){
               if(users[userID].id === client.user.id || users[userID].id === user.id) continue;
               fieldDescription += users[userID].id + "\n";
             }
             embed.spliceFields(i, 1, {name: fieldTitle[i], value: fieldDescription})
          }
        }
      }

      msg.edit(embed);

    });
})