0

I've been coding a Poll Command for my Discord Bot. It is in Discord.JS but when I am going to run the command, it does this error:

I've been trying to fix this issue for a while and it still does this issue. I've changed some lines of code, particularly line 65 and line 70-80.

Code:

const options = [
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
  '',
];

const pollLog = {}; 

function canSendPoll(user_id) {
  if (pollLog[user_id]) {
    const timeSince = Date.now() - pollLog[user_id].lastPoll;
    if (timeSince < 1) {
      return false;
    }
  }
  return true;
}

exports.run = async (client, message, args, level, Discord) => {

    if (args) {
      if (!canSendPoll(message.author.id)) {
        return message
          .channel
          .send(`${message.author} please wait before sending another poll.`);
      } else if (args.length === 1) { // yes no unsure question
        const question = args[0];
        pollLog[message.author.id] = {
          lastPoll: Date.now()
        };
        return message
          .channel
          .send(`${message.author} asks: ${question}`)
          .then(async (pollMessage) => {
            await pollMessage.react('');
            await pollMessage.react('');
            await pollMessage.react(message.guild.emojis.get('475747395754393622'));
          });
      } else { // multiple choice
        args = args.map(a => a.replace(/"/g, ''));
        const question = args[0];
        const questionOptions = message.content.match(/"(.+?)"/g);
        if (questionOptions.length > 20) {
          return message.channel.send(`${message.author} Polls are limited to 20 options.`);
        } else {
          pollLog[message.author.id] = {
            lastPoll: Date.now()
          };
          return message
            .channel
            .send(`${message.author} asks: ${question}
${questionOptions
    .map((option, i) => `${options[i]} - ${option}`).join('\n')}
`)
            .then(async (pollMessage) => {
              for (let i = 0; i < questionOptions.length; i++) {
                await pollMessage.react(options[i]);
                }
            });
        }
      }
    } else {
      return message.channel.send(`**Poll |** ${message.author} invalid Poll! Question and options should be wrapped in double quotes.`);
    }
  }

JeremyW
  • 5,157
  • 6
  • 29
  • 30
NTM Nathan
  • 67
  • 1
  • 4
  • 13
  • Can you show me how your args array looks like? – Sorin Lascu May 20 '19 at 13:26
  • My Args Array looks like this: message.content.match (/"(.+?)"/g); args = args.map(a => a.replace (/"/g, ' ')); const question = args.map (a => a.replace(/" /g, ' ')); const questionOptions = message.content.match(/"(.+?)"/g); – NTM Nathan May 20 '19 at 13:48
  • I meant the content of the args array. You know, `console.log(args);` . – Sorin Lascu May 20 '19 at 15:45

1 Answers1

1

The reason some of the question is listed as choices is because you define question as args[0], which is simply the first word given. You can solve this by looping through the arguments and adding those that don't appear to be a choice into the question. See the sample code below.

const args = message.content.trim().split(/ +/g);

// Defining the question...
let question = [];

for (let i = 1; i < args.length; i++) {
  if (args[i].startsWith('"')) break;
  else question.push(args[i]);
}

question = question.join(' ');

// Defining the choices...
const choices = [];

const regex = /(["'])((?:\\\1|\1\1|(?!\1).)*)\1/g;
let match;
while (match = regex.exec(args.join(' '))) choices.push(match[2]);

// Creating and sending embed...
let content = [];
for (let i = 0; i < choices.length; i++) content.push(`${options[i]} ${choices[i]}`);
content = content.join('\n');

var embed = new Discord.RichEmbed()
  .setColor('#8CD7FF')
  .setTitle(`**${question}**`)
  .setDescription(content);

message.channel.send(`:bar_chart: ${message.author} started a poll.`, embed)
  .then(async m => {
    for (let i = 0; i < choices.length; i++) await m.react(options[i]);
  });

The Regex used is from this answer (explanation included). It removes the surrounding quotation marks, allows escaped quotes, and more, but requires a solution like this to access the desired capturing group.

Note that you'll still have to check whether there's a question and if choices exist, and display any errors as you wish.

slothiful
  • 5,548
  • 3
  • 12
  • 36