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

networking.mddocs/

Low-Level Networking

Direct access to networking components for advanced use cases, including WebSocket and UDP socket management, protocol handling, connection state control, and low-level Discord voice protocol implementation.

Capabilities

Networking Manager

Core networking class that manages the complete Discord voice connection lifecycle.

/**
 * Manages Discord voice connection networking including WebSocket and UDP components
 */
class Networking extends EventEmitter {
  /** Current networking state */
  readonly state: NetworkingState;

  /**
   * Create a new networking instance
   * @param connectionOptions - Discord voice connection configuration
   * @param options - Additional networking options
   */
  constructor(connectionOptions: ConnectionOptions, options: NetworkingOptions);

  /** Destroy the networking instance and all components */
  destroy(): void;

  /**
   * Prepare an Opus audio packet for transmission
   * @param opusPacket - Raw Opus audio data
   * @returns Prepared packet buffer or undefined if not ready
   */
  prepareAudioPacket(opusPacket: Buffer): Buffer | undefined;

  /** 
   * Dispatch previously prepared audio packet
   * @returns true if packet was sent successfully
   */
  dispatchAudio(): boolean;

  /**
   * Set speaking status for this connection
   * @param speaking - Whether currently speaking/sending audio
   */
  setSpeaking(speaking: boolean): void;
}

interface ConnectionOptions {
  /** Voice channel ID */
  channelId: string;
  /** Discord voice server endpoint */
  endpoint: string;
  /** Voice server ID */
  serverId: string;
  /** Voice session ID from gateway */
  sessionId: string;
  /** Voice connection token from gateway */
  token: string;
  /** Bot user ID */
  userId: string;
}

interface NetworkingOptions {
  /** Enable DAVE end-to-end encryption (default: true) */
  daveEncryption?: boolean;
  /** Enable debug logging (default: false) */
  debug?: boolean;
  /** Decryption failure tolerance for DAVE (default: 24) */
  decryptionFailureTolerance?: number;
}

Usage Example:

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

// Create networking instance (typically done internally by VoiceConnection)
const networking = new Networking(
  {
    channelId: "123456789012345678",
    endpoint: "discord-voice-server.discord.gg",
    serverId: "server-id-here",
    sessionId: "session-id-here", 
    token: "voice-token-here",
    userId: "bot-user-id-here",
  },
  {
    daveEncryption: true,
    debug: true,
    decryptionFailureTolerance: 24,
  }
);

// Monitor networking state
networking.on("stateChange", (oldState, newState) => {
  console.log(`Networking: ${oldState.code} -> ${newState.code}`);
});

// Prepare and send audio
const opusPacket = Buffer.from(/* opus audio data */);
const preparedPacket = networking.prepareAudioPacket(opusPacket);
if (preparedPacket) {
  networking.dispatchAudio();
}

Networking States

Comprehensive state management for voice connection lifecycle.

enum NetworkingStatusCode {
  /** Opening WebSocket connection to voice gateway */
  OpeningWs,
  /** Identifying with voice gateway */
  Identifying,
  /** Performing UDP handshake for audio transmission */
  UdpHandshaking, 
  /** Selecting voice protocol and encryption */
  SelectingProtocol,
  /** Ready for audio transmission and reception */
  Ready,
  /** Resuming existing voice connection */
  Resuming,
  /** Connection closed */
  Closed
}

type NetworkingState = 
  | NetworkingOpeningWsState
  | NetworkingIdentifyingState
  | NetworkingUdpHandshakingState
  | NetworkingSelectingProtocolState
  | NetworkingReadyState
  | NetworkingResumingState
  | NetworkingClosedState;

interface NetworkingOpeningWsState {
  code: NetworkingStatusCode.OpeningWs;
  ws: VoiceWebSocket;
  connectionOptions: ConnectionOptions;
}

interface NetworkingIdentifyingState {
  code: NetworkingStatusCode.Identifying;
  ws: VoiceWebSocket;
  connectionOptions: ConnectionOptions;
}

interface NetworkingUdpHandshakingState {
  code: NetworkingStatusCode.UdpHandshaking;
  ws: VoiceWebSocket;
  udp: VoiceUDPSocket;
  connectionData: ConnectionData;
  connectionOptions: ConnectionOptions;
}

interface NetworkingSelectingProtocolState {
  code: NetworkingStatusCode.SelectingProtocol;
  ws: VoiceWebSocket;
  udp: VoiceUDPSocket;
  connectionData: ConnectionData;
  connectionOptions: ConnectionOptions;
}

interface NetworkingReadyState {
  code: NetworkingStatusCode.Ready;
  ws: VoiceWebSocket;
  udp: VoiceUDPSocket;
  connectionData: ConnectionData;
  connectionOptions: ConnectionOptions;
  preparedPacket?: Buffer;
  dave?: DAVESession;
}

interface NetworkingResumingState {
  code: NetworkingStatusCode.Resuming;
  ws: VoiceWebSocket;
  udp: VoiceUDPSocket;
  connectionData: ConnectionData;
  connectionOptions: ConnectionOptions;
  preparedPacket?: Buffer;
  dave?: DAVESession;
}

interface NetworkingClosedState {
  code: NetworkingStatusCode.Closed;
}

Voice WebSocket

WebSocket wrapper for Discord voice gateway communication.

/**
 * WebSocket wrapper for Discord voice gateway
 */
class VoiceWebSocket extends EventEmitter {
  /** Last recorded ping in milliseconds */
  ping?: number;
  /** Last acknowledged sequence number */
  sequence: number;

  /**
   * Create voice WebSocket connection
   * @param address - WebSocket address to connect to
   * @param debug - Enable debug logging
   */
  constructor(address: string, debug: boolean);

  /** Destroy the WebSocket connection */
  destroy(): void;

  /**
   * Handle incoming message from WebSocket
   * @param event - WebSocket message event
   */
  onMessage(event: MessageEvent): void;

  /**
   * Send JSON packet to voice gateway
   * @param packet - Voice gateway payload to send
   */
  sendPacket(packet: VoiceSendPayload): void;

  /**
   * Send binary message to voice gateway
   * @param opcode - Voice opcode for the message
   * @param payload - Binary payload data
   */
  sendBinaryMessage(opcode: VoiceOpcodes, payload: Buffer): void;

  /**
   * Set or clear heartbeat interval
   * @param ms - Heartbeat interval in milliseconds, or -1 to clear
   */
  setHeartbeatInterval(ms: number): void;
}

// Voice WebSocket Events
interface VoiceWebSocket extends EventEmitter {
  /** Emitted when connection encounters an error */
  on(event: "error", listener: (error: Error) => void): this;
  /** Emitted when WebSocket connection opens */
  on(event: "open", listener: () => void): this;
  /** Emitted when WebSocket connection closes */
  on(event: "close", listener: (code: number, reason: string) => void): this;
  /** Emitted for debug messages */
  on(event: "debug", listener: (message: string) => void): this;
  /** Emitted when JSON packet is received */
  on(event: "packet", listener: (packet: VoiceReceivePayload) => void): this;
  /** Emitted when binary message is received */
  on(event: "binary", listener: (message: BinaryWebSocketMessage) => void): this;
}

interface BinaryWebSocketMessage {
  op: VoiceOpcodes;
  payload: Buffer;
  seq: number;
}

Usage Example:

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

const ws = new VoiceWebSocket("wss://voice-gateway.discord.gg", true);

ws.on("open", () => {
  console.log("Voice WebSocket connected");
});

ws.on("packet", (packet) => {
  console.log("Received packet:", packet.op);
});

ws.on("close", (code, reason) => {
  console.log(`WebSocket closed: ${code} - ${reason}`);
});

// Send identify packet
ws.sendPacket({
  op: VoiceOpcodes.Identify,
  d: {
    server_id: "server-id",
    user_id: "user-id", 
    session_id: "session-id",
    token: "voice-token",
  },
});

Voice UDP Socket

UDP socket manager for audio packet transmission.

/**
 * UDP socket for Discord voice audio transmission
 */
class VoiceUDPSocket extends EventEmitter {
  /** Deprecated ping measurement */
  ping?: number;

  /**
   * Create UDP socket connection to Discord voice server
   * @param remote - Remote socket configuration (IP and port)
   */
  constructor(remote: SocketConfig);

  /**
   * Send buffer to Discord voice server
   * @param buffer - Audio or control data to send
   */
  send(buffer: Buffer): void;

  /** Close the UDP socket */
  destroy(): void;

  /**
   * Perform IP discovery to determine external IP and port
   * @param ssrc - SSRC identifier for this connection
   * @returns Promise resolving to discovered socket configuration
   */
  performIPDiscovery(ssrc: number): Promise<SocketConfig>;
}

interface SocketConfig {
  /** IP address */
  ip: string;
  /** Port number */
  port: number;
}

/**
 * Parse IP discovery response packet
 * @param message - Response buffer from IP discovery
 * @returns Parsed socket configuration
 */
function parseLocalPacket(message: Buffer): SocketConfig;

// Voice UDP Socket Events
interface VoiceUDPSocket extends EventEmitter {
  /** Emitted when socket encounters an error */
  on(event: "error", listener: (error: Error) => void): this;
  /** Emitted when socket is closed */
  on(event: "close", listener: () => void): this;
  /** Emitted for debug messages */
  on(event: "debug", listener: (message: string) => void): this;
  /** Emitted when message is received */
  on(event: "message", listener: (message: Buffer) => void): this;
}

Usage Example:

import { VoiceUDPSocket, parseLocalPacket } from "@discordjs/voice";

const udp = new VoiceUDPSocket({ ip: "162.159.130.1", port: 50001 });

udp.on("message", (message) => {
  console.log("Received UDP message:", message.length, "bytes");
});

// Perform IP discovery
const ssrc = 12345;
const localConfig = await udp.performIPDiscovery(ssrc);
console.log("Discovered local IP:", localConfig.ip, "port:", localConfig.port);

// Send audio packet
const audioPacket = Buffer.from(/* encrypted audio data */);
udp.send(audioPacket);

Connection Data

Runtime connection information and state data.

interface ConnectionData {
  /** Set of connected client user IDs */
  connectedClients: Set<string>;
  /** Voice encryption mode being used */
  encryptionMode: string;
  /** Current nonce for encryption */
  nonce: number;
  /** Nonce buffer for encryption operations */
  nonceBuffer: Buffer;
  /** Number of audio packets sent */
  packetsPlayed: number;
  /** Encryption secret key */
  secretKey: Uint8Array;
  /** RTP sequence number */
  sequence: number;
  /** Current speaking status */
  speaking: boolean;
  /** SSRC identifier for this connection */
  ssrc: number;
  /** RTP timestamp */
  timestamp: number;
}

/** Supported voice encryption modes */
const SUPPORTED_ENCRYPTION_MODES: VoiceEncryptionMode[];

Advanced Usage

Custom Networking Implementation

For advanced use cases, you can implement custom networking behavior:

import { Networking, NetworkingStatusCode } from "@discordjs/voice";

class CustomNetworking extends Networking {
  constructor(connectionOptions, options) {
    super(connectionOptions, options);
    
    // Override state change handling
    this.on("stateChange", (oldState, newState) => {
      if (newState.code === NetworkingStatusCode.Ready) {
        console.log("Custom networking ready for audio");
        this.setupCustomAudioProcessing();
      }
    });
  }

  prepareAudioPacket(opusPacket) {
    // Custom packet preparation logic
    const prepared = super.prepareAudioPacket(opusPacket);
    if (prepared) {
      // Add custom headers or processing
      return this.addCustomHeaders(prepared);
    }
    return prepared;
  }

  private addCustomHeaders(packet) {
    // Custom implementation
    return packet;
  }

  private setupCustomAudioProcessing() {
    // Custom audio processing setup
  }
}

Direct Protocol Implementation

For maximum control, work directly with WebSocket and UDP components:

import { VoiceWebSocket, VoiceUDPSocket, VoiceOpcodes } from "@discordjs/voice";

// Direct WebSocket control
const ws = new VoiceWebSocket("wss://voice-server.discord.gg", true);
const udp = new VoiceUDPSocket({ ip: "127.0.0.1", port: 50001 });

ws.on("packet", (packet) => {
  switch (packet.op) {
    case VoiceOpcodes.Ready:
      console.log("Voice ready, starting UDP handshake");
      break;
    case VoiceOpcodes.SessionDescription:
      console.log("Received session description");
      break;
    case VoiceOpcodes.Speaking:
      console.log("Speaking update:", packet.d);
      break;
  }
});

// Custom packet handling
ws.sendPacket({
  op: VoiceOpcodes.SelectProtocol,
  d: {
    protocol: "udp",
    data: {
      address: "192.168.1.1",
      port: 1234,
      mode: "aead_aes256_gcm_rtpsize",
    },
  },
});

Error Handling

Handle networking errors appropriately:

networking.on("error", (error) => {
  console.error("Networking error:", error);
});

networking.on("close", () => {
  console.log("Networking connection closed");
});

ws.on("error", (error) => {
  console.error("WebSocket error:", error);
});

udp.on("error", (error) => {
  console.error("UDP error:", error);
});