Guide

Make a Discord bot in JavaScript

From nothing to a bot that answers slash commands in your server. You need Node.js installed and a Discord server you can add bots to.

10 minute read

1. Create the application

  1. Go to the Discord Developer Portal and press New Application.
  2. On General Information, copy the Application ID. You need it to register commands.
  3. Open Bot, press Reset Token, and copy the token. It is the bot's password; keep it private.
  4. Leave the privileged intents off for now. Only turn on Message Content Intent if your bot will read ordinary messages.

2. Invite it to your server

  1. OAuth2, then URL Generator.
  2. Tick bot and applications.commands, and under bot permissions tick Send Messages.
  3. Open the URL at the bottom and add the bot to your server.

3. Set up the project

You need Node.js 20 or newer (node -v); the current LTS release is the safe choice.

mkdir my-bot
cd my-bot
npm init -y
npm install discord.js dotenv

Create .env with the token and the Application ID:

BOT_TOKEN=paste-your-token-here
CLIENT_ID=paste-your-application-id-here

If you use Git, put .env and node_modules/ in .gitignore before your first commit.

4. Define the commands

Create commands.js, the one place your commands are described:

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

module.exports = [
  new SlashCommandBuilder().setName("hello").setDescription("Say hello"),
  new SlashCommandBuilder()
    .setName("roll")
    .setDescription("Roll a die")
    .addIntegerOption((o) => o.setName("sides").setDescription("How many sides").setMinValue(2)),
];

5. Register them with Discord

Create deploy-commands.js:

require("dotenv").config();
const { REST, Routes } = require("discord.js");
const commands = require("./commands");

const rest = new REST().setToken(process.env.BOT_TOKEN);

rest
  .put(Routes.applicationCommands(process.env.CLIENT_ID), { body: commands.map((c) => c.toJSON()) })
  .then((data) => console.log(`Registered ${data.length} commands`))
  .catch(console.error);
node deploy-commands.js

Run this again whenever you add or change a command. Not on every start: Discord limits how many commands you can create a day.

6. Write the bot

Create index.js:

require("dotenv").config();
const { Client, Events, GatewayIntentBits } = require("discord.js");

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

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

client.on(Events.InteractionCreate, async (interaction) => {
  if (!interaction.isChatInputCommand()) return;

  if (interaction.commandName === "hello") {
    await interaction.reply(`Hello, ${interaction.user}!`);
  }

  if (interaction.commandName === "roll") {
    const sides = interaction.options.getInteger("sides") ?? 6;
    await interaction.reply(`You rolled ${1 + Math.floor(Math.random() * sides)}`);
  }
});

client.login(process.env.BOT_TOKEN);

Add a start script to package.json so it is one command to run, here and on any host:

"scripts": {
  "start": "node index.js"
}

dotenv reads .env when there is one and does nothing when there is not, so the same code works on a host that provides the token another way. (Node's own --env-file=.env flag stops with an error if the file is missing, which is a common surprise after deploying.)

7. Run it

npm start

You should see Logged in as and the bot turns green. Type / in your server and use /hello. If the commands are not listed, reload Discord with Ctrl+R.

If it did not work

  • TokenInvalid: An invalid token was provided: the token is wrong, or BOT_TOKEN is not set. Check .env is in the folder you ran the command from and the line is spelt exactly BOT_TOKEN=.
  • Cannot find module 'dotenv': run npm install dotenv in the project folder.
  • Used disallowed intents: your code asks for an intent that is switched off in the Developer Portal.
  • Commands never appear: the deploy script did not run, CLIENT_ID is wrong, or the invite link was missing applications.commands.

Where to go next

SnowServers runs discord.js bots from $3 a month with a 7-day free trial. Push this folder to GitHub (without .env), paste the repository link and your token into the panel, and npm start runs on its own.