2
votes

I'm making a simple discord bot, this is my first time doing so. I want the Discord bot to await my message before continuing but I can't seem to get this to work. How can I have the Discord bot wait before continuing on? Also, I know my "throw new Error"'s might not be super correct; I wasn't sure of another way to stop the run.

Any help is greatly appreciated! Thank you so much!

Code:

const Discord = require('discord.js');

module.exports = class NewgameCommand extends BaseCommand {
  constructor() {
    super('newgame', 'managment', []);
  }

  async run(client, message, args) {
    if (!message.member.roles.cache.some((r) => r.name === "staff")) {
      return message.channel.send("Only staff members can set up games!");
    }
    const gameEmbed = new Discord.MessageEmbed()
      .setTitle('New MvM Mondays Game!')
      .setDescription('Add description here.')
      .setColor("#FF0000")
      .setTimestamp();
    const twoCitiesMissionsDisplayed = "\`\`\`\n1 - ????Empire Escalation\n2 - ????Metro Malice\n3 - ????Hamlet Hostility\n4 - ????Bavarian Botbash\`\`\`";
    const twoCitiesMissionsArray = ['Empire Escalation', 'Metro Malice', 'Hamlet Hostility', 'Bavarian Botbash'];
    const numOfMissions = [1, 2, 3, 4];
    message.channel.send("What Two Cities mission?");
    message.channel.send(twoCitiesMissionsDisplayed);
    message.channel.awaitMessages(m => m.author.id == message.author.id,
      {max: 1, time: 30000}).then(collected => {
        const chosenMission = collected.first().content;
        if (!numOfMissions.includes(chosenMission)) {
          message.channel.send("You chose an invalid number!");
          throw new Error("Chose invalid mission number");
        }   
      }).catch(() => {
        message.channel.send('No answer after 30 seconds, operation canceled.');
        throw new Error("Took too long to respond.");
      });
    message.channel.send("Default classes? (yes/no)");
    message.channel.awaitMessages(m => m.author.id == message.author.id,
      {max: 1, time: 30000}).then(collected => {
        const classesAnswer = collected.first().content;
        if (!numOfMissions.includes(collected.first().content)) {
          message.channel.send("All you had to do was say \"yes\" or \"no\"...");
          throw new Error("Didn't say \"yes\" or \"no\"");
        }       
      }).catch(() => {
        message.channel.send('No answer after 30 seconds, operation canceled.');
        throw new Error("Took too long to respond.");
      });
  }
}

What I see in Discord: What I see in Discord

1

1 Answers

2
votes

We can detect timeouts using the catch block of the awaitMessages promise. Then, we can make it emit an error after timeout. Here is an example.

function filter(m){
    if(m.author.id != message.author.id) return false;
    if (!numOfMissions.includes(chosenMission)) {
        m.channel.send('You chose an invalid number!');
        return false;
    }
    return true;
}  
message.channel.awaitMessages(filter, { max: 1, time: 30000, errors: ['time'] })
    .then(collected => {
        const chosenMission = collected.first().content;
        message.channel.send(`You chose the ${chosenMission} mission`);
    })
    .catch(() => {
        message.channel.send('No answer after 30 seconds, operation canceled.');
    });

As you can see, I included the valid-number-check in the filter. This can allow the message collector not to end even if an invalid number is entered.

Also, I included errors: ['time'] in the options of the awaitMessages() function. This tells the function to throw an error when the time is up (30 seconds in this case), and the error will cause the code to fall in the catch block of the promise.