首页 > 解决方案 > 添加反应时删除嵌入

问题描述

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()
        }
      })
    });
  }
}

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

标签: javascriptnode.jsdiscord.js

解决方案


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

将侦听器附加到客户端的messageReactionAdd事件是导致这种情况的原因;任何反应都会发出此事件,并且在一次清除后为每个反应执行您的代码。只要反应是并且用户不是客户端,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 s,而不是将侦听器附加到messageReactionAdd事件。前者用于此用途,可防止内存泄漏。此外,我更改了一些变量名称,以使代码更易于阅读和理解。还存在其他一些非常小的改进。


推荐阅读