温馨提示:本文翻译自stackoverflow.com,查看原文请点击:javascript - Delete an embed when a reaction is added
discord.js javascript node.js

javascript - 添加反应时删除嵌入

发布于 2020-03-27 10:49:43
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()
        }
      })
    });
  }
}

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

查看更多

查看更多

提问者
Asgarrrr
被浏览
192
slothiful 2019-07-04 11:45

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

Attaching a listener to the client's messageReactionAdd event is what's causing this; any reaction emits this event, and your code is executed for each one after a single purge. As long as the reaction is ???? and the user isn't the client, Message.delete() will be called on 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)

After adding that reaction that deletes the wrong message, it no longer exists. When you try to delete it again, this error will be thrown.

Furthermore, your code isn't waiting for the messages to be purged before sending the reply. Because of this, the message can be sent before and subsequently deleted by the TextChannel.bulkDelete() call. Then, when you try to react to the same message via Message.react(), your error is thrown because it no longer exists.

为了确保代码以正确的顺序执行,请确保您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事件。前者用于此用途,可以防止内存泄漏。另外,我还更改了一些变量名称,以使代码更易于阅读和理解。还存在其他一些非常小的改进。