Create & host a Discord bot with Heroku in 5 min

pic credit to discord blog

This post I will go through how to create a discord bot and host the bot in Heroku.

What is a bot ?

On a high level, we can see bot as a user that serving as our agent in a discord server. We can ask the bot to do many things, from simple task like greeting new users with some template message, to complex ones like listen to command from other users on the server and react to them.

On a more tech side, a bot is a server running web-socket, it hook itself up to the server you add it to, receive and sending message to channels inside that server. This actually create some interesting restrictions on where we can host the bot, which I will cover later in this post.

For this post, our use case is on the complex side where we host game service online, need a bot listen to some command in the server, create play-space for players on demand etc.

Where should it live ?

The bot need to be created within Discord. Its logic however, can live wherever you want it to be. Here we gonna host the bot logic in Heroku just for the sake of simplicity.

Creating the bot in Discord itself is straight forward.

Go to discord.com/developers/applications and click on New Application.

Give it a proper name, then once it’s created, go to its Settings → Bot , where you can create a bot.

A note here is you cannot delete a bot once it’s created, because… “bots are awesome” ? 😄

What’s important here is the token, this is what you need to act as the bot later. Don’t worry you can always go back and copy it later.

Now we have a bot, we need to add this bot to a server.

Go to OAuth2, under SCOPES choose bot. Once we do that, a link will show up below, copy it to your browser.

If you are logged in to Discord and your account is admin to some server, it will show up in the drop down list, choose it, add it, done !

Note: a bot is public by default, which means we allow other servers to install the bot if their admin have our OAuth2 link. If we don’t want this, set it to private just to be safe.

Now the bot is live and well in a server, let’s see what logic we want and where to host it.

Code

our use case: listen to command play , create a play space & respond to users in the channel with ready-to-join play space.

For listening & respond part, we will need Discord.js. Get a local node.js server up, grab Discord.js from npm:

npm install discord.js

Get the client up follow what its welcome doc says is quick, putting their sample code inside index.js would just work:

const Discord = require('discord.js');
const client = new Discord.Client();

client.on('ready', () => {
console.log(`Logged in...`);
});

client.on('message', msg => {
msg.reply('pong');
});

client.login('token');

Note: the token is the bot token in the screenshot above.

Test it locally by running the node server.

node index.js

Then in the discord server we have installed the bot, notice once client.login success, the application itself will show up as an online user.

Now we would like to only listen to certain command, here take !play for example.

const prefix = `!`;
client.on("message", function (message) {
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) return;
// get channel id and command out of message
const channelId = message.channel.id;
const commandBody = message.content.slice(prefix.length);
const args = commandBody.split(" ");
const command = args.shift().toLowerCase();
if (command === 'play') {
...
// after successfully create the play space, response to the user that call this command.
message.reply(...);
}
}

We can also ask the command to take parameters, like !play game1, where game1 will be part of commandBody .

Deploy

For production, we are going to use heroku as the hosting service. To make things easier, we can use one of the sample git repo as a base: https://github.com/heroku/node-js-getting-started.git

Add what we need to its index.js should just work.

Get heroku-cli installed and configured properly (see instructions).

Create a project on heroku (single dyno would work if we don’t expect too much traffic), point local git remote heroku to where the project is, then commit & push.

git push heroku main

Done !

Reading continues ….

img cred to surge.com

Why Heroku ?

If you still remember at the beginning of this post I mentioned the nature of bot make it a bit tricky to deploy ? It is true.

Websocket requires a live connection: this means auto-create-and-destroy-on-the-fly service (like google cloud function, or amazon lambda) probably won’t work well. We need full control over how many instance of service is up and running, in our case, it’s 1 because we only install the bot to 1 server and we don’t expect too much traffic.

On GCP service close to Heroku would be App Engine, we actually get it to work on App Engine as well. However there is concern where we can’t delete App Engine once it’s created (not that it’s a killer you can still deploy no-op code to App Engine to make server sleep).

On the other hand, Heroku is such a easy-going hosting service we decide to go with it 💌

How about webhook ?

Discord.js does support webhook, however it only allow us to post message to the channel, not listen to the channel.

That’s it ! Hope it helps.

I help my team building amazing projects.