Skip to main content

Command Palette

Search for a command to run...

How to Connect to Discord Voice Using a User Token

Written by
Yasin Çakmak avatar
Yasin Çakmak
Published onFeb 9, 2026
Views
Comments

Introduction

Most developers interact with Discord voice through high-level bot libraries such as discord.js or Eris. These libraries abstract away what is actually a fairly complex real-time system.

Behind the scenes, Discord voice consists of:

  • A main Gateway WebSocket
  • A separate Voice WebSocket
  • A UDP-based real-time transport layer

dconnect is a CLI tool that implements this entire pipeline from scratch, without using any bot framework — and it does so using a user token, not a bot token.

⚠️ This article is for educational and experimental purposes only. Using user tokens may violate Discord’s Terms of Service.


What Does dconnect Do?

With a single command, dconnect:

  1. Connects to the Discord Gateway
  2. Authenticates a user account
  3. Sends a VOICE_STATE_UPDATE
  4. Receives voice server information
  5. Opens a Voice WebSocket
  6. Performs UDP discovery
  7. Establishes a real voice session

Result: the account actually joins the target voice channel.


CLI Usage

dconnect <token> --guild <guild_id> --channel <channel_id>

Options

--mute   ## Join muted
--deaf   ## Join deafened

Example

dconnect MTIzNDU2... --guild 123456789 --channel 987654321 --mute

On success, the following sequence occurs:

  • Gateway connection
  • READY event
  • Voice state & server updates
  • UDP discovery
  • Voice session becomes ready

Architecture Overview

The project consists of two core components:

  • DiscordGateway — Handles the main Discord Gateway connection
  • VoiceConnection — Manages Voice WebSocket + UDP

Both components are built on top of Node.js EventEmitter.


Discord Gateway Flow

Fetching the Gateway URL

GET https://discord.com/api/gateway

This endpoint returns the Gateway WebSocket URL.


Establishing the WebSocket

new WebSocket(`${url}?v=10&encoding=json`)

Gateway v10 with JSON encoding is used.


HELLO & Heartbeat

After connecting, Discord sends:

{
  "op": 10,
  "d": { "heartbeat_interval": 41250 }
}

The client must send heartbeats at this interval:

{ op: 1, d: sequence }

IDENTIFY

{
  op: 2,
  d: {
    token,
    intents: GUILDS | GUILD_VOICE_STATES
  }
}

This authenticates the user session.


READY Event

READY → session_id + user information

The session_id is critical for the voice handshake.


Joining a Voice Channel

VOICE_STATE_UPDATE

{
  op: 4,
  d: {
    guild_id,
    channel_id,
    self_mute,
    self_deaf
  }
}

This packet tells Discord that the user wants to join a voice channel.


VOICE_SERVER_UPDATE

Discord responds with:

  • endpoint
  • token

These values are required to open the Voice WebSocket.


Voice WebSocket Flow

Opening the Voice WebSocket

wss://<endpoint>?v=4

Voice IDENTIFY

{
  op: 0,
  d: {
    server_id,
    user_id,
    session_id,
    token
  }
}

READY Event

The voice server responds with:

  • ssrc
  • ip
  • port

At this stage, UDP discovery begins.


UDP Discovery (The Critical Part)

Discord voice requires UDP discovery to determine the client’s external IP and port.

const packet = Buffer.alloc(70)
packet.writeUInt32BE(ssrc, 0)
udp.send(packet, port, ip)

Once a response is received, the UDP transport is considered established.


Selecting the Transport Protocol

{
  op: 1,
  d: {
    protocol: "udp",
    data: {
      address,
      port,
      mode: "xsalsa20_poly1305"
    }
  }
}

This selects Discord’s default encryption mode.


SESSION_DESCRIPTION

The voice server sends the encryption key:

secret_key

At this point, the voice connection is fully established.


Speaking State

voiceConn.setSpeaking(true)

This updates the speaking indicator for the user.


Graceful Shutdown

Ctrl + C
  • Heartbeats stop
  • UDP socket closes
  • All WebSockets close cleanly

Conclusion

dconnect is a low-level reference implementation of how Discord voice actually works under the hood.

Without any bot framework abstraction, it demonstrates:

  • Gateway protocol
  • Voice WebSocket handshake
  • UDP discovery
  • Encryption setup

If you want to truly understand Discord voice internals, this project exposes the entire pipeline.

If you don’t know what you’re doing, don’t use it. If you do know — this project should feel very satisfying.


Source: dconnect source code

Edit on GitHub
Last updated: Feb 9, 2026