如何使Discord.js回复不一致的DM消息

时间:2019-05-21 07:05:17

标签: node.js discord.js

我正在尝试让discord.js在Discord上读取DM消息,以拥有一个将是从头开始制作的服务器/派生应用程序机器人的机器人,但是当您将%apply输入到该机器人时,我可以将其发送给第一部分尝试通过问题2时问题就来了,它总是得到问题2而不是问题3

当它们与传递的DM消息不同时,我试图过滤掉DM消息,所以我有几个if命令

bot.on("message", function(message) {
if (message.author.equals(bot.user)) return;
    if (message.content === "%apply") {
        apply = "TRUE";
        a0 = message.author.lastMessageID
        message.author.sendMessage("```We need to ask some questions so  we can know a litte bit about yourself```");
        message.author.sendMessage("```Application Started - Type '#Cancel' to cancel the application```");
        message.author.sendMessage("```Question 1: In-Game Name?```");
    }
    if ((message.guild === null) && (message.author.lastMessageID != a0) && (message.content != "%apply") && (apply === "TRUE")) {
        a1 = message.author.lastMessageID;
        message.author.sendMessage("```Question 2: Age?```");
    }
    if ((message.guild === null) && (message.author.lastMessageID != a1) && (message.author.lastMessageID != a0) && (apply === "TRUE")) {
        a2 = message.author.lastMessageID;
        message.author.sendMessage("```Question 3: Timezone? NA, AU, EU, NZ, or Other? (If other, describe your timezone)```");
    }
    if ((message.guild === null) && (message.author.lastMessageID != a2) && (message.author.lastMessageID != a1) && (message.author.lastMessageID != a0) && (apply === "TRUE")) {
        a3 = message.author.lastMessageID;
        message.author.sendMessage("```Question 4: Do you have schematica?```");
    }

我希望它从问题1到问题2,再到问题3

2 个答案:

答案 0 :(得分:3)

前言

尽管@Gruntzy的回答没有错,但Discord.js中内置了另一种解决方案,用于这些情况-TextChannel.awaitMessages()。您可以在如下所示的系统中使用它。

示例代码

const questions = [                    // ------------------------------------
  "What's your IGN?",                  //
  "How old are you?",                  // Define the questions you'd like the
  "What time zone do you reside in?",  // application to have in this array.
  "Do you have Schematica?"            //
];                                     // ------------------------------------

const applying = [];

bot.on("message", async message => {
  if (message.author.bot) return;

  if (message.content.toLowerCase() === "%apply") {
    if (applying.includes(message.author.id)) return;

    try {
      console.log(`${message.author.tag} began applying.`);

      applying.push(message.author.id);
      await message.channel.send(":pencil: **Application started!** Type `#cancel` to exit.");

      for (let i = 0, cancel = false; i < questions.length && cancel === false; i++) {
        await message.channel.send(questions[i]);
        await message.channel.awaitMessages(m => m.author.id === message.author.id, { max: 1, time: 300000, errors: ["time"] })
          .then(collected => {
            if (collected.first().content.toLowerCase() === "#cancel") {
              await message.channel.send(":x: **Application cancelled.**");
              applying.splice(applying.indexOf(message.author.id), 1);
              cancel = true;

              console.log(`${message.author.tag} cancelled their application.`);
            }
          }).catch(() => {
            await message.channel.send(":hourglass: **Application timed out.**");
            applying.splice(applying.indexOf(message.author.id), 1);
            cancel = true;

            console.log(`${message.author.tag} let their application time out.`);
          });
      }

      await message.channel.send(":thumbsup: **You're all done!**");

      console.log(`${message.author.tag} finished applying.`);
    } catch(err) {
      console.error(err);
    }
  }
});

说明

为了使代码更易于理解,让我们逐步进行操作...

1。前几行。

  • questions数组包含您想要在应用程序中询问的所有问题。为了效率起见,我实现了一个数组。只需更改一行就可以添加或删除一个问题,并且不会重复复制和粘贴相同的代码。
  • applying数组将帮助我们在申请过程中跟踪用户。

2。消息事件。

  • 我已经实现了箭头函数(ES6)作为回调并声明了它异步,因此我们可以在其中使用await
  • 我们阻止机器人触发任何命令。
  • 我们检查案例iNsEnSiTiVeLy是否应该运行该命令。
  • 您会注意到,后续代码包装在try...catch statement中。这样一来,我们就可以轻松捕获任何unhandled promise rejections(即TextChannel.send()抛出错误)。

3。 %apply命令。

  • 我们将用户添加到applying数组中。
  • 我们发送开始消息。
    • 请注意关键字await:它会继续兑现承诺,然后继续前进。
  • 我们使用for循环来迭代questions数组。
    • let i = 0, cancel = false声明了i(“ counter”变量)和一个cancel变量,因此,如果用户要取消应用程序或它超时,我们可以停止循环。我们无法在break回调中使用then(),因此我已恢复为此方法。
    • i < questions.length && cancel === false是我们要继续进行下一个迭代之前要匹配的条件-计数器必须在数组的范围内,并且cancel仍必须为false
    • i++将计数器加1。
  • 在循环内部,我们发送问题,然后调用TextChannel.awaitMessages()。我们的第一个参数是消息必须通过的过滤器,第二个参数是选项。
    • 在我们的then()回调中,我们检查消息是否为#cancel。如果是这样,我们发送取消消息,从阵列中删除用户,并将cancel的值设置为true
    • 如果5分钟内未提供任何消息,则将调用我们的catch()方法。因此,在回调中,我们发送超时消息,从数组中删除用户,并将cancel的值设置为true
  • 循环完成后,我们将发送完成消息。此时,您可以根据需要处理该应用程序。

答案 1 :(得分:0)

您的变量a0, ... , a3"onMessage"范围内,并且每次在回调中都未定义。因此,如果您的消息不是%apply,则会陷入“问题2”步骤

您应该在全局变量中跟踪用户的注册步骤,并阅读该变量以了解您要执行的步骤。 这是如何执行此操作的简短示例。 请注意,这是一种非常基本的方法,如果需要在应用过程中添加更复杂的功能,则最好使用一些内存数据库。 它还需要更多控件,我想还有一些其他数据存储来跟踪用户答案。

let userApplications = {}

bot.on("message", function(message) {
  if (message.author.equals(bot.user)) return;

  let authorId = message.author.id;

  if (message.content === "%apply") {
      console.log(`Apply begin for authorId ${authorId}`);
      // User is not already in a registration process    
      if (!(authorId in userApplications)) {
          userApplications[authorId] = { "step" : 1}

          message.author.send("```We need to ask some questions so  we can know a litte bit about yourself```");
          message.author.send("```Application Started - Type '#Cancel' to cancel the application```");
          message.author.send("```Question 1: In-Game Name?```");
      }

  } else {

      if (message.channel.type === "dm" && authorId in userApplications) {
          let authorApplication = userApplications[authorId];

          if (authorApplication.step == 1 ) {
              message.author.send("```Question 2: Age?```");
              authorApplication.step ++;
          }
          else if (authorApplication.step == 2) {
              message.author.send("```Question 3: Timezone? NA, AU, EU, NZ, or Other? (If other, describe your timezone)```");
              authorApplication.step ++;
          }
          else if (authorApplication.step == 3) {
              message.author.send("```Question 4: Do you have schematica?```");
              authorApplication.step ++;
          }

          else if (authorApplication.step == 4) {
              message.author.send("```Thanks for your registration. Type %apply to register again```");
              delete userApplications[authorId];
          }

      }
  }


});

其他一些快速注释:

  • sendMessage(msg)已在discord.js api中弃用,send(msg)现在应使用
  • 要测试接收到的消息是否为dm,我认为最好检查message.channel.type而不是查找空的message.guildId