Interaction & Command Handling
Relevant source files
The following files were used as context for generating this wiki page:The Interaction and Command Handling system is the core of the bot's user-facing functionality. It is responsible for defining, deploying, and processing Discord Application (slash) Commands. The system leverages the discord.js library to listen for interaction events from Discord's gateway and routes them to the appropriate command handlers for execution.
This architecture decouples command definitions from their execution logic. Commands are defined using @discordjs/builders, registered with Discord's API, and then handled by a central listener in the main application file. This allows for a clean and scalable way to add or modify bot commands.
Sources: src/app.ts:3, 20-46, src/interactions.ts:4-11
Command Registration and Deployment
Commands are defined as SlashCommandBuilder instances and collected into an array. This array is then used to register the commands with Discord's API, making them available for users in guilds. The system supports both global and guild-specific command deployment.
Sources: src/interactions.ts:13-19
Command Definitions
Each command is built using SlashCommandBuilder from the @discordjs/builders package. This builder provides a fluent API for defining the command's name, description, and any options (like the target language in the /start command). These definitions are exported from their respective files in the src/commands/ directory.
Example of the /start command definition:
export const startCommand = new SlashCommandBuilder()
.setName('start')
.setDescription('Start the translation')
.addStringOption((option) =>
option
.setName('target')
.setDescription('Target Language')
.addChoices(...languageChoices)
.setRequired(true)
);
Sources: src/commands/start.ts:13-22
All command definitions are imported into src/interactions.ts and aggregated into a single commands array, which is then converted to JSON for the API request.
Sources: src/interactions.ts:4-19
Deployment Process
Command deployment is handled by scripts that use the @discordjs/rest module to make PUT requests to Discord's API endpoints.
- Global Deployment: The
pnpm run deployscript executessrc/deploy.ts, which callsinitGlobalCommands. This registers the commands globally for all guilds the bot is in.
Sources: package.json:12, src/deploy.ts:6-9 - Guild-Specific Deployment: On startup, if
CLIENT_IDandGUILD_IDare present in the environment variables,initGuildCommandsis called. This is useful for development and testing, as guild commands update instantly.
Sources: src/app.ts:51-57
The following diagram illustrates the command deployment flow.
This diagram shows how command definitions are collected and then pushed to the Discord API via either the global or guild-specific deployment functions.
Sources: src/interactions.ts, src/deploy.ts, src/app.ts:51-57
Interaction Lifecycle
Once commands are registered, the bot listens for interactionCreate events from the Discord Gateway. This is the entry point for all command executions.
Sources: src/app.ts:20-22
Event Listener and Router
The main application file, src/app.ts, sets up a listener on the Discord client. When an interaction is received, it first checks if it's a command. If so, it uses a switch statement on interaction.commandName to route the interaction object to the corresponding handler function.
This flow is visualized below:
This sequence shows a user executing a command, the bot receiving the event, and the central router dispatching it to the correct handler.
Sources: src/app.ts:20-46
Command Handlers
Each command has a dedicated handler function, typed as CommandHandler, which accepts the CommandInteraction object as its only argument. These handlers contain the core logic for the command, such as joining a voice channel, managing user settings, or replying to the user.
The CommandHandler type is defined as:
export type CommandHandler = (interaction: CommandInteraction) => void | Promise<void>;
Sources: src/types.ts:3
Most handlers perform the following steps:
- Validate the interaction context (e.g., ensure it's from a guild member).
- Defer the reply using
interaction.deferReply()to avoid the interaction timing out. - Execute the command's primary logic.
- Edit the original deferred reply with the result using
interaction.editReply().
Sources: src/commands/join.ts:28, 50, 84, src/commands/start.ts:24, 42
Available Slash Commands
The bot exposes several slash commands to control its functionality.
| Command | Description | Handler Source |
|---|---|---|
/join | Move the bot into your voice channel | src/commands/join.ts |
/leave | Move the bot out of your voice channel | src/commands/leave.ts |
/start <target> | Start the translation for yourself | src/commands/start.ts |
/stop | Stop the translation | src/commands/stop.ts |
/status | Show your current settings | src/commands/status.ts |
/languages | Show all available languages | src/commands/languages.ts |
Sources: src/interactions.ts:13-18, README.md:14-23
Summary
The interaction and command handling system is a robust, event-driven architecture. It clearly separates the definition of commands from their implementation. Commands are defined declaratively, registered with Discord via a REST client, and processed through a central interactionCreate event listener in app.ts. This listener acts as a router, delegating tasks to specific CommandHandler functions, which contain the business logic for each user-facing feature. This design is modular and easy to extend with new commands.
Sources: src/app.ts, src/interactions.ts