DEV Community

Vishnu Dileesh
Vishnu Dileesh

Posted on

Creating a Discord bot in Nodejs: Create GitHub issues from Discord Chat

A Discord bot that can help you create Github issues from the Discord chat, let's begin. Discord bots can also be created to use slash commands, which gives a better user experience.

We will be using Nodejs to build the bot while using the discord.js library. For the bot to talk to GitHub we will be using the GitHub-provided SDK Octokit. To deal with environment variables we will be using the npm package Dotenv. The Octokit SDK that will talk to GitHub needs a fetch package, for that we will be installing the package Node Fetch.

That was all about installing packages. Now we will move on to some real coding.

Create a project folder with your bot project name. And do npm init, to initialize npm.

NPM is our package manager and all the packages we talked about will be installed through npm commands.

npm install dotenv discord.js node-fetch octokit
Enter fullscreen mode Exit fullscreen mode

The above command will install the needed packages. Now visit the package.json file which was auto-generated while we did npm init. There check to see if "main" is pointing to "index.js". Also while we are in here add the line "type": "module" to enable ES6 modules.

The finished package.json will look like below.

{
  "name": "yourbotname",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
}
Enter fullscreen mode Exit fullscreen mode

Now we create another file named .env, this file will have the environment variables. The secrets that we don't want anyone to see.

Just because we talked about secrets, and if you have plans to push the code to GitHub, never push this file .env to GitHub. For that create another file named .gitignore, so that when you do git add and git commit, the .env file is ignored.

.env
Enter fullscreen mode Exit fullscreen mode

Moving on to the .env file, the file will have the following environment variables.

BOT_TOKEN=<your-bot-token-from-discord-application>
GITHUB_AUTH_TOKEN=<your-github-auth-pat-token>
Enter fullscreen mode Exit fullscreen mode

Before jumping in and creating the index.js file and getting going with coding. Let's figure out how to get BOT_TOKEN and GITHUB_AUTH_TOKEN.

First, let's dive in for the BOT_TOKEN. For that visit the Discord Developer Portal and on the Application page, click on the giant "Blurple" colored button that says New Application.

Before that if you have not turned on the Developer Mode. Please do so by clicking on the gear icon next to your username to get to the User Settings page.

There scroll a bit down while keeping an eye on the left panel items to find the one named Advanced. And then turn that Developer Mode on to become a Developer.

Now that you are a Developer and have the Developer permissions, let's continue with creating a new application.

In the pop-up appearing after clicking the New Application button while you were on the Developer Portal. Enter your dream bot project name. Select the check box and then proceed by clicking the button that says Create.

On the page that opens after the bot is created. There on the General Information page, you can beautify your bot by adding a profile picture and such.

Then move your eyes through the menu items listed under General Information on the left side panel. Then click on Bot.

While on the page, turn that Public Bot option off, if you don't want people other than you using the bot. Initially, you won't see the Token listed like in the screenshot. But then you will see the Reset Token button, click on that and proceed. And there you will have your Token displayed. Remember it's a secret, a deep secret to be kept secret. Don't ever take a screenshot of that Token post it on a blog article for the world to see.

Copy the TOKEN and paste it into your .env file corresponding to BOT_TOKEN. And keep it a secret.

BOT_TOKEN=MTE1NjQzOTgxNDQ2NDM0MDAxOQ.Gixlqs.HZlLAsfqaQdECiAgQ5v7UE3uec5eoYazliDW1M
Enter fullscreen mode Exit fullscreen mode

Then scroll a bit and under the Privileged Gateway Intents, turn on the option for Message Content Intent. This will allow your bot to see the chat message contents happening on your server.

Now again gaze your eyes through the left panel and click on OAuth2, which is above Bot on the side panel. Therein click on URL Generator, which will be in the dropdown that just opened while you clicked OAuth2.

On the screen, where a giant box of checkboxes with scops appears, click the checkmark for bot. Now that would have opened another giant box of checkboxes with Bot Permissions. Here select Administrator. (It is best practice to only provide the permissions that you really intend to use for security purposes.)

Now scrolling to a bit bottom, you will see a URL. That's the generated URL for you to invite your bot to your server. Copy and paste the URL into a new tab of your browser.

And on the page that opens select a Server of your choice in which you intend to add the bot. Click Continue. A confirmation page opens asking if you are sure about the permissions that you are giving to this newly born bot. If you are good with it, then click Authorize.

Done, there in you get a success message of your bot being added to the server. Now if you go to your Server and check the members list you will see your bot listed.

Now let's dive back into coding, the bot, and deploying it.

In the index.js file, we will start by doing the imports of the packages we installed.

import 'dotenv/config'
import { Octokit } from 'octokit'
import fetch from 'node-fetch'
import { Client, GatewayIntentBits } from 'discord.js'
Enter fullscreen mode Exit fullscreen mode

Then we will initialize both Discord client.

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent
  ]
})
Enter fullscreen mode Exit fullscreen mode

Now to do the same for Ocktokit, that is to initialize Octkokit. We need GitHub PAT (Personal Access Token)

Log in to GitHub and then click on your profile, in the menu, scroll down and select Settings. Now in on your profile page, scroll to the bottom to find the Developer Settings link. That is on the left panel, the last item.

Now you will see a page with GitHub Apps, OAuth Apps, and Personal Access Tokens.

We know what to click here, select Personal Access tokens. In the newly opened sub-menu of items under PAT, click on Tokens (Classic).

On the page, click, Generate New Token and again go for the option of Classic. Now we have to enter a note to understand why created this token when we come back in the future. Then select an expiration for the bot from the dropdown selection. Then we are to carefully select the permissions we need for the bot to work with GitHub with this newly generated access token.

Then we click on the green button at the bottom that says Generate Token.

On the next opened screen, copy your personal access token. It's a one-time thing, you won't be able to see the token again on this page. So save it in your .env, and keep it away from spying eyes. Never share it with anyone.

BOT_TOKEN=MTE1NjQzOTgxNDQ2NDM0MDAxOQ.Gixlqs.HZlLAsfqaQdECiAgQ5v7UE3uec5eoYazliDW1M
GITHUB_ACCESS_TOKEN=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
Enter fullscreen mode Exit fullscreen mode

Now that we have got Personal Access Token from GitHub, let's now initialize Octokit.

const octokit = new Octokit({
  auth: process.env.GITHUB_AUTH_TOKEN,
  request: {
    fetch
  }
})
Enter fullscreen mode Exit fullscreen mode

Here we are passing the token from our environment to the auth parameter on the initialization. And also we are setting fetch as our choice request handler for Octokit.

Now we will add a listener to know when our discord client is connected and ready to go ahead and listen for messages.

client.on("ready", () => {
  console.log(`Logged in as MyNewBot!`);
});

// we will also ! mark as our prefix to identify the message commands
const prefix = "!";
Enter fullscreen mode Exit fullscreen mode

Okay, so we have our client ready code done, which will do a console log, we have our bot token, our GitHub personal access token, and the exclamation mark as a prefix set.

We will do the on message listening to check if a message is our command to create some GitHub issues.

So how do we want the bot to work?

The message should have a prefix of !. And then the word "mybot" or something like that to identify. Let's go with "gdbot" (GitHub Discord Bot?).

And then we need arguments like repository name and issue name.

So the message will look like:

!gdbot my_repository_name issue_name_that_i_choose

client.on("messageCreate", async (msg) => {
  if (msg.author.bot) return; // if message is by a bot, ignore

  // checking if the message has a prefix to ensure it's our command
  if (!msg.content.startsWith(prefix)) return;

  // remove the prefix from the message
  const commandBody = msg.content.slice(prefix.length);

  // then we split and turn the first item to lower case
  const commands = commandBody.split(" ");

  const command = commands[0].toLocaleLowerCase();

  // other items in the message we will treat as argument
  const args = commands.slice(1);

  // !gdbot <repository name> <issue name>

  if (command === "gdbot") {
    await octokit.rest.issues
      .create({
        owner: "YourGitHubUsername",
        repo: args[0],
        title: args[1],
        body: "Issue created using my new discord bot!",
      })
      .then(async ({ data }) => {
        await msg.channel.send(
          `Issue created in ${args[0]} repository with title ${args[1]} \n
          Issue URL: ${data["html_url"]} \n
          `
        );
      })
      .catch((err) => {
        console.log(err);
      });
  }
});
Enter fullscreen mode Exit fullscreen mode

The above code, checks if the command is "gdbot". Then if it is, we proceed with creating an issue using the Octokit SDK where we will pass the owner parameter value as our GitHub username. And then the repository name as the first item in our extracted args variable. And title parameter value is the second item in the args, which is the issue name.

When the issue is created successfully our bot will send in a message in the server channel, saying the issue has been created with a link to the newly created issue.

Then below the code that does all the magic of listening to the command and creating an issue. We need to make the bot login with the bot token.

client.login(process.env.BOT_TOKEN)
Enter fullscreen mode Exit fullscreen mode

That's it we have our bot ready. Now the next part is to deploy the project to a server.

The easiest forms of deployments are through Heroku or Railway.

Full source code: GithubDiscordBot.

Top comments (0)