Discord BOT Development Basics using Node.JS

Discord BOT Development Basics  using Node.JS

In this blog post you will hopefully gain a basic understanding of how you can create your own Discord BOT application, the BOT we will be creating is very simple but it will hopefully teach you enough to allow you to expand on your own.

Prerequisites

  • Node.js v10 or higher installed
  • Discord account
  • Basic knowledge of using a terminal

Setting Up Test Server

In order to test our application we will need to create a test server on Discord, you don't have to create a test server but its just a good idea. Create a new server by clicking the plus icon on the bottom left side of your Discord client. If you already have a test server setup or know how to make a server consider skipping these steps.

You should then see a pop-up message there will be a few options that you can select from but click on "Create My Own".

Another window should pop-up and you will want to click on "For me and my friends"

Then give your server a name (Test Server) and click create.

You should now see your newly created server!

Creating an Application (Discord BOT)

Now lets create a new Discord BOT, head over to the Discord Developer Portal login with your Discord account and click "New application" found in the top right corner. You should then see a new pop-up message, give your BOT a name (Test BOT) and then click create.

You will be redirected to a new screen which will show important information we need in order to program our BOT. Copy down the Client ID and save it somewhere as we will need to use it later, then click on the BOT button on the side menu.

You should now see another new window this is where we will create our BOT, click on the "Add Bot" button. Now you should be able to access the BOT's token.

Copy down the BOT's token and save it somewhere safe, make sure to not share this to anyone otherwise they will then have access to your BOT!

Inviting our BOT

Now in order for us to actually test our BOT we require it to be in our Test Server, to do this head over to Discord Permission Calculator and paste the CLIENT ID you copied earlier in the text field.

Next select the permissions your BOT requires, for our Test BOT we wont need much so just select (Send Messages and Read Messages). A link should be generated at the bottom of the page, go ahead and open that up in a new tab.

You will then be prompted with a new window, from the drop down menu find and select your Test Server that you created and click "Continue".

Your Test BOT should now show up on your server!

Project Setup

Lets start creating our application, first open up an text editor of your choice (Visual Studio Code) and open up a new project folder, call it whatever you want.
Next we will install the packages we need, open up a Terminal inside of your project folder and run the following commands (Keep in mind you should have Node.JS installed),

npm init - Step-by-step tool to scaffold out your project.
npm install discord.js - Install's discord.js package.
npm install chalk - Install's chalk package.
npm install enmap - Install's enmap package.

After running those commands you should now see a new folder called node_modules this folder consists of the packages for our application, package.json more info can be found here and for the package-lock.json file more info can also be found here.

Folder Structure

Below is our folder structure, this is how our project will be set out. If you don't understand how to read this I will explain below! If you would like to see the folder structure for yourself you can see the source code here.

*Note: You wont need to create node_modules, package.json or package-lock.json since these where generated from the commands we ran earlier.

├── cfg
│   └── config.json
├── commands
│   └── help.js
├── events
│   ├── message.js
│   └── ready.js
├── node_modules
│   └── Our packages will show here*
├── main.js
├── package-lock.json
└── package.json

First of all we have cfg this is a folder and inside that folder we have config.json which is a file where we will store our BOT's token and prefix.

Next we have the commands folder where we will store all our of our commands, whatever you name the file inside of this folder is what our command handler will call for. (If our prefix is ~ and we have help.js inside our command folder, to call this command on discord we will run ~help)

Then we have the events folder basically inside this folder we have two files, message.js and ready.js. message.js will handle all the messages that the BOT see's (It will tell the BOT to ignore messages not starting with the prefix, If that command doesn't exist, silently exit and do nothing etc...) and finally ready.js basically logs our console once our BOT is ready and online.

node_modules will just store all of our packages that we install so we don't have to create this folder or really touch it.

And next is main.js this is one of the most important files in our project since this is where everything starts basically, when we want to run our application we will call this file and it should load our BOT and all the commands we store.

Finally we have package.json and package-lock.json, again these are created when we run our commands from before they basically store important information (What packages we have installed etc...)

Programming our BOT

First we will start with configuring our application, create a new folder called cfg in the root directory of our project. And inside that folder create a new file called config.json. Depending on what text editor you are using you should have something like this,

Inside the config.json file we will add the following code,

{
    "token": "token_here",
    "prefix": "prefix_here"
}

Place your BOT's token that you saved earlier into token_here and now we want to chose a prefix, a prefix is what we will use to call commands from our BOT (Most BOTS use !) Put anything you want in prefix_here for this application I am going to be using "!". It should then look something like this,

Next lets create our main.js file, create this in the root directory of our project, first we will import our requirements you can do this by adding the following code,

const Discord = require("discord.js");
const Enmap = require("enmap");
const fs = require("fs");

const - Is what we use to define something, in our first line we are defining Discord to the "discord.js" package we installed earlier using require.

Now we will initialize our Discord BOT and making sure to add our config we created earlier. There is a also a few other lines of code which I will explain below.

const client = new Discord.Client();
const config = require('./cfg/config.json')
client.commands = new Enmap();
chalk = require('chalk');
client.config = config;

const client = new Discord.Client(); - Creates a new Discord Client that will be used by our application, we defined this to client. We where able to do this becuase earlier we defined the Discord.js package to Discord allowing us to call multiple methods from this package.

Next we import our config file which we will later use to set our prefix and token.

Since we defined our Discord Client to client we will have to use that whenever we want to define something to our Client, so on line three we are creating a data structure that can be used to store data in memory using Enmap.

Finally we import the chalk package which will be used later and we also define our config to the client.

Your main.js file should now look something like this,

Now lets create two new folders inside of the root directory, call one events and the other one commands. We will create the files that are required in these folders in a second, first we need to setup our event / command handler inside of our main.js file. Add the following code.

fs.readdir("./events/", (err, files) => {
    if (err) return console.error(err);
    files.forEach(file => {
      const event = require(`./events/${file}`);
      let eventName = file.split(".")[0];
      client.on(eventName, event.bind(null, client));
    });
  });
  
  client.commands = new Enmap();
  
  fs.readdir("./commands/", (err, files) => {
    if (err) return console.error(err);
    files.forEach(file => {
      if (!file.endsWith(".js")) return;
      let props = require(`./commands/${file}`);
      let commandName = file.split(".")[0];
      console.log(chalk.green(`[+] ${commandName}`));
      client.commands.set(commandName, props);
    });
});

It may seem like quite a-lot at first but its quite simple to understand, the first section is going to read each file inside of the events folder and then name each event by splitting the file name from "." (If file is called ready.js is will be named ready), finally it will then initialize these events with our client.

Next we we will create a new data structure that will be used to store our commands in memory using Enmap, and the final section of code is going to basically do the same as the events section, we will  read each file inside of the commands folder and then log our console when a command has been loaded.

We are almost done with our main.js file we just need to add a few more lines of code, these will basically log our BOT into Discord and set our BOT's online activity.

client.on("ready", () => {
  client.user.setActivity('Set Activity', { type: 'WATCHING' });
});

client.login(config.token)

When our client is "ready" (logged in) it will then set its online activity, this is basically what users see on Discord when you are playing a game or something else. And finally we log our BOT into Discord by accessing our config file we defined earlier and grabbing the token from that file.

If you did everything correctly your main.js file should look something like this,

If you run into any errors you can find the source code for this file here.

Now inside of your events folder create a new file called ready.js, as I explained earlier this file will basically just log our console when our BOT is online and ready. Please add the following code.

const chalk = require("chalk")
const config = require("../cfg/config.json")
module.exports = (client) => {
    console.log(chalk.magenta(`Bot Made by LachlanDev#8014 \nPrefix is ${config.prefix}`));
}

Basically we import the chalk package we installed earlier, this allows us to log our console with coloured text. Then we import our config file so we can access the prefix. And finally module.exports allows us to access our client that we defined in our main.js file then logging the console.

Create a new file inside of the events folder called message.js this file will tell our BOT basically what to look for whenever it reads a message that is sent. Add the following code.

module.exports = (client, message) => {
    // Ignore all bots
    if (message.author.bot) return;
  
    // Ignore messages not starting with the prefix (in config.json)
    if (message.content.indexOf(client.config.prefix) !== 0) return;
  
    // Our standard argument/command name definition.
    const args = message.content.slice(client.config.prefix.length).trim().split(/ +/g);
    const command = args.shift().toLowerCase();
  
    // Grab the command data from the client.commands Enmap
    const cmd = client.commands.get(command);
  
    // If that command doesn't exist, silently exit and do nothing
    if (!cmd) return;
  
    // Run the command
    cmd.run(client, message, args);
  };

I have added comments before each line (// Ignore all bots) these will hopefully explain each function to you.

Now your events folder should contain two files ready.js and message.js you can find the source code to the events folder here.

Our BOT is pretty much now setup, we just have to add some commands and then that's it.

Creating Commands

Creating a new command is simple, create a new file in the commands folder calling it whatever you want the command to be called, for example lets create one called ping.js. As I mentioned earlier whatever we name the file inside the commands folder is what the command will be called when we want to execute it.
Now add the following code to your ping.js file.

const discord = require ("discord.js");

exports.run = (client, message, args) =>{
    message.channel.send ('pong!')
}

We are again importing the Discord.js package, this can be used to create embeds and other things which I will explain later on. Then we use the exports.run function which will run the code inside that block whenever the file gets called, we also state client, message and args.
Client can be used to get all kinds of Properties from our client such as the PING of our BOT or simply its uptime.
Message will be used to send messages or to see the Author of a message (Whoever executed the command).
And finally args which is used to get arguments after the command has been executed, this allows us to read any content attached to the command.

This is a simple script which will just send a message back saying "pong!" and it will look something like this.

If you want to test out your BOT open a Terminal to the root directory of your project and run the following command.

node main.js

Your console should hopefully output the following,

If so you have successfully created your BOT and now you can test your command in your test server by running !ping or whatever you defined your prefix.

Now lets create a simple Discord Embed, this is basically is another component of a Discord messages that can be used to present data with special formatting and structure. Create a new file called help.js and then add the following code.

const discord = require ("discord.js");

exports.run = (client, message, args) =>{
    const help = new discord.MessageEmbed()
    .setColor('#b434eb')
    .setTitle('Discord BOT Basic Embed')
    .setURL("https://blog.lachlan-dev.com/discord-bot-development-basics")
    .addField("Info", "This is a template for Discord BOT's.")
    .setFooter("BOT Template Made by LachlanDev#8014", "https://avatars1.githubusercontent.com/u/58458169?s=460&u=79564adeae9287fecf24814f64ed89cff91ca358&v=4")
    message.channel.send({embed: help })
};

Again we are importing the Discord.js package and setting up exports.run. We then construct a new embed and set it's properties. Once we have customized our embed we will then send it to the user, that will look something like this.

Make sure to restart your application by clicking ctrl + c and then running,

node main.js

to start your application again, this will then load the new command we just created.

Conclusion

Hopefully now you have gained a basic understanding of Discord BOT development, you now can almost do anything you want with this application. You can find most of the source code for this project here.
If you ran into any issues or would like help creating other commands or anything else feel free to join my Discord and I'll be happy to help, you can join here.

Thanks for taking the time to read through this blog post and I hope I helped you out, if you would like to contact me for anything you can use any of the following methods.

Twitter - @LachlanDev
Instagram -
@LachlanDev
Discord -
LachlanDev#8014
Discord Server -
Invite
Email -
[email protected]

Thanks again,
LachlanDev