Basic: Basic if - else block

The if - else block is the most basic way to handle commands. This method use simple logic to make the process flow goes into different blocks depends on the command. Almost all the discord.js basic tutorial, be it text or video, is using this method.

Pros:

  • Easy to understand
  • Easy to set up and get it running

Cons:

  • Everything is in one file, which means as the bot expands, maintenance and updating is getting more and more difficult
  • Have to update help command manually

StartsWith()

The basic guides made by evie use this method, which basically check if the message's content starts with a certain string, in our case, it's prefix + command

if (msg.content.startsWith("$ping")) {
    msg.channel.sendMessage('Pong!');
}

And if you want to include more commands, use else if like followed:

if (msg.content.startsWith("$ping")) {
    // Ping command
} else if (msg.content.startsWith("$repeat")) {
    // Repeat command
}

The { } indicate a block, and in this case, an if and else if block. And unless you know when you can not use it, please use it to properly mark the start and end of the block.

The code above will direct the process flow into the Ping command block if the message's content starts with "$ping", if it doesn't (aka else), it will check if the content starts with "$repeat" and goes into the Repeat command block if it does.

This works for most of the time, however it does have some downsides: If there's another command that starts with the same string as another command, for example, "inviteMe" which give a bot's auth link and "invite" which will give the guild's invite link, then there might be some conflict due to msg.content.startsWith("$invite") will also return true for the "$inviteMe". The way we do this is by add a space at the end of the command as well as the command.

let content = msg.content + ' ';
if (msg.content.startsWith("$ping ") {
    msg.channel.sendMessage("Pong!");
}

By adding a space at the end of the command, we indicate that the "ping" is a full word, and "pingAister" or "pinguin" won't trigger the command. This will be a problem if the content is just simply "$ping" though, so we add a space at the end of the message's content as well, and now both the content and the command checking will match. Handy!

Getting arguments

In ping command, you don't need arguments. However if you want to change the nickname of someone else, you might need to get the content AFTER the command. There are generally two ways to do this:

Slice + indexOf

args = message.content.slice(message.content.indexOf(' ') + 1);

This is a basic string manipulation to get the content of the message after the first space. This is simple and easy to understand, however if you have several arguments, then things will get a little dicey. So if you want to have several arguments, each arguments separated by a space, then you will need a way to "split" the string into array. And luckily, javascript have a method that does exactly that.

Split, Slice and Join

This method using 3 different methods

String.split(separator) will split the string into smaller strings which were previously separated by the separator, and then put them into an array. This method will return an array.
Array.slice(position, [length])
kinda similar to the String.slice, Array.slice will return part of the array starting from the position and has an optional length.
Array.join(separator) is the opposite of the String.split. This will put all the Array elements into a string, separated by the separator.

Put it together, we will have this small piece of code

// message.content = "$quote Crawl Grey is too cute";
// expected result = "Crawl said: Grey is too cute";
// the first word of the content is the command and thus can be ignored after we run command check
// the second word (args1) is the author of the quote
// the rest of the content (args2) is the content of the quote

content = message.content + ' ';
msgArray = message.content.split(' '); // msgArray = ["$quote", "Crawl", "Grey", "is", "too", "cute"]
if (message.content.startsWith("$quote ")) {
    if (msgArray.length > 2) { // Since this command needs 2 arguments, the number of element in the array will need to be 3 at least
        args1 = msgArray[1]; // args1 = "Crawl";
        args2 = msgArray.slice(1); // args2 = ["Grey", "is", "too", "cute"]
        args2= args2.join(' '); // args2 = "Grey is too cute";

        console.log(args1 + " said: " + args2); //Console: Crawl said: Grey is too cute
    }
}

However, if we look at the comments closely, you can see that the command itself is also part of the msgArray! And if we use that for the command check, then we don't even need to use startsWith anymore! We have ourselves a new way to do our command check!

Split(' ')

Using what we've learned from the above code, we adjust the code to this!

args = message.content.split(' '); // msgArray = ["$quote", "Crawl", "Grey", "is", "too", "cute"]
command = args[0]; // command = "$quote"

if (command == "$quote") {
    if (args.length > 2) {
        args1 = args[1]; // args1 = "Crawl";
        args2 = msgArray.slice(2); // args2 = ["Grey", "is", "too", "cute"]
        args2= args2.join(' '); // args2 = "Grey is too cute"

        console.log(args1 + " said: " + args2); //Console: Crawl said: Grey is too cute
    }
}

This looks way cleaner, doesn't it? Not only it looks cleaner, it is faster too! Even though it's just a very small unnoticeable margin. The only down-side of this is we won't be able to use commands that are two words or more. However these kind of commands is not recommended anyway so let's try our best to stay away from those.

There you have it, the basic tutorial of how to handle commands via if-else block. You can improve the code by adding more stuffs to it like having a separate variable for the prefix for easy prefix change, but I'll leave that up to you to modify it to your liking.

I hope this tutorial is easy enough to understand. I don't know if I have missed anything, so if there's anything you don't know, please feel free to ask and I'll try my best to answer!

results matching ""

    No results matching ""