A Guide to Discord Bots
Prefix & More Commands
Prefix
A prefix is something that you attach before every command.
Most bots have one, it helps to reduce RAM usage and you can have multiple bots with the sames commands, but a different prefix.
In this book, I'll use the prefix *
.
Let's implement it into our code:
client.on('message', message => {
if (message.channel.type != 'text' || message.author.bot || !message.startsWith('*'))
return;
if (message.content === '*ping') {
message.channel.send('pong');
}
});
The startsWith() method.!message.startsWith('*')
will make sure the bot ignores the message if it doesn't start with our prefix.
I also edited the condition to check if the message is *ping
.
More commands
Let's add a *say
command!
This command will make the bot say what we want. Simple, right?
client.on('message', message => {
if (message.channel.type != 'text' || message.author.bot || !message.startsWith('*'))
return;
if (message.content === '*ping') {
message.channel.send('pong');
}
else if (message.content === '*say') {
message.channel.send(message.content);
}
});
Let's test it!
...
It only answers with *say
when I type *say
and does nothing else... why?
Because your bot is checking if the message is exactly *say
.
To fix that, we can use, as seen earlier, message.content.startsWith('*say');
.
It works! ...almost.
It still answers with *say
+ what you typed.
One solution could be:
else if (message.content.startsWith('*say')) {
/* this will make sure the person didn't just type '*say',
but something like '*say hi'... */
if (!message.content.includes(' '))
return;
/* ...or else this would make your bot crash.
this will only remove the first '*say ' found */
message.channel.send(message.content.replace('*say ', '');
}
Of course, we don't necessarily need the check, because we could find a better solution, but the reason why I included it is because we can make the bot answer with the command's syntax.
Example: Syntax: *say <message>
.
If...else if...else if...switch?
Having multiple else if
statements is not really a bad thing, but you might be interesting in using a switch
instead.
If you have many else if
, using a switch
statement is often faster.
Note: you'll need a better way to determine which command was used.
let command = message.content.split(' ')[0].slice(1);
/* message.content: '*say hello world'
message.content.split(' '): ['*say', 'hello', 'world']
message.content.split(' ')[0]: '*say'
message.content.split(' ')[0].slice(1): 'say'
*/
// Arguments will be useful in the next part
let args = message.content.replace('*' + command, '').trim();
switch (command) {
case 'ping':
message.channel.send('pong');
break; /* <- don't forget this!
If you don't put it, it will execute the next command too */
case 'pong':
// You don't need brackets inside a switch
message.channel.send('ping');
break;
case 'say': {
// But you can use them to avoid a conflict between let statements
let sentence = message.content.replace(command, '').trim();
message.channel.send(sentence);
message.delete(); /* not obligatory,
don't forget you can customize your commands :) */
break;
}
case 'test': {
/* 'let sentence' is not already defined, because we put brackets
in the previous command */
let sentence = 'brackets are useful';
console.log(sentence);
break; /* <- useless for the last command, but as you add more,
you might forget to add it*/
}
}
trim() will remove whitespaces from the left and the right of the given string.
You can alternatively use trimLeft() or trimRight(), but trim() is more common.