Developer
Handlers
Command Handler

Command Handler

A command handler in a Discord bot is responsible for processing and executing commands received from users. It helps in organizing the command logic, making it easier to manage and extend. By using a command handler, you can separate the command definitions from the execution logic, ensuring that each command is handled appropriately based on the user's input.

Project Structure

Create a folder named handlers inside the src folder, and then create a file named commandHandler.ts.

      • commandHandler.ts
  • Create commandHandler.ts

    This file will contain the logic of the command handler. It supports both message and interaction commands.

    src/handlers/commandHandler.ts
    import { Collection } from 'discord.js'
    import { readdirSync, statSync } from 'fs'
    import { join } from 'path'
    import { Command } from '../interfaces/Command'
    import { ExtendedClient } from '../interfaces/ExtendedClient'
    import { logger } from '../utils/logger'
     
    export const commandHandler = (client: ExtendedClient) => {
      client.slashCommands = new Collection()
      client.messageCommands = new Collection()
     
      const loadSlashCommands = (dir: string) => {
        const files = readdirSync(dir)
     
        for (const file of files) {
          const filePath = join(dir, file)
          const fileStat = statSync(filePath)
     
          if (fileStat.isDirectory()) {
            loadSlashCommands(filePath)
          } else if (file.endsWith('.js') || file.endsWith('.ts')) {
            const command: Command = require(filePath).default
            if (typeof command.executeSlash === 'function') {
              client.slashCommands.set(command.name, command)
              logger.log(`Slash command loaded: ${command.name} from ${filePath}`)
            }
          }
        }
      }
     
      const loadMessageCommands = (dir: string) => {
        const files = readdirSync(dir)
     
        for (const file of files) {
          const filePath = join(dir, file)
          const fileStat = statSync(filePath)
     
          if (fileStat.isDirectory()) {
            loadMessageCommands(filePath)
          } else if (file.endsWith('.js') || file.endsWith('.ts')) {
            const command: Command = require(filePath).default
            if (typeof command.executeMessage === 'function') {
              client.messageCommands.set(command.name, command)
              logger.log(`Message command loaded: ${command.name} from ${filePath}`)
            } else {
              logger.error(
                `Message command ${command.name} does not have executeMessage function defined`,
              )
            }
          }
        }
      }
     
      loadSlashCommands(join(__dirname, '../commands/slashCommands'))
      loadMessageCommands(join(__dirname, '../commands/messageCommands'))
     
      logger.sLog('All commands loaded')
      client.slashCommands.forEach((command, name) => logger.log(`Loaded slash command: ${name}`))
      client.messageCommands.forEach((command, name) => logger.log(`Loaded message command: ${name}`))
    }

    Verification

    Ensure that your commands are correctly imported from your command interface.

    Alright, now let's go further!