Adding Custom Commands
Relevant source files
The following files were used as context for generating this wiki page:
The TrackerBot framework utilizes Discord.js v14 to implement a modular slash command system. Adding custom commands involves a three-step process: defining the command metadata using the SlashCommandBuilder, registering the command with Discord's Global or Guild API, and implementing the execution logic within the interaction handling pipeline.
Sources: AGENTS.md, src/commands/registerSlashCommands.js:1-32
Command Architecture and Lifecycle
TrackerBot separates command definition from execution logic. Commands are registered during the bot's initialization phase and handled via a centralized interaction listener that routes incoming requests to specific handler functions.
The following sequence diagram illustrates the lifecycle of a command from registration to execution:
Command Definition
Commands are defined in src/commands/registerSlashCommands.js using the SlashCommandBuilder class. Each entry in the slashCommands array defines the name, description, and optional parameters (options) for the command.
| Element | Description | Implementation Detail |
|---|---|---|
setName | The trigger name for the command (lowercase). | Must be unique within the bot. |
setDescription | Brief explanation of the command's purpose. | Visible in the Discord UI. |
addStringOption | Defines a text input parameter. | Can be marked as required. |
Example Definition
new SlashCommandBuilder()
.setName("message")
.setDescription("Send a message as the bot (Discord Admin only)")
.addStringOption(opt =>
opt.setName("content")
.setDescription("Message content")
.setRequired(true)
)
Sources: src/commands/registerSlashCommands.js:3-23
Interaction Routing
Incoming slash commands are processed by src/handlers/interactionHandler.js, which ensures the interaction occurs within a guild before passing it to handleChatInputCommand in src/interactions/slashHandlers.js.
Permission Validation
Before executing a command, the bot checks for two levels of permissions:
- Command Role Access: Validates if the user has a role listed in
ALLOWED_COMMAND_ROLE_IDS. - Admin Role Access: Certain commands (e.g.,
/wipe,/nuke) require a "Discord Admin" role name or an ID listed inADMIN_ROLE_ID.
Sources: src/interactions/slashHandlers.js:15-30, src/config/constants.js:15-23, src/commands/wipeCommand.js:23-35
Implementation Pattern
The slashHandlers.js file contains a switch statement that maps command names to their respective handler functions. Complex commands are often exported from their own files (e.g., wipeCommand.js) to maintain readability.
Implementing Execution Logic
Command handlers are responsible for interacting with the Discord API to perform actions and provide feedback to the user via replies.
Ephemeral Replies
For administrative actions or errors, the bot uses MessageFlags.Ephemeral to ensure the response is only visible to the user who triggered the command.
Sources: src/interactions/slashHandlers.js:21-28, src/commands/nukeCommand.js:32-40
Interaction Flow (Wipe/Nuke Example)
Commands that perform destructive actions follow a confirmation pattern:
- Initial Reply: Send an ephemeral message with "Confirm" and "Cancel" buttons.
- Collector: Use
awaitMessageComponentto wait for user input within a specific timeout (e.g., 15 seconds). - Execution: Perform the action (e.g.,
bulkDeleteorchannel.clone) only if the user confirms.
Sources: src/commands/wipeCommand.js:48-95, src/commands/nukeCommand.js:70-125
Summary of Implementation Files
| File Path | Role |
|---|---|
src/commands/registerSlashCommands.js | Define metadata and sync with Discord API. |
src/interactions/slashHandlers.js | Route commands and handle simple logic. |
src/handlers/interactionHandler.js | Entry point for all Discord interactions. |
src/commands/[commandName]Command.js | (Optional) Separate file for complex logic. |
src/config/constants.js | Role-based access control definitions. |
Sources: AGENTS.md, bot.js:25-27
TrackerBot's command system is designed for safety and scalability, ensuring that destructive operations are gated behind role checks and confirmation flows while maintaining a clear separation between API registration and functional logic.