Utility Functions
Relevant source files
The following files were used as context for generating this wiki page:The discord-live-translator bot relies on a collection of utility functions and classes, primarily located in the src/utils/ directory, to handle cross-cutting concerns. These utilities provide shared, reusable logic for tasks such as logging, audio playback management, user settings persistence, event telemetry, and type checking. Encapsulating this logic into dedicated modules promotes code reuse and separation of concerns, simplifying the core application and command handling logic.
This document outlines the architecture and functionality of these key utilities, including how they are configured and used throughout the application.
Logging (writeToLog)
A simple logging utility is implemented to provide standardized, timestamped output to the console and, optionally, to a log file.
Sources: src/utils/writeToLog.ts, src/app.ts:5, src/env.ts:11
Logic Flow
The writeToLog function takes any number of string arguments, joins them into a single message, prepends an ISO timestamp, and logs it to the console. If the LOG_PATH environment variable is set, it will also asynchronously append the message to the specified file.
This diagram shows the conditional logic for writing log messages to a file.
Sources: src/utils/writeToLog.ts:6-16
Configuration
The file logging behavior is controlled by the LOG_PATH environment variable.
| Variable | Description | Type |
|---|---|---|
LOG_PATH | Optional. The relative or absolute path to the log file. | string |
Sources: src/env.ts:11, src/utils/writeToLog.ts:10-12
Audio Management (AudioQueue)
The AudioQueue class is responsible for managing the playback of text-to-speech (TTS) audio files in a voice channel. It ensures that audio clips are played sequentially for each channel, preventing overlap.
Sources: src/utils/AudioQueue.ts, src/commands/join.ts:80, src/commands/leave.ts:46
Architecture
The system is composed of the AudioQueue singleton and a PlayerPool which manages AudioPlayer instances for each guild. AudioQueue maintains a map of queues, where each key is a channel ID and the value is an array of audio file paths. A Set (playingIn) tracks which channels are currently active to prevent multiple concurrent playback streams in the same channel.
This diagram illustrates the structure of the AudioQueue class and its relationship with PlayerPool.
Sources: src/utils/AudioQueue.ts
Core Methods
| Method | Description |
|---|---|
init(connection) | Gets or creates an AudioPlayer for the guild and subscribes the VoiceConnection to it. |
play(connection, audioUrl) | Adds an audio file to the queue for the connection's channel and starts playback if not already playing. |
add(channelId, audioUrl) | Adds an audio file path to the queue for a specific channel ID. |
stop(connection) | Clears the queue for the connection's channel and stops the current audio player. |
Sources: src/utils/AudioQueue.ts:7-66
Playback Sequence
When audioQueue.play() is called, it adds the audio file to the queue and then checks if playback is already active in that channel. If not, it initiates the playFromQueue loop, which plays the next item from the queue and recursively calls itself when the current track finishes.
This diagram shows the sequence of events when a new audio file is played via the AudioQueue.
Sources: src/utils/AudioQueue.ts:49-55, src/utils/AudioQueue.ts:29-47
User Settings (settingsStorage)
User settings, specifically the target language for translation, are managed by settingsStorage. While the source file is not provided in full, its usage across command files reveals its public interface and likely implementation. It appears to function as a key-value store, mapping a user's ID within a guild to their chosen language.
Sources: src/commands/start.ts:29, src/commands/status.ts:16, src/commands/stop.ts:15, src/env.ts:15
Interface
Based on its usage, settingsStorage exposes the following asynchronous methods:
| Method | Description |
|---|---|
get(guildId, userId) | Retrieves the settings for a specific user in a guild. |
set(guildId, userId, targetLanguage) | Sets the target language for a user in a guild. |
delete(guildId, userId) | Removes the settings for a user in a guild. |
Data Flow
Commands like /start, /status, and /stop interact with settingsStorage to manage a user's translation state. The presence of a REDIS_URL in the environment configuration strongly suggests that Redis is the backing data store.
This diagram illustrates how the /start command uses settingsStorage to persist a user's target language, likely in Redis.
Sources: src/commands/start.ts:29, src/env.ts:15
Type Guards (is.ts)
The project uses type guard functions to help TypeScript narrow down types for better type safety, particularly with Discord.js objects.
Sources: src/commands/join.ts:15, src/commands/leave.ts:12
isGuildMember
The isGuildMember function is a user-defined type guard. It checks if an interaction.member object is an instance of GuildMember, which contains properties and methods specific to a server context (like voice.channel), as opposed to the more generic APIInteractionGuildMember. This is crucial for commands that operate within a voice channel.
Its usage can be seen in commands that require access to the member's voice state.
// From src/commands/join.ts
if (!interaction.member || !isGuildMember(interaction.member) || !interaction.guild) {
// ...
}
// After this check, `interaction.member` is known to be of type `GuildMember`
if (!interaction.member.voice.channel) {
// ...
}
Sources: src/commands/join.ts:15-20
Telemetry
The application includes a telemetry utility to track events, such as command usage, using PostHog. This is handled by trackEvent and flushEvents functions.
Sources: src/app.ts:16-27, src/app.ts:80-83, src/env.ts:12-14
Event Tracking
The trackEvent function is called whenever a command interaction is received. It sends an event payload containing the user ID, guild ID, and command name to a PostHog instance if configured. The flushEvents function is called during graceful shutdown (SIGTERM, SIGINT) to ensure all buffered events are sent before the process exits.
This diagram shows the flow for tracking an event during runtime and flushing the event queue on shutdown.
Sources: src/app.ts:16-27, src/app.ts:80-83
Configuration
Telemetry is configured via environment variables.
| Variable | Description | Type | Default |
|---|---|---|---|
POSTHOG_API_KEY | The API key for the PostHog project. | string | (optional) |
POSTHOG_HOST | The URL of the PostHog instance. | string | https://app.posthog.com |
Sources: src/env.ts:12-14