Skip to content

A template for discord bot, easy to expand, and easy to manage

Notifications You must be signed in to change notification settings

Chaoray/DiscordBotTemplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


DiscordBotTemplate

An awesome discord template to jumpstart your projects!

Getting Started

This is an example of how to use this template

Prerequisites

This project assumes that you have a passing acquaintance with these tools:

  • javascript
  • node.js
  • discord.js

Installation

  1. Clone the repo

    git clone https://github.com/Chaoray/DiscordBotTemplate.git
  2. Install packages

    npm install
  3. Enter your discord bot information in .env.
    You may have to create the .env file by yourself due to security issue.
    Here's a template, paste it to the file and fill in the blank.

    TOKEN=[Your Token Here]
    APP_ID=[Your Application ID Here]
    
  4. Deploy Commands

    npm run build

    or Press Ctrl+Shift+B if you're using VSCode

  5. Start the bot

    npm start

    or Press F5 if you're using VSCode

(back to top)

Usage

Add a new command

Here's an example of creating an echo command

Result:

  1. Go to the commands folder and add a new file.
    In this example, the filename is echo.mjs

  2. Copy-paste the following command template into the file:

    import { SlashCommandBuilder, CommandInteraction } from 'discord.js';
    
    export default {
        data: new SlashCommandBuilder()
            .setName('my-command-name')
            .setDescription('my-command-description'),
        
        /**
         * execute
         * @param {CommandInteraction} interaction 
         */
        async execute(interaction) {
        },
    };
  3. Change the name and description into whatever you like

        data: new SlashCommandBuilder()
            .setName('echo')
            .setDescription('repeat what you said'),
  4. Let's add an option

    data: new SlashCommandBuilder()
        .setName('echo')
        .setDescription('repeat what you said')
        // add the following
        .addStringOption(option =>
            option.setName('message')
                .setDescription('the message to repeat')
                .setRequired(true)),
  5. Now we can code the execute function

    /**
     * execute
     * @param {CommandInteraction} interaction 
     */
    async execute(interaction) {
        const message = interaction.options.getString('message');
        
        if (message) {
            await interaction.reply(message);
        } else {
            await interaction.reply('Sorry, I can\'t hear you.');
        }
    },

    Final Code:

    import { SlashCommandBuilder, CommandInteraction } from 'discord.js';
    
    export default {
        data: new SlashCommandBuilder()
            .setName('echo')
            .setDescription('repeat what you said')
            .addStringOption(option =>
                option.setName('message')
                    .setDescription('the message to repeat')
                    .setRequired(true)),
        
        /**
         * execute
         * @param {CommandInteraction} interaction 
         */
        async execute(interaction) {
            const message = interaction.options.getString('message');
    
            if (message) {
                await interaction.reply(message);
            } else {
                await interaction.reply('Sorry, I can\'t hear you.');
            }
        },
    };
  6. Deploy Commands

    npm run build

    or Press Ctrl+Shift+B if you're using VSCode

  7. Start the bot

    npm start
  8. You might notice that the command is nowhere to be found.
    In this regard, you can press Ctrl+R to refresh your discord to see the change.

(back to top)

Add a new command with components

The structure of commands with components is similar to normal commands.
You can check commands/ping-button.mjs as an example.

Let's create an "say my name" button.
Result:

  1. Complete the basic structure of a normal command

    import { SlashCommandBuilder, CommandInteraction } from 'discord.js';
    
    export default {
        data: new SlashCommandBuilder()
            .setName('create-say-my-name-button')
            .setDescription('Create a button that say your name'),
    
        /**
         * execute
         * @param {CommandInteraction} interaction 
         */
        async execute(interaction) {
        },
    };
  2. Add hasComponent property to inform the command loader.

    import { SlashCommandBuilder, CommandInteraction } from 'discord.js';
    
    export default {
        data: new SlashCommandBuilder()
            .setName('create-say-my-name-button')
            .setDescription('Create a button that say your name'),
    
        hasComponent: true, // add this
    
        /**
         * execute
         * @param {CommandInteraction} interaction 
         */
        async execute(interaction) {
        },
    };
  3. Create a button reply in execute, don't forget to import modules needed.

    import { SlashCommandBuilder, CommandInteraction, ButtonBuilder, ButtonStyle, ActionRowBuilder, MessageComponentInteraction } from 'discord.js';
    
    export default {
        data: new SlashCommandBuilder()
            .setName('create-say-my-name-button')
            .setDescription('Create a button that say your name'),
    
        hasComponent: true,
    
        /**
         * execute
         * @param {CommandInteraction} interaction 
         */
        async execute(interaction) {
            const sayMyName = new ButtonBuilder()
                .setCustomId('say-my-name-button')
                .setLabel('Say My Name!')
                .setStyle(ButtonStyle.Primary);
        
            const row = new ActionRowBuilder().addComponents(sayMyName);
    
            await interaction.reply({
                content: `Press it!`,
                components: [row]
            });
        },
    };
  4. Now we can add a customId field and fill it with our components' custom Ids

    import { SlashCommandBuilder, CommandInteraction, ButtonBuilder, ButtonStyle, ActionRowBuilder, MessageComponentInteraction } from 'discord.js';
    
    export default {
        data: new SlashCommandBuilder()
            .setName('create-say-my-name-button')
            .setDescription('Create a button that say your name'),
    
        hasComponent: true,
        customId: ['say-my-name-button'], // add this, the same with your button
    
        /**
         * execute
         * @param {CommandInteraction} interaction 
         */
        async execute(interaction) {
            const sayMyName = new ButtonBuilder()
                .setCustomId('say-my-name-button') // the button's custom Id
                .setLabel('Say My Name!')
                .setStyle(ButtonStyle.Primary);
        
            const row = new ActionRowBuilder().addComponents(sayMyName);
    
            await interaction.reply({
                content: `Press it!`,
                components: [row]
            });
        },
    };

    That will function as an register. When buttonInteractionCreate is triggered, we should be notified.
    If you didn't add those ids to the array, you can handle interactions in execute by yourself. (only one execution)

  5. Insert in a new function componentExecute that executes when notified.

    import { SlashCommandBuilder, CommandInteraction, ButtonBuilder, ButtonStyle, ActionRowBuilder, MessageComponentInteraction } from 'discord.js';
    
    export default {
        data: new SlashCommandBuilder()
            .setName('create-say-my-name-button')
            .setDescription('Create a button that say your name'),
    
        hasComponent: true,
        customId: ['say-my-name-button'],
    
        /**
         * execute
         * @param {CommandInteraction} interaction 
         */
        async execute(interaction) {
            const sayMyName = new ButtonBuilder()
                .setCustomId('say-my-name-button')
                .setLabel('Say My Name!')
                .setStyle(ButtonStyle.Primary);
        
            const row = new ActionRowBuilder().addComponents(sayMyName);
    
            await interaction.reply({
                content: `Press it!`,
                components: [row]
            });
        },
    
        // add the following lines
        /**
         * execute
         * @param {MessageComponentInteraction} interaction 
         * @returns 
         */
        async componentExecute(interaction) {
            if (interaction.component.customId === 'say-my-name-button') {
                return interaction.update({ content: `<@${interaction.user.id}>` });
            }
        }
        // end
    };

    Even though the componentExecute will be called when correct ids are received,
    I still recommend you to check customId.

  6. We are done! Now build and run to see the result.
    Final Code:

    import { SlashCommandBuilder, CommandInteraction, ButtonBuilder, ButtonStyle, ActionRowBuilder, MessageComponentInteraction } from 'discord.js';
    
    export default {
        data: new SlashCommandBuilder()
            .setName('create-say-my-name-button')
            .setDescription('Create a button that say your name'),
    
        hasComponent: true,
        customId: ['say-my-name-button'],
    
        /**
         * execute
         * @param {CommandInteraction} interaction 
         */
        async execute(interaction) {
            const sayMyName = new ButtonBuilder()
                .setCustomId('say-my-name-button')
                .setLabel('Say My Name!')
                .setStyle(ButtonStyle.Primary);
        
            const row = new ActionRowBuilder().addComponents(sayMyName);
    
            await interaction.reply({
                content: `Press it!`,
                components: [row]
            });
        },
    
        /**
         * execute
         * @param {MessageComponentInteraction} interaction 
         * @returns 
         */
        async componentExecute(interaction) {
            if (interaction.component.customId === 'say-my-name-button') {
                return interaction.update({ content: `<@${interaction.user.id}>` });
            }
        }
    };

(back to top)

FAQ

When to deploy commands?

Whenever the command data e.g. name, description or options is changed.
Or when a command is added / deleted.

Don't deploy on every start. It's redundant.

How to handle interactions in execute?

Please check the official tutorial: Component interactions

What is reload command?

This command can reload a command without restarting the bot, including itself.
You can add role check or id check to prevent others from using it.

About

A template for discord bot, easy to expand, and easy to manage

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published