or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

audio-playback.mdaudio-reception.mddave-encryption.mdindex.mdnetworking.mdutilities.mdvoice-connections.md
tile.json

voice-connections.mddocs/

Voice Connection Management

Core functionality for establishing and managing Discord voice connections, including joining channels, handling disconnections, reconnections, and managing connection state throughout the lifecycle.

Capabilities

Join Voice Channel

Creates and establishes a connection to a Discord voice channel with comprehensive configuration options.

/**
 * Creates a VoiceConnection to a Discord voice channel
 * @param options - Configuration for joining the voice channel and connection behavior
 * @returns VoiceConnection instance for the established connection
 */
function joinVoiceChannel(options: CreateVoiceConnectionOptions & JoinVoiceChannelOptions): VoiceConnection;

interface CreateVoiceConnectionOptions {
  /** Discord gateway adapter creator function */
  adapterCreator: DiscordGatewayAdapterCreator;
  /** Whether to use DAVE protocol for end-to-end encryption (default: true) */
  daveEncryption?: boolean;
  /** Enable debug messages for connection and components (default: false) */
  debug?: boolean;
  /** Consecutive decryption failures before re-initializing encrypted session (default: 24) */
  decryptionFailureTolerance?: number;
}

interface JoinVoiceChannelOptions {
  /** Discord voice channel ID to join */
  channelId: string;
  /** Guild ID that contains the voice channel */
  guildId: string;
  /** Optional group identifier for organizing connections (default: "default") */
  group?: string;
  /** Join the channel deafened (default: true) */
  selfDeaf?: boolean;
  /** Join the channel muted (default: true) */
  selfMute?: boolean;
}

Usage Example:

import { joinVoiceChannel } from "@discordjs/voice";

// Basic voice channel join
const connection = joinVoiceChannel({
  channelId: "123456789012345678",
  guildId: "987654321098765432",
  adapterCreator: guild.voiceAdapterCreator,
});

// Advanced configuration with DAVE encryption disabled
const connection = joinVoiceChannel({
  channelId: "123456789012345678",
  guildId: "987654321098765432",
  adapterCreator: guild.voiceAdapterCreator,
  daveEncryption: false,
  debug: true,
  selfDeaf: false,
  selfMute: false,
  group: "music-bots",
});

VoiceConnection Class

Main class representing an active voice connection with full lifecycle management.

class VoiceConnection extends EventEmitter {
  /** Current connection state */
  readonly state: VoiceConnectionState;
  /** Join configuration used for this connection */
  readonly joinConfig: JoinConfig;
  /** Voice receiver for incoming audio (when connection is ready) */
  readonly receiver: VoiceReceiver;

  /** Destroy the connection permanently (cannot be reused) */
  destroy(): void;
  /** Disconnect temporarily (can be reconnected) */
  disconnect(): VoiceConnectionDisconnectReason;
  /** Rejoin voice channel with new configuration */
  rejoin(joinConfig?: JoinConfig): void;
  /** Subscribe an AudioPlayer to this connection */
  subscribe(player: AudioPlayer): PlayerSubscription;
  /** Unsubscribe the current AudioPlayer */
  unsubscribe(): void;
  /** Configure network and encryption components */
  configureNetworking(): void;
  /** Set speaking status for this connection */
  setSpeaking(speaking: boolean): void;
  /** Play an Opus audio packet directly */
  playOpusPacket(opusPacket: Buffer): void;
}

// Connection state interfaces
type VoiceConnectionState = 
  | VoiceConnectionSignallingState
  | VoiceConnectionConnectingState
  | VoiceConnectionReadyState
  | VoiceConnectionDisconnectedState
  | VoiceConnectionDestroyedState;

interface VoiceConnectionSignallingState {
  status: VoiceConnectionStatus.Signalling;
  adapter: DiscordGatewayAdapterImplementerMethods;
  subscription?: PlayerSubscription;
}

interface VoiceConnectionConnectingState {
  status: VoiceConnectionStatus.Connecting;
  adapter: DiscordGatewayAdapterImplementerMethods;  
  networking: Networking;
  subscription?: PlayerSubscription;
}

interface VoiceConnectionReadyState {
  status: VoiceConnectionStatus.Ready;
  adapter: DiscordGatewayAdapterImplementerMethods;
  networking: Networking;
  subscription?: PlayerSubscription;
}

interface VoiceConnectionDisconnectedState {
  status: VoiceConnectionStatus.Disconnected;
  adapter: DiscordGatewayAdapterImplementerMethods;
  reason: VoiceConnectionDisconnectReason;
  closeCode?: number;
  subscription?: PlayerSubscription;
}

interface VoiceConnectionDestroyedState {
  status: VoiceConnectionStatus.Destroyed;
}

Usage Example:

import { VoiceConnectionStatus, entersState } from "@discordjs/voice";

// Monitor connection state changes
connection.on("stateChange", (oldState, newState) => {
  console.log(`Connection state changed from ${oldState.status} to ${newState.status}`);
});

// Wait for connection to be ready
try {
  await entersState(connection, VoiceConnectionStatus.Ready, 30_000);
  console.log("Connection is ready!");
} catch (error) {
  console.error("Failed to connect within 30 seconds");
}

// Handle disconnections
connection.on(VoiceConnectionStatus.Disconnected, () => {
  console.log("Connection lost, attempting to reconnect...");
  connection.rejoin();
});

Connection Retrieval Functions

Functions for retrieving existing voice connections and managing connection groups.

/**
 * Retrieves an existing voice connection for a guild
 * @param guildId - Guild ID to search for
 * @param group - Optional group name (default: "default")
 * @returns VoiceConnection if found, undefined otherwise
 */
function getVoiceConnection(guildId: string, group?: string): VoiceConnection | undefined;

/**
 * Gets all voice connections for a specific group
 * @param group - Group name (default: "default")
 * @returns ReadonlyMap of guild ID to VoiceConnection
 */
function getVoiceConnections(group?: string): ReadonlyMap<string, VoiceConnection>;

/**
 * Gets all connection groups
 * @returns Map of group names to guild ID -> VoiceConnection maps
 */
function getGroups(): ReadonlyMap<string, ReadonlyMap<string, VoiceConnection>>;

Usage Example:

// Check if connection already exists
const existingConnection = getVoiceConnection("123456789012345678");
if (existingConnection) {
  console.log("Already connected to this guild");
} else {
  // Create new connection
  const connection = joinVoiceChannel({
    channelId: "123456789012345678",
    guildId: "987654321098765432", 
    adapterCreator: guild.voiceAdapterCreator,
  });
}

// Get all connections in default group
const allConnections = getVoiceConnections();
console.log(`Active connections: ${allConnections.size}`);

// Work with grouped connections
const musicBotConnections = getVoiceConnections("music-bots");
for (const [guildId, connection] of musicBotConnections) {
  console.log(`Guild ${guildId}: ${connection.state.status}`);
}

Connection Status and Reasons

Enums and interfaces defining connection states and disconnection reasons.

enum VoiceConnectionStatus {
  /** Sending gateway packets to indicate voice state change */
  Signalling = "signalling",
  /** Attempting to establish voice connection after receiving gateway packets */  
  Connecting = "connecting",
  /** Voice connection established and ready for audio */
  Ready = "ready",
  /** Voice connection severed or not established */
  Disconnected = "disconnected",
  /** Voice connection destroyed permanently and untracked */
  Destroyed = "destroyed"
}

enum VoiceConnectionDisconnectReason {
  /** WebSocket connection was closed */
  WebSocketClose,
  /** Adapter was unable to send required message */
  AdapterUnavailable,
  /** VOICE_SERVER_UPDATE packet received with null endpoint */
  EndpointRemoved,
  /** Manual disconnect was requested */
  Manual
}

Player Subscription Management

System for linking AudioPlayers to voice connections.

class PlayerSubscription {
  /** The voice connection this subscription is associated with */
  readonly connection: VoiceConnection;
  /** The audio player this subscription is associated with */
  readonly player: AudioPlayer;

  /** Remove this subscription, unlinking player from connection */
  unsubscribe(): void;
}

Usage Example:

import { createAudioPlayer } from "@discordjs/voice";

const player = createAudioPlayer();
const subscription = connection.subscribe(player);

// Later, unsubscribe when done
subscription.unsubscribe();
// or
connection.unsubscribe();

Error Handling

Voice connections can fail for various reasons. Handle errors appropriately:

connection.on("error", (error) => {
  console.error("Voice connection error:", error);
});

connection.on(VoiceConnectionStatus.Disconnected, (oldState, newState) => {
  if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
    console.error("Disconnected: Do not have permission to connect to voice channel");
  }
});