Milkhype235
Milkhype235

Reputation: 13

I cannot add multiple prefixes in Discord.js

The current prefix is '#'.

module.exports = async function(msg) {
    let args = msg.content.split(' ');
    let command = args.shift();
    if (command.charAt(0) === '#') {
      command = command.substring(1);
      commandName[command](msg, args);
    }
};

When I tried to add an array of prefixes to it, it doesn't seem to work.

const prefix = [ '#', 'br', 'bread', '<@767558534074204191>', '<@!767558534074204191>', ];

module.exports = async function(msg) {
  let tokens = msg.content.split(' ');
  let command = tokens.shift();
  if (command.charAt(0) === prefix) {
    command = command.substring(1);
    commandName[command](msg, tokens);
  }
};

How can I add more prefixes to this so I can have multiple prefixes? Like the bot mention as one of the prefix.

Upvotes: 1

Views: 484

Answers (2)

Zsolt Meszaros
Zsolt Meszaros

Reputation: 23161

If you’ve got an array of prefixes, you can’t compare that to the first character of a string. It will be false, every single time. You should compare strings to strings, so you should compare the elements of the array to the message.

You can use the .some() method on arrays to check if at least one element in the array passes the test implemented by the provided function. In that function you can check if the message startsWith() any of the strings in the array.

A function like array.some(el => message.startsWith(el)) returns true if the message starts with any of the strings in array.

Check the following snippet. You can see how you can use .some() and .startsWith() together:

let message = '';
const prefixes = [ '#', 'br', 'bread', '<@767558534074204191>', '<@!767558534074204191>', ];

console.log(prefixes.some(prefix => message.startsWith(prefix)), message)

message = 'lorem ipsum'
console.log(prefixes.some(prefix => message.startsWith(prefix)), message)

message = '# lorem ipsum'
console.log(prefixes.some(prefix => message.startsWith(prefix)), message)

message = 'br lorem ipsum'
console.log(prefixes.some(prefix => message.startsWith(prefix)), message)

message = 'bread lorem ipsum'
console.log(prefixes.some(prefix => message.startsWith(prefix)), message)

message = '<@767558534074204191> lorem ipsum'
console.log(prefixes.some(prefix => message.startsWith(prefix)), message)

message = '<@!767558534074204191> lorem ipsum'
console.log(prefixes.some(prefix => message.startsWith(prefix)), message)

Your code will look like this:

const prefixes = [
  '#',
  'br',
  'bread',
  '<@767558534074204191>',
  '<@!767558534074204191>',
];

module.exports = async function(msg) {
  let tokens = msg.content.split(' ');
  let command = tokens.shift();

  if (prefixes.some(prefix => command.startsWith(prefix))) {
    command = command.substring(1);
    commandName[command](msg, tokens);
  }
};

Update: I've just checked back and noticed that you try to remove the prefix from the command using command.substring(1). That hardcoded 1 will always remove the first character only, so you need to change that to the prefix's length.

At the moment, using .some() you don't know which prefix is used so it's probably better to use the .find() method that returns the value of the first element in the provided array that satisfies the provided testing function. This way you can check if the message contains any of the prefixes AND you know the prefix and its length. Run the following snippet how it works:

// I changed the order of prefixes as bread starts with br
const prefixes = [ '#', 'bread', 'br', '<@767558534074204191>', '<@!767558534074204191>', ];
let prefix = '';
let command = '';

command = 'lorem ipsum'
prefix = prefixes.find((prefix) => command.startsWith(prefix));
console.log({command, prefix});

command = '# lorem ipsum'
prefix = prefixes.find((prefix) => command.startsWith(prefix));
console.log({command, prefix});

command = 'br lorem ipsum'
prefix = prefixes.find((prefix) => command.startsWith(prefix));
console.log({command, prefix});

command = 'bread lorem ipsum'
prefix = prefixes.find((prefix) => command.startsWith(prefix));
console.log({command, prefix});

command = '<@767558534074204191> lorem ipsum'
prefix = prefixes.find((prefix) => command.startsWith(prefix));
console.log({command, prefix});

command = '<@!767558534074204191> lorem ipsum'
prefix = prefixes.find((prefix) => command.startsWith(prefix));
console.log({command, prefix});

So your modified code will look like this:

client.on('message', (msg) => {
  let tokens = msg.content.split(' ');
  let command = tokens.shift();
  let prefix = prefixes.find((prefix) => command.startsWith(prefix));

  if (prefix) {
    command = command.substring(prefix.length);
    commandName[command](msg, tokens);
  }
});

Upvotes: 1

Daniel Turcich
Daniel Turcich

Reputation: 1834

The lines

const prefix = [ '#', 'br', 'bread', '<@767558534074204191>', '<@!767558534074204191>' ];

  if (command.charAt(0) === prefix) {
     ... do stuff
  }
};

You defined an array with 5 values, and then you are trying to see if the first character of the string command is equal to the array. This will never evaluate to true because the function .charAt(0) is going to return only the first character of that string.

What you're going to want to do is check each value of the array against the command. We can use the startsWith() function on the string while looping through the array.

Something like:

const prefix = [ '#', 'br', 'bread', '<@767558534074204191>', '<@!767558534074204191>' ];
  
  // see if a value in the prefix array is at the beginning of the command.
  for(let x = 0; x < prefix.length; x++) {
      if (command.startsWith(prefix[x])) { 
          ...do whatever you were intending to here
          break // break out of the loop by using the break keyword.         
      }
  }
  })
};

Upvotes: 0

Related Questions