如何根据 Discord.js 中的反应编辑消息(创建列表和切换页面) [英] How to edit message according to reaction in Discord.js (create a list and switch page)

查看:18
本文介绍了如何根据 Discord.js 中的反应编辑消息(创建列表和切换页面)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我的 Discord 机器人发送一条消息,然后在人们做出反应时对其进行编辑(例如创建一个列表,然后单击向右或向左箭头将编辑消息并显示列表的下一个/上一个部分).

I want my Discord bot to sent a message and then edit it when people react (for example creating a list, and clicking on the right or left arrow will edit the messages and show the next/previous part of the list).

示例:
反应前:

Example:
before reaction:

反应后:

推荐答案

如何处理消息反应?

对消息反应有 3 种反应方式:

How to handle a message reaction?

There is 3 ways to react to a message reaction:

  1. 使用函数 awaitReactions(基于承诺)
  2. 使用 ReactionCollector
  3. 使用 messageReactionAdd 事件

区别:

messageReactionAdd 是一个链接到 Client 的事件:

The Difference:

messageReactionAdd is an event linked to the Client:

每当响应添加到缓存消息时发出.

Emitted whenever a reaction is added to a cached message.

ReactionCollectorawaitReactions 链接到特定消息时,如果将反应添加到另一条消息,则不会执行任何操作.

while a ReactionCollector and awaitReactions are linked to a specific message, and won't do anything if a reaction is added to another message.

messageReactionAdd 如果将反应添加到缓存消息(旧消息),则不会触发.有一个指南用于收听旧消息 在 Discord.js 指南中,给出了这个警告

messageReactionAdd will not be fired if a reaction is added to a cached message (old message). There is a guide for listening on old messages in the Discord.js guide, where this warning is given

本节描述了如何使用一些未记录的 API 将不受支持的功能添加到 discord.js,因此您应该极其谨慎地遵循此处的任何内容.此处的任何内容都可能随时更改,恕不另行通知,并且可能会破坏您机器人中的其他功能.

This section describes how to use some undocumented APIs to add unsupported functionality into discord.js, and as such you should follow anything here with extreme caution. Anything here is subject to change at any time without notice, and may break other functionality in your bot.

awaitReactions 是基于 Promise 的,它只会在 Promise 解决后返回所有添加的反应的集合(在添加 X 个反应后,在 Y 秒后等).没有特定的支持来处理每个添加的反应.您可以将您的函数放在 filter 函数中以添加每个反应,但这不是有意的小技巧.然而,ReactionCollector 有一个 collect 事件.

awaitReactions is promise based, and it will only return the collection of all added reactions when the promise is solved (after X reactions have been added, after Y seconds, etc). There isn't a specific support to handle every added reaction. You can put your function in the filter function to get every reactions added, but it's a little hack which is not intended. The ReactionCollector, however, has a collect event.

您想要编辑您的机器人发送的消息(因为您无法编辑其他用户的消息).所以 ReactionCollectorawaitReactions.

You want to edit a message sent by your bot (because you can't edit other's users message). So ReactionCollector or awaitReactions.

如果您想在满足特定条件后编辑消息(X 人已投票,已添加 Y 反应,15 分钟后,...)(例如:投票,您将允许用户投票在 15 分钟内),您可以同时使用 awaitReactionsReactionCollector.

If you want to edit a message after a certain condition has been met (X persons has voted, Y reactions has been added, after 15 mins, ...) (e.g: a vote, where you will allow users to vote during 15 mins), you can both use awaitReactions and ReactionCollector.

但是,如果您想根据特定反应(如示例中对箭头表情符号做出反应)编辑消息,则必须使用 ReactionCollector.

But if you want to edit the message based on a specific reaction (as in the example, when reacting to an arrow emoji) you'll have to use a ReactionCollector.

如果消息没有被缓存,你可以使用 messageReactionAdd 但它会更复杂,因为你基本上必须重写一个表情符号收集器,但对于每个表情符号.

If the message is not cached, you can use messageReactionAdd but it will be more complicated because you will basically have to rewrite an emoji collector but for every emojis.

注意:如果机器人重新启动,ReactionCollectorawaitReactions 将被删除,而 messageReactionAdd 将照常工作(但你会丢失你声明的变量,所以如果你存储了你想收听的消息,它们也会消失).

Note: the ReactionCollector and awaitReactions will be deleted if the bot restart, while messageReactionAdd will work as usual (but you'll lost the variable you have declared, so if you has stored the messages you want to listen, they will also disappear).

你需要不同的东西:

  • 将触发功能的表情符号列表(您可以选择对每个表情符号做出反应)
  • 停止收听消息反应的条件(如果您想使用 messageReactionAdd
  • 收听每条消息,则不适用
  • 接收消息并对其进行编辑的函数
  • 一个返回布尔值的过滤函数:true我想对这个表情符号做出反应,false我不想做出反应.此功能将基于表情符号列表,但也可以过滤用户反应或您需要的任何其他条件
  • 编辑消息的逻辑.例如:对于一个列表,它将基于结果的数量、当前索引和添加的反应
  • The list of emojis which will trigger a function (you can choose to react to every emojis)
  • The condition to stop listening to a message reactions (doesn't apply if you want to listen to every messages with messageReactionAdd
  • A function which take a message and edit it
  • A filter function which will return a boolean: true I want to react to this emoji, false I don't want to react. This function will be based on the list of emojis but can also filter the user reacting, or any others conditions you need
  • A logic to edit your message. e.g: for a list, it will be based on the number of result, the current index and the reaction added
const emojiNext = '➡'; // unicode emoji are identified by the emoji itself
const emojiPrevious = '⬅';
const reactionArrow = [emojiPrevious, emojiNext];

停止条件

const time = 60000; // time limit: 1 min

编辑功能

这里的功能很简单,消息是预先生成的(时间戳和页脚除外).

Edit function

Here the function is really simple, the message are pre-generated (except the timestamp and the footer).

const first = () => new Discord.MessageEmbed()
      .setAuthor('TOTO', "https://i.imgur.com/ezC66kZ.png")
      .setColor('#AAA')
      .setTitle('First')
      .setDescription('First');

const second = () => new Discord.MessageEmbed()
      .setAuthor('TOTO', "https://i.imgur.com/ezC66kZ.png")
      .setColor('#548')
      .setTitle('Second')
      .setDescription('Second');

const third = () => new Discord.MessageEmbed()
      .setAuthor('TOTO', "https://i.imgur.com/ezC66kZ.png")
      .setColor('#35D')
      .setTitle('Third')
      .setDescription('Third');

const list = [first, second, third];

function getList(i) {
return list[i]().setTimestamp().setFooter(`Page ${i+1}`); // i+1 because we start at 0
}

过滤功能

function filter(reaction, user){
  return (!user.bot) && (reactionArrow.includes(reaction.emoji.name)); // check if the emoji is inside the list of emojis, and if the user is not a bot
}

逻辑

请注意,我在这里使用 list.length 来避免进入 list[list.length] 及其他范围.如果您没有硬编码列表,则应在参数中传递限制.
如果索引无效,您还可以使 getList 返回 undefined,而不是将索引用于布尔条件,而是将返回的值与 undefined 进行比较.

The logic

note that I use list.length here to avoid going in list[list.length] and beyond. If you don't have list hardcoded, you should pass a limit in argument.
You can also make getList return undefined if the index is invalid and instead of using the index for the boolean condition, compare the returned value to undefined.

function onCollect(emoji, message, i, getList) {
  if ((emoji.name === emojiPrevious) && (i > 0)) {
    message.edit(getList(--i));
  } else if ((emoji.name === emojiNext) && (i < list.length-1)) {
    message.edit(getList(++i));
  }
  return i;
}

这是另一个带有另一个 getList 函数的逻辑,例如,它只返回 list[i],而不是像上面那样设置时间戳,因为尝试在 undefined 上执行 .setTimestamp 会引发错误.

This is another logic with another getList function which just return list[i] for example, and not setting a timestamp as the one above does, since trying to do .setTimestamp on undefined will raise an error.

  if (emoji.name === emojiPrevious) {
    const embed = getList(i-1);
    if (embed !== undefined) {
      message.edit(embed);
      i--;
    }
  } else if (emoji.name === emojiNext) {
    const embed = getList(i+1);
    if (embed !== undefined) {
      message.edit(embed);
      i++;
    }
  }
  return i;

构建构造函数

例子同题,用箭头功能编辑消息.

Build the constructor

The example is the same as asked in the quesion, editing a message with the arrow function.

我们将使用收集器:

function createCollectorMessage(message, getList) {
  let i = 0;
  const collector = message.createReactionCollector(filter, { time });
  collector.on('collect', r => {
    i = onCollect(r.emoji, message, i, getList);
  });
  collector.on('end', collected => message.clearReactions());
}

它需要我们想听的信息.你也可以给它一个内容列表//消息//一个数据库//任何必要的东西.

It takes the message we want to listen to. You can also give it a list of content // messages // a database // anything necessary.

function sendList(channel, getList){
  channel.send(getList(0))
    .then(msg => msg.react(emojiPrevious))
    .then(msgReaction => msgReaction.message.react(emojiNext))
    .then(msgReaction => createCollectorMessage(msgReaction.message, getList));
}

这篇关于如何根据 Discord.js 中的反应编辑消息(创建列表和切换页面)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆