Slash Command: /start
Relevant source files
The following files were used as context for generating this wiki page:The /start command is a user-facing slash command that enables the live translation feature for the user who invokes it. Its primary purpose is to allow a user to select a target language for translation and persist this choice as a user-specific setting within the guild. This command does not initiate the voice connection or the translation process itself; rather, it "arms" the translation for the user.
The actual translation is triggered when the user speaks in a voice channel after the bot has joined via the /join command. The setting configured by /start is then retrieved to determine which language to translate the user's speech into. The translation can be disabled using the /stop command and checked with the /status command.
Command Definition
The /start command is defined using @discordjs/builders. It is registered with Discord's API along with other application commands.
- Name:
start - Description:
Start the translation
The command includes one mandatory option.
Sources: src/commands/start.ts:12-13, src/interactions.ts:13
Command Options
| Parameter | Type | Required | Description |
|---|---|---|---|
target | String | Yes | The target language for translation. Choices are populated from languages.ts. |
Sources: src/commands/start.ts:14-20
The choices for the target option are dynamically generated by mapping over the languages object, which provides a user-friendly displayName and an internal key for each supported language.
Sources: src/commands/start.ts:8-11
Execution Flow
When a user executes the /start command, the interaction is processed by the main application, which routes it to the dedicated command handler. The handler validates the input, saves the user's preference, and sends a confirmation.
The following sequence diagram illustrates the execution flow for the /start command.
This diagram shows the sequence of events from user command execution to the final confirmation message.
Sources: src/app.ts:20, 39, src/commands/start.ts:22-45
User Settings Management
The core function of the /start command is to manage a user's translation settings. This is handled by the settingsStorage utility, which persists the target language choice. The settings are stored on a per-user, per-guild basis.
State Management
The /start and /stop commands act as toggles for a user's translation state.
/start: Sets the user's state to "Active" by storing their target language./stop: Sets the user's state to "Inactive" by deleting their setting./status: Reads the current state without changing it.
The following state diagram shows the lifecycle of a user's translation setting.
This diagram illustrates how /start and /stop transition the user's translation status.
Sources: src/commands/start.ts:43, src/commands/stop.ts:16, src/commands/status.ts:16
The settingsStorage module appears to use Redis as its backend, as suggested by the REDIS_URL environment variable and the Redis service in the production Docker Compose file.
Sources: src/env.ts:17, docker-compose.prod.yml:9
Integration with the Translation Pipeline
The /start command only configures the translation; it does not activate any voice processing. The setting is consumed later by the logic initiated by the /join command.
When a user speaks in a voice channel where the bot is present, the speaking event listener in joinCommandHandler is triggered. This handler then checks if the speaking user has an active translation setting by calling settingsStorage.get(). If a setting is found, the full translation pipeline is executed for that user's speech.
The following flowchart shows this decision logic.
This diagram shows how the setting persisted by /start is used to trigger the translation pipeline.
Sources: src/commands/join.ts:85-99
Code Example: Consuming the Setting
The following snippet from join.ts demonstrates how the user's setting is retrieved and used.
// File: src/commands/join.ts
connection.receiver.speaking.on('start', async (userId) => {
if (!connection) return;
const fileName = await recordAudio(connection.receiver, userId);
if (!fileName) return;
// Retrieve the setting saved by /start
const userSettings = await settingsStorage.get(interaction.guildId as string, userId);
if (!userSettings) return; // If no setting, do nothing
const originalText = await recognizeRecording(fileName);
if (!originalText) return;
// Use the target language from the setting
const translatedText =
userSettings.target === 'en'
? originalText
: await translate(originalText, languages[userSettings.target].translatorCode);
await readText(connection, translatedText, userSettings.target);
});
Sources: src/commands/join.ts:85-102
Summary
The /start command is the entry point for a user to opt-in to the live translation service. By capturing the user's desired target language and storing it, it enables the core translation pipeline to function when the user speaks. It works in tandem with /join, which sets up the voice listeners, and /stop, which allows the user to opt-out. This separation of concerns—configuration via /start and execution via voice events—creates a clear and manageable system for handling user-specific translation preferences.