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

查看:89
本文介绍了如何根据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:

反应后:

< img src = https://i.stack.imgur.com/HKd3v.png alt =在此处输入图片描述>

推荐答案

如何处理消息反应?


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

How to handle a message reaction?

There is 3 ways to react to a message reaction:


  1. 使用函数 awaitReactions (基于承诺)

  2. 使用 ReactionCollector

  3. 使用 messageReactionAdd 事件

  1. Using the function awaitReactions (promise based)
  2. Using a ReactionCollector
  3. Using the messageReactionAdd event


区别:


messageReactionAdd 是链接到 Client 的事件:


每当将响应添加到缓存的消息时发出。

Emitted whenever a reaction is added to a cached message.

ReactionCollector awaitReactions 链接到特定消息,如果将响应添加到另一条消息中,则不会执行任何操作。

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秒后等等),才返回所有添加的反应的集合。没有专门的支持来处理每个增加的反应。您可以将函数放入过滤器函数中,以获取添加的所有响应,但这不是一个小技巧。但是, 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.

您要编辑您的漫游器发送的消息(因为您无法编辑其他用户的消息)。因此, ReactionCollector awaitReactions

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

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

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.

注意:如果机器人重新启动, ReactionCollector awaitReactions 将被删除,而 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,而不是对布尔条件使用索引

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],而不是像上面一样设置一个时间戳,因为尝试对未定义执行 .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 // anything. Here the edit functions is globally defined, but it will more likely be given as an argument from the collector to the logic function.

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天全站免登陆