How to code a Discord bot with Node.JS

Hey there, friends! I'm David, and today, we'll be building our very own Discord bot using Node.js. So, buckle up and let's get started!

Prerequisites and Setup

Before we begin, make sure you have Node.js installed on your computer. You can download it from nodejs.org. You'll also need a code editor, like Visual Studio Code or Sublime Text.

Once you have Node.js installed, we'll create a new folder for our project, navigate to it in the terminal, and run npm init to create a new package.json file. This file will store our project's dependencies and configurations.

Creating a Discord Application

Now, we'll head to the Discord Developer Portal at https://discord.com/developers/applications and create a new application by clicking the 'New Application' button. Give your bot a name and click on 'Create'.

Next, navigate to the 'Bot' tab on the left sidebar, and click 'Add Bot'. Confirm the action, and now you have a new bot!

Copy the bot's token secret (or refresh it if you don’t see it). The token is sensitive. It is what allows your code to act as the bot.

To protect this information, we will store it in a .env file. Let’s create it at the root of our project, and inside write :

BOT_TOKEN=<the value of the token>

While we are at it, we also need to add the APP_ID and SERVER_IDvalues to the file. The APP_ID is easy to find on the General Information page of your app in the Discord Developer Portal. Let’s add it to the .envfile:

APP_ID=<your app id>

The SERVER_IDis a bit more difficult to find.

First, you need to activate Developper mode in Discord. For that, you need to head to the Advanced tab in the user settings in the Discord client and change the setting called “Developer Mode”.

Then, still in the Discord client, go to the Discord server, right-click on the server name and select Copy IDright at the bottom. Let’s add it to the .envfile:

SERVER_ID=<your server id>

Now an important step. Create a .gitignorefile, and add.envfile to it. This excludes the file from being tracked by git.

.env

This prevents our secret from being pushed to wherever our code is stored, if we want to track our changes with git.

Adding the bot to a server

Before we go any further, we also need to invite the bot to the server. To do this, the Discord App section has a useful invitation link builder within the oAuth2 section.

You must select bot and application.commands and the permissions you want to give, such as “Send Messages” or “Embed Links”. The exact permissions depend on what exactly you want to do. Don’t worry about it; you can always add more later.

Sign up to our newsletter

We help you better understand software development. Receive the latest blog posts, videos, insights and news from the frontlines of web development

We respect your privacy. Unsubscribe at any time.

Installing Dependencies and Setting Up the Project

Now, in your project folder, run the following command in your terminal to install the Discord.js library:

npm install discord.js

We also want to install the dotenvlibrary to ensure the environment variables stored in the .envfile are read and added to the code.

Let’s create a new file called index.js in your project folder. In this file, we'll write the code to set up and run our Discord bot. First, let's import the necessary libraries and create a new Discord client. We’ll import Client, Eventsand GatewayIntentBitsfrom the discord.jslibrary.

// Require the necessary discord.js classes
const { Client, Events, GatewayIntentBits } = require('discord.js');


We also want to initialise our environment variables using dotenv, and for that, we add:

require('dotenv').config();

Now we want to initialise the client instance. Here we call the Client constructor and specify the value of the intents field in the parameter object. The intents are basically the rights you want your bot to have. For now, let’s specify that we want the Guildsobject from the GatewayIntentBit. A Guild, in internal discord parlance, means a server.

// Create a new client instance
const client = new Client({ intents:[
	GatewayIntentBits.Guilds
]});

Then we create a callback for the discord client to call when the login is done, where we basically print out the user the client is logged in as:

client.once(Events.ClientReady, c => {
	console.log(`Ready! Logged in as ${c.user.tag}`);
});

Finally, we log in using the BOT_TOKEN we’ve defined in our .envfile.

client.login('YOUR_BOT_TOKEN');

If we run the bot using node JS, the bot now logs in and tells us what it is logged in as :

node index.js

Now, let's create a first command for our bot to react to:

Creating our first command

First, we’ll create a commands folder. This will store our different commands. We’ll use the SlashCommandBuilderutility from the discord.js library. Let’s start by importing it.

const { SlashCommandBuilder } = require('discord.js');

First, we need to define the command options. We do this by creating a data object that is an instance of SlashCommandBuilder.

const data = new SlashCommandBuilder()

Now we need to modify it to suit our needs. We’re creating a simple ping command for now, so we add :

    .setName('ping')
    .setDescription('Replies with Pong!')

This is also where we define if there are other additional parameters, for example, by using setStringOption. 

Now we need to define the code that the bot will be running when it gets the command, and to that end, we define an execute asynchronous function that takes an interaction object as a parameter:

const execute = async (interaction) => {
}

This object has a reply function, which we will be using to answer “Pong” to the user.

const execute = async (interaction) => {  
	await interaction.reply(`Pong!`);
}

Now we need to package this all up into a module that exports the data configuration and the execute callback :

module.exports = {
	data,
  execute
};

Our ping command is now ready to be added to the bot.

Adding the command to the bot

We need to tell the bot to execute the code we’ve just created. For that, let’s head to index.js and create a commands object that imports the code we’ve just written:

const commands = {
	ping: require('./commands/ping');
}

Now let’s create an event listener to react to Discord events :

const listener = async (interaction) => {
}

Inside this function, we first want to filter out any interaction that is not a command by checking the interaction is a “Chat Input Command” :

  if (!interaction.isChatInputCommand()) return;

Now we know the interaction is a command, we can log its name using the commandName property on the interaction:

console.log(`Received command : ${interaction.commandName}`);

Next, let’s retrieve the code that corresponds to the command :

const command = commands[interaction.commandName];

If the code does not exist, we leave:

if (!command) {
  return;
}

And now, we execute the code :

await command.execute(interaction);

Ideally, if we were building a full application, we would wrap this in a try/catch.

Our function now looks something like this :


const listener = async (interaction) => {

  if (!interaction.isChatInputCommand()) return;

  console.log(`Received command : ${interaction.commandName}`)

  const command = commands[interaction.commandName]
  if (!command) {
    return;
  }

  await command.execute(interaction);
};

Now let’s register the listener by adding:

client.on(Events.InteractionCreate, listener);

Start your bot by running node index.js in your terminal. Once the bot is online, type !ping in your Discord server, and the bot should reply with Pong!.

Congratulations! You've just built your very own Discord bot using Node.js. You can now extend its capabilities by adding more commands and functionality to suit your needs. Thanks for reading, and have fun coding!

Social
Made by kodaps · All rights reserved.
© 2024