添加反应时删除嵌入

时间:2019-07-03 13:59:49

标签: javascript node.js discord.js

module.exports.run = (client, message, args) => {

  if (message.member.roles.some(role => role.name === process.env.MODO)) {

    const user = message.mentions.users.first();
    // Parse Amount
    const amount = !!parseInt(message.content.split(' ')[1]) ? parseInt(message.content.split(' ')[1]) : parseInt(message.content.split(' ')[2])
    if (!amount) return message.reply('Vous devez spécifier un montant à supprimer !');
    if (!amount && !user) return message.reply('Vous devez spécifier un utilisateur et le montant, ou juste une quantité de messages à purger !');
    if (amount > 100) return message.reply('Malheureusement, discord ne permet pas la Suppression de plus de 100 messages en une fois ...');
    // Fetch 100 messages (will be filtered and lowered up to max amount requested)
    message.channel.fetchMessages({
      limit: amount,
    }).then((messages) => {
      if (user) {
        const filterBy = user ? user.id : Client.user.id;
        messages = messages.filter(m => m.author.id === filterBy).array().slice(0, amount);
      }
      message.channel.bulkDelete(messages).catch(error => console.log(error.stack));
    });

    var purge = new Discord.RichEmbed()

      .setAuthor(`Suppression de ${amount} Messages dans le salon ${message.channel.name}`)
      .setFooter("Requête par " + message.member.user.tag, message.member.user.avatarURL)
      .setTimestamp()
      .setColor(0xF03434)

    message.channel.send(purge).then(message => {
      message.react('?')
      client.on('messageReactionAdd', (reaction, user) => {
        // on vérifie que ce soit bien la bonne réaction et on ne compte pas celui du bot
        if (reaction.emoji.name === '?' && user.id !== client.user.id) {
          message.delete()
        }
      })
    });
  }
}

我想要的是在“最终”嵌入的级别上,当它告诉我清除已完成时,会有一个反应“?”,当我们单击它会删除消息。
问题是当前代码删除了相同类型的所有嵌入。

1 个答案:

答案 0 :(得分:1)

  

如果我单击第一个嵌入的反应,它也会删除第二个嵌入,并且不会删除其他任何内容...

将侦听器附加到客户端的messageReactionAdd事件是导致此问题的原因; any 反应将引发此事件,并且在一次清除后针对每个代码执行您的代码。只要响应为?并且用户不是客户端,Message.delete()就会在message上被调用。

  
(node: 10752) UnhandledPromiseRejectionWarning: DiscordAPIError: Unknown Message
    at item.request.gen.end (/Users/jeremy/Desktop/BERRYBOT/node_modules/discord.js/src/client/rest/RequestHandlers/Sequential.js:85:15)
    at then (/Users/jeremy/Desktop/BERRYBOT/node_modules/snekfetch/src/index.js:215:21)
    at process._tickCallback (internal / process / next_tick.js: 68: 7)
(node: 10752) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated from the inside of the outside world, but it was not handled by .catch (). (rejection id: 14)

添加了删除错误消息的响应后,该响应不再存在。当您尝试再次删除它时,将引发此错误。

此外,您的代码在发送答复之前不等待清除消息。因此,可以在之前发送消息,然后通过TextChannel.bulkDelete()调用将其删除。然后,当您尝试通过Message.react()对同一条消息做出反应时,会抛出错误,因为它不再存在。

要确保代码以正确的顺序执行,请确保您正确使用了then()链,或者利用了async/await的美感。


仍然使用then()方法重新组织代码:

message.channel.fetchMessages({ limit: amount })
  .then(fetchedMessages => {
    const filterBy = user ? user.id : Client.user.id;
    const toPurge = messages.filter(m => m.author.id === filterBy).array().slice(0, amount);

    message.channel.bulkDelete(toPurge)
      .then(deletedMessages => {
        var embed = new Discord.RichEmbed()
          .setAuthor(`Suppression de ${deletedMessages.size} Messages dans le salon ${message.channel.name}`)
          .setFooter(`Requête par ${message.author.tag}`, message.author.avatarURL)
          .setTimestamp()
          .setColor(0xF03434)

        message.channel.send(embed)
          .then(reply => {
            reply.react('?');

            const filter = (reaction, user) => reaction.emoji.name === '?' && user.id !== client.user.id;
            reply.createReactionCollector(filter, { maxMatches: 1 })
              .on('collect', () => reply.delete());
          });
      });
  })
  .catch(console.error);

或者,使用await

// You must define your callback function as async to use the 'await' keyword! It should look like...
// async (client, message, args) => { ... }

try {
  const fetchedMessages = await message.channel.fetchMessages({ limit: amount });

  const filterBy = user ? user.id : Client.user.id;
  const toPurge = messages.filter(m => m.author.id === filterBy).array().slice(0, amount);

  const deletedMessages = await message.channel.bulkDelete(toPurge);

  var embed = new Discord.RichEmbed()
    .setAuthor(`Suppression de ${deletedMessages.size} Messages dans le salon ${message.channel.name}`)
    .setFooter(`Requête par ${message.author.tag}`, message.author.avatarURL)
    .setTimestamp()
    .setColor(0xF03434)

  const reply = await message.channel.send(embed)
  await reply.react('?');

  const filter = (reaction, user) => reaction.emoji.name === '?' && user.id !== client.user.id;
  reply.createReactionCollector(filter, { maxMatches: 1 })
    .on('collect', async () => await reply.delete());
} catch(err) {
  console.error(err);
}

您会注意到此代码使用ReactionCollector,而不是将侦听器附加到messageReactionAdd事件。前者用于此用途,可以防止内存泄漏。另外,我还更改了一些变量名称,以使代码更易于阅读和理解。还存在其他一些非常小的改进。