In this tutorial, you will learn how to connect a bot to the Discord server and create commands that it will respond to. To achieve this, you will use Node, Typescript, DiscordJS, and dependency injection(InversifyJS). But before we start, let’s talk about the benefits Discord offers.
Every day we have more and more VoIP services to choose from, but most gamers have already decided on Discord for communication. Today, not only gamers but agencies and companies started using Discord. Why? You may ask. Because it offers everything that business communication platforms, such as Slack or RocketChat, need. The main differences are that Discord:
Note: Discord, along with all of the features we will be using in this tutorial, is free to use.
To summarize, in this tutorial, you will learn:
Note: If you want to skip ahead to the final project, check out the code in my GitHub repository.
For the IDE, you can use whatever you feel comfortable with - for me, that is Webstorm. Before creating a bot, you need to create a project. To do that, use the following command:
This will open an interactive process for initializing your project with the package.json file. Fill these questions or just skip all by pressing Enter, because it does not matter for this tutorial.
After initializing the project, install the following dependencies by running this command inside your project (terminal):
Then for the last step of setup, you need to change scripts inside the package.json file. Later on, you will need two scripts, and these start and watch.
We will use the start script to start the bot and the watch one to compile the Typescript code with flag -w(atch), which will watch any changes done to the code and compile upon saving. This is how the package.json file should look like after your changes:
Now that you have set up the scripts, it is time to define the TS compiler for your project.
Create tsconfig.json in the root directory and add the following snippet to the file:
The snippet that you need to add:
We are adding experimentalDecorators, emitDecoratorMetadata, es6, and reflect-metadata because InversifyJS requires it. Once we have created this, we can create index.ts inside the src folder and run something like console.log(“Hello”) just for testing purposes.
If everything is correct, run npm run watch which should create src/index.js, and then run npm start which returns the simple message Hello.
The next step is to create a Discord app and connect a Bot to your server.
Our goal is to communicate and work with the Discord server, but before you do that you need to create a Discord bot that will connect to the server.
To create the bot, first, you need to sign in to Discord and create an application. You can do that by visiting here and clicking on the New Application button at the top right corner.
Clicking the New Application button will prompt you to the next step, where you need to choose the NAME of your application. Whenever you are ready, click Create.
Now, you should see an Application screen with the possibility to enter information about the application - you can skip it for this tutorial.
To create a bot, click Bot and then the Add Bot button. It will tell you that this action is irrevocable and ask you if you want to create a bot. After clicking Yes, do it! You will create a Discord bot. So simple, right?
A page, including the token you need, should open up on your screen right now.
To work with and later on test your bot, you need a Discord server. You need to either create a new Discord server or use an existing one. Whatever you decide, connecting will look the same.
To add the bot to your server, follow these steps:
Now that you have added a bot to the server, it is time to set up the environment in your project.
To safely provide a token to our application, we are using the dotenv package. You need to get the Bot token from the Discord Application developer dashboard. It is located at Bot > Click to Reveal Token. After you have the token, you need to safely store it in the .env file in the following way:
One more thing we need to create for the future is the .env.example file. It explains how to define the .env file. Inside of the .env.example place:
For an easier understanding of dependency injections, you should already have a *solid* knowledge of the SOLID principle. If you do, you will have no issue understanding what dependency injections are used for.
In our case, we use InversifyJS for dependency injections, and that is why we need to create our DI container in the inversify.config.ts file:
One more thing we need to do for dependency injections is to define types. This will give us the security to not have name collisions with containers. Even though it doesn’t matter that much for us in this tutorial, it is good practice to follow the clean architecture and best practices even when developing a project like this.
We will create bot.ts inside the src folder and add the following:
After this, you can add the bot to index.ts:
With this done, we have created our basic logic and we can start the project and connect the bot with the Discord server.
These are your project foundations. The next step is to develop the logic for listening and responding to messages.
Now, you need to create the logic that listens to certain types of messages and responds to them accordingly. Specifically, you want the bot to listen to two commands: !who and !roll. These two commands will make the bot introduce himself and roll one number between 1 and 100.
Then, you need to create two classes - CommandListener and CommandResponder. Do it by injecting CommandResponder into the Bot class and CommandListener into the CommandResponder. But first, we need to create command-listener.ts inside src/services.
You can inject that to command-responder.ts, which you can create inside src/services.
And then, the Bot class needs to be changed to use the CommandResponder class:
One last thing to do is creating new DI containers and types for CommandResponder and CommandListener.
Remember how you bound containers before for token, Bot, and Client classes? Now you need to do the same for CommandResponder and CommandListener.
You also need to add these two types, so that you don’t create a bug by the last addition to the inversify.config.ts. An error will occur because you used CommandResponder and CommandListener types which are not declared in types.ts.
And voila! Your Discord bot is ready to listen to your two new commands and respond to them accordingly. The only thing left to do is to restart the app and test the bot.
After testing our commands, this is the response you get:
This is the response you should expect - it shows everything works as developed.
First of all, congratulations! You just made it through the whole article and (hopefully) learned how to do a Discord bot. But you might say - OK, that's cool and all. But what can I do with it?
Well, you can play around and create more complex commands, connecting Discord to your external database or integrating Discord with some type of API (such as OMDB API or any other of the free ones). However, since I covered the basics in this article, I suggest you research larger communities and learn about all the commands and the complexity of Discord bots.
If you have any questions or ideas regarding this blog post, please feel free to reach out. And most importantly, have fun coding! :)