DEV Community

Robert
Robert

Posted on • Updated on

How to create a discord bot with discord.js and node.js

cryptocurrency-discord-bot

A cryptocurrency discord bot made with Node, discord.js and coingecko API
In this post we will learn how to create a cryptocurrency Discord bot to obtain the values of the cryptocurrency we want to know using Coingecko API.

To make this post I used the same example from my other post How to make a Cryptocurrency Telegram bot with Node and Telegraf.

You can contact me by telegram if you need to hire a Full Stack developer or if you need a discord bot for your server.

You can also find me on discord as Appu#9136.

You can clone the repo if you want..

Prerequisites

  • Node.js installed
  • you will need a Discord account

Creating Our Project

  1. open your terminal and type the following
  2. mkdir discord-cryptocurrency-bot
  3. cd discord-cryptocurrency-bot
  4. npm init --y
  5. code .

Dependencies

To install dependencies go to your project folder open a terminal and type the following.

npm i axios dotenv discord.js
Enter fullscreen mode Exit fullscreen mode

Now go to your package.json and add this.

  "scripts": {
    "start": "node ./src index.js"
  },
Enter fullscreen mode Exit fullscreen mode

Project File Structure

discord-cryptocurrency-bot/
├── node_modules/
├── src/
│ └── index.js
├── .env
└── package.json

Table of Contents.

  1. Creating our own discord server
  2. Creating our bot and adding it to our server
  3. Coding our Bot
  4. Creating the bot commands
  5. Deploying it to Heroku
  6. Conclusion

1. Creating our own discord server

In order to test our bot we need to create a server, this step is easy, just open your discord and click the + on the left panel, it will show a window with the create my own option, click it, and for this example select for my and my friends.

New server button

create server option

After create your server, go and click the wheel icon to open the user settings, go to app settings and click Advanced, now activate the developer mode.

Developer mode

2. Creating our bot and adding it to our server

Now open your browser and go to Discord Developer Portal be sure to be in the Applications tab, and click the New Application button, it will show a modal where you can choose a name for your new application.

Create a new discord application

Now in the left panel click on Bot, then click on add bot, here you can set a name and an icon for your bot, below the name will be the token, copy and save it in a .txt file by the moment.

bot tab

Image description

Now scroll down to Privileged Gateway Intents, here we will check some intents to be able to interact with our bot.

discord intents

Now go to OAuth2 -> URL Generator, there will be a panel with the SCOPES label, check the bot scope, then a url will be generated, copy it, open a new tab and paste it, you will see something similar to the image below, select your server and then click the Authorize button.

oauth tab

adding the bot

Finally the bot is in the server and we can start coding it.

bot in the server

3. Coding our Bot

Let's start coding our bot, first let's create a .env file in our project root folder, lets add a BOT_TOKEN var and assign it the token we saved earlier in the previous section.

BOT_TOKEN = paste-the-token-here
Enter fullscreen mode Exit fullscreen mode

Now in our index.js, import discord.js, axios and dotenv

const axios = require("axios");
const Discord = require("discord.js");
require("dotenv").config();
Enter fullscreen mode Exit fullscreen mode

Then create a client object from Discord Class using the Client constructor, we need to pass the intents like this.

const client = new Discord.Client({
  intents: [
    "GUILDS",
    "GUILD_MEMBERS",
    "GUILD_MESSAGES",
    "GUILD_MESSAGE_REACTIONS",
  ],
});
Enter fullscreen mode Exit fullscreen mode

Now we are going to make our bot online by using the login method and add a event listener, so that when the bot is ready it will pass a message through the console.

client.on("ready", () => {
  console.log(`Hello my name is ${client.user.tag}!`);
});

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

You should receive a message similar to this one.

Hello my name is cryptocurrency-bot#0235!
Enter fullscreen mode Exit fullscreen mode

Bot online

4. Creating the bot commands

For this example I will create only three commands, !help command to get all the available commands, a !currencies command to get all the supported currencies and a !crypto_price to get the price of the selected cryptocurrency in the desired currency.

  • So let's start creating our !help command.

Let's use our client object with the event listener, it will be listening for messageCreate event that will be emitted whenever a message is created, and we are going to use async/await because we are going to make some HTTP requests to the Coingecko API.

Please be sure to read the documentation from discord.js and discord.

With msg.content we can get what the text that the user sent, if the message is equals to !help then we will answer the user with the commands and a description of each one.

Embeds are a way to format our messages, you can read about it in the documentation

client.on("messageCreate",  async (msg) => {
  if(msg.content === '!help'){
    const embed1 = new Discord.MessageEmbed()
      .setTitle("Command list")
      .setDescription(
        '**!help** - shows the command list \n\n' +
        '**!currencies** to get all the suppported currencies. \n\n' +
        '**!crypto_price** *<currencies>* *<cryptocurrencies>* to get the value of the cryptocurrency in another currency, to use it first type the **currency** and then the **cryptocurrency** e.g. (**!crypto_price usd bitcoin**), can also add more currencies and cryptos separating them with commas but without spaces e.g. (**!crypto_price usd,eur,btc bitcoin,ethereum**) \n\n'
      );

    msg.channel.send({ embeds: [embed1] });
  }
});
Enter fullscreen mode Exit fullscreen mode

Now if you try the !help command you should get something similar to this:

help command

  • Now let's create our !currencies command

Let's go back to our code and instead of if block lets create a switch block with the msg.content like this, and by the moment we are going to send !currencies command message when the user enters the !currencies command:

client.on("messageCreate",  async (msg) => {

  switch (msg.content) {
    case "!help" || "!commands":
      const embed1 = new Discord.MessageEmbed()
      .setTitle("Command list")
      .setDescription(
        '**!help** or **!commands** - shows the command list \n\n' +
        '**!currencies** to get all the suppported currencies. \n\n' +
        '**!crypto_price** *<currencies>* *<cryptocurrencies>* to get the value of the cryptocurrency in another currency, to use it first type the **currency** and then the **cryptocurrency** e.g. (**!crypto_price usd bitcoin**), can also add more currencies and cryptos separating them with commas but without spaces e.g. (**!crypto_price usd,eur,btc bitcoin,ethereum**) \n\n'
      );

    msg.channel.send({ embeds: [embed1] });
      break;
    case "!currencies":

      break;
  }
});
Enter fullscreen mode Exit fullscreen mode

Let's code our !currencies command, delete this line msg.channel.send('!currencies command'), and first lets make a GET request to the coingecko API and retrieve the supported currencies.

I used the map method to return each currency in italic and assign it to a constant named currencies, and created a new embed

  const res = await axios.get("https://api.coingecko.com/api/v3/simple/supported_vs_currencies");

  const currencies = res.data.map((currency) => `*${currency}*`)

  const embed2 = new Discord.MessageEmbed()
    .setTitle("Supported Currencies")
    .setDescription(currencies.join(", "))
    .setColor("#0099ff")
    .setFooter("Powered by CoinGecko");

  msg.channel.send({ embeds: [embed2] });
Enter fullscreen mode Exit fullscreen mode

If you try the command you will get this.

!currencies

Finally we will create the !crypto_price command.

For this one as a user we will send a message like this !crypto_price usd,eur bitcoin, so we will split the string by spaces with .split(' '). This should split the string into three parts, the first part will be the !crypto_price, second part usd,eur and third part bitcoin, so we will create two variables currencies and cryptoCurrencies, then we will assign the values respectively.

But to be able to get the words after !crypto_price we should use msg.content.startsWith("!crypto_price") otherwise we won't get the next words and the command won't work.

So before our switch block we will use an if block, if the message starts with !crypto_price then we will execute our command:

client.on("messageCreate",  (msg) => {
  if (msg.content.startsWith("!crypto_price")) {

  } else {
    switch (msg.content) {
     .
     .
     .
    }
  }
});
Enter fullscreen mode Exit fullscreen mode

So let's get currencies and the cryptoCurrencies by splitting the string.

We need to create a conditional in case the user enters the data incorrectly, or in case the user does not send any data in the command. if this is the case we need to send the user a message, in this case I want the user to remember how to use the command so I added an example.

Now we are going to make the GET request to the API, we also going to check if the object from the response is empty, if it's empty it's because there was a spelling error, or some of the data was misplaced. If this is the case we will answer again telling the user how to use the command.

We are getting the data like this.

data: {
    bitcoin: { usd: 21816, eur: 20872 },
    ethereum: { usd: 1177.46, eur: 1126.54 }
  }
Enter fullscreen mode Exit fullscreen mode

So I chose to use a for loop inside another for loop to manipulate the data, then used an embed again to format the text.

if (msg.content.startsWith("!crypto_price")) {
  const currencies = msg.content.split(" ")[1];
  const cryptoCurrencies = msg.content.split(" ")[2];

  if (cryptoCurrencies === undefined || currencies === undefined) {
    const embed = new Discord.MessageEmbed()
      .setTitle("Error")
      .setDescription("Please provide a currency and a cryptocurrency, remember to separate them with commas but without spaces e.g. (!crypto_price usd,eur bitcoin,ethereum)")
      .setColor("#ff0000");

    msg.channel.send({ embeds: [embed] });
    return
  }

  axios.get( `https://api.coingecko.com/api/v3/simple/price?ids=${cryptoCurrencies}&vs_currencies=${currencies}`)
  .then((res) => {
    if (res) {

      //if res is empty
      if(Object.keys(res.data).length === 0) {
        const embed = new Discord.MessageEmbed()
        .setTitle("Error")
        .setDescription("Please enter the **currency** and the **cryptocurrency** you want to convert to, remember to separate them with commas but without spaces e.g. (*!crypto_price usd,eur,btc bitcoin,ethereum*).")
        .setColor("#ff0000");

        msg.channel.send({ embeds: [embed] });
      }

      const response = res.data;

      for (let cryptoCurrency in response) {
        for (let currency in response[cryptoCurrency]) {
          const embed = new Discord.MessageEmbed()
          .setDescription(`**${cryptoCurrency}** price in **${currency.toUpperCase()}** ➡️ ${response[cryptoCurrency][currency]}`)

          msg.channel.send({ embeds: [embed] });
        }
      }
    }
  })
}
Enter fullscreen mode Exit fullscreen mode

If you try !crypto_price command, you should get something like this.

!crypto_price command

5. Deploying it to Heroku

  • we need to create a server

In case you want to deploy this app, we need to create a server, so let's install express with this command npm i express and create a server in our index.js.

Remember to create a port constant and assign this process.env.PORT to it (Heroku will give us a port value).

const express = require('express')

//initialization
const app = express()

const port = process.env.PORT || 3000;

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
})
Enter fullscreen mode Exit fullscreen mode
  • Create an account

This is an easy step, just go to Heroku and click on sign up.

Heroku sign up

Fill the required fields and verify your account, then login and go to your apps and create a new one.

creating our app

Choose a name for your new app and continue to the next part.

  • Install Heroku CLI

We are not going to ad a pipeline, so we can skip that part. Now for the deployment method I will use Heroku CLI.

Heroku cli

I will use npm install -g heroku to install it, then we need to open a terminal and type heroku cli, and you will see this message.

CLI message

Now let's login by clicking the button in our browser.

heroku Login button

  • Deploy.

Now lets follow the steps below, replace master by main or won't let you git push.

deployment main -> master

6. Conclusion

We learned how to make a cryptocurrency discord bot using discord.js and node.js.

I really hope you have been able to follow the post without any trouble, otherwise I apologize, please leave me your doubts or comments.

You can contact me by telegram if you need to hire a Full Stack developer..

You can also find me on discord as Appu#9136.

You can clone the repo if you want.

Thanks for your time.

Top comments (0)