Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/disgoorg/disgo/llms.txt

Use this file to discover all available pages before exploring further.

The voice package provides a complete voice connection implementation for Discord, enabling bots to join voice channels, send and receive audio, and manage voice connections.

Installation

import "github.com/disgoorg/disgo/voice"

Manager

The Manager handles all voice connections for a bot.

NewManager

Creates a new voice connection manager.
func NewManager(
    voiceStateUpdateFunc StateUpdateFunc,
    userID snowflake.ID,
    opts ...ManagerConfigOpt
) Manager
voiceStateUpdateFunc
StateUpdateFunc
required
Function to update voice state with Discord
userID
snowflake.ID
required
The bot’s user ID
opts
...ManagerConfigOpt
Optional configuration options

Manager interface

type Manager interface {
    // HandleVoiceStateUpdate handles a gateway.EventVoiceStateUpdate
    HandleVoiceStateUpdate(update gateway.EventVoiceStateUpdate)

    // HandleVoiceServerUpdate handles a gateway.EventVoiceServerUpdate
    HandleVoiceServerUpdate(update gateway.EventVoiceServerUpdate)

    // CreateConn creates a new voice connection for the given guild
    CreateConn(guildID snowflake.ID) Conn

    // GetConn returns the voice connection for the given guild
    GetConn(guildID snowflake.ID) Conn

    // Conns returns all voice connections
    Conns() iter.Seq[Conn]

    // RemoveConn removes the voice connection for the given guild
    RemoveConn(guildID snowflake.ID)

    // Close closes all voice connections
    Close(ctx context.Context)
}

Manager configuration

WithLogger

Sets the logger for the voice manager.
func WithLogger(logger *slog.Logger) ManagerConfigOpt

WithConnCreateFunc

Sets a custom connection creation function.
func WithConnCreateFunc(connectionCreateFunc ConnCreateFunc) ManagerConfigOpt

WithConnConfigOpts

Sets configuration options for connections.
func WithConnConfigOpts(opts ...ConnConfigOpt) ManagerConfigOpt

WithDaveSessionCreateFunc

Sets the DAVE (Discord Audio Video Encryption) session creation function.
func WithDaveSessionCreateFunc(sessionCreateFunc godave.SessionCreateFunc) ManagerConfigOpt

WithDaveSessionLogger

Sets the logger for DAVE sessions.
func WithDaveSessionLogger(logger *slog.Logger) ManagerConfigOpt

Connection

Conn interface

Represents a voice connection to a Discord voice channel.
type Conn interface {
    // Gateway returns the voice Gateway used by the voice Conn
    Gateway() Gateway

    // UDP returns the voice UDPConn conn used by the voice Conn
    UDP() UDPConn

    // ChannelID returns the ID of the voice channel
    ChannelID() *snowflake.ID

    // GuildID returns the ID of the guild
    GuildID() snowflake.ID

    // UserIDBySSRC returns the ID of the user for the given SSRC
    UserIDBySSRC(ssrc uint32) snowflake.ID

    // SetSpeaking sends a speaking packet to Discord
    SetSpeaking(ctx context.Context, flags SpeakingFlags) error

    // SetOpusFrameProvider lets you inject your own OpusFrameProvider
    SetOpusFrameProvider(handler OpusFrameProvider)

    // SetOpusFrameReceiver lets you inject your own OpusFrameReceiver
    SetOpusFrameReceiver(handler OpusFrameReceiver)

    // SetEventHandlerFunc lets you listen for voice gateway events
    SetEventHandlerFunc(eventHandlerFunc EventHandlerFunc)

    // Open opens the voice connection
    Open(ctx context.Context, channelID snowflake.ID, selfMute bool, selfDeaf bool) error

    // Close closes the voice connection
    Close(ctx context.Context)

    // HandleVoiceStateUpdate provides the gateway.EventVoiceStateUpdate
    HandleVoiceStateUpdate(update botgateway.EventVoiceStateUpdate)

    // HandleVoiceServerUpdate provides the gateway.EventVoiceServerUpdate
    HandleVoiceServerUpdate(update botgateway.EventVoiceServerUpdate)
}

Connection configuration

WithConnLogger

Sets the connection logger.
func WithConnLogger(logger *slog.Logger) ConnConfigOpt

WithConnGatewayCreateFunc

Sets a custom gateway creation function.
func WithConnGatewayCreateFunc(gatewayCreateFunc GatewayCreateFunc) ConnConfigOpt

WithConnGatewayConfigOpts

Sets gateway configuration options.
func WithConnGatewayConfigOpts(opts ...GatewayConfigOpt) ConnConfigOpt

WithUDPConnCreateFunc

Sets a custom UDP connection creation function.
func WithUDPConnCreateFunc(udpConnCreateFunc UDPConnCreateFunc) ConnConfigOpt

WithUDPConnConfigOpts

Sets UDP connection configuration options.
func WithUDPConnConfigOpts(opts ...UDPConnConfigOpt) ConnConfigOpt

WithConnAudioSenderCreateFunc

Sets a custom audio sender creation function.
func WithConnAudioSenderCreateFunc(audioSenderCreateFunc AudioSenderCreateFunc) ConnConfigOpt

WithConnAudioReceiverCreateFunc

Sets a custom audio receiver creation function.
func WithConnAudioReceiverCreateFunc(audioReceiverCreateFunc AudioReceiverCreateFunc) ConnConfigOpt

WithConnEventHandlerFunc

Sets the event handler function.
func WithConnEventHandlerFunc(eventHandlerFunc EventHandlerFunc) ConnConfigOpt

Gateway

The voice gateway handles the WebSocket connection to Discord’s voice servers.

Gateway interface

type Gateway interface {
    // SSRC returns the SSRC of the current voice connection
    SSRC() uint32

    // Open opens a new websocket connection to the voice gateway
    Open(ctx context.Context, state State) error

    // Close closes the websocket connection to the voice gateway
    Close()

    // CloseWithCode closes the websocket connection with a specific close code
    CloseWithCode(code int, message string)

    // Status returns the Status of the Gateway
    Status() Status

    // Send sends a message to the voice gateway
    Send(ctx context.Context, opCode Opcode, data GatewayMessageData) error

    // Latency returns the current latency of the voice gateway connection
    Latency() time.Duration
}

Gateway status

type Status int

const (
    StatusUnconnected Status = iota
    StatusConnecting
    StatusWaitingForHello
    StatusIdentifying
    StatusResuming
    StatusWaitingForReady
    StatusReady
    StatusDisconnected
)

State

Represents the current state of a voice connection.
type State struct {
    GuildID   snowflake.ID
    UserID    snowflake.ID
    ChannelID *snowflake.ID
    SessionID string
    Token     string
    Endpoint  string
}

UDP connection

Handles the UDP connection for sending and receiving voice data.

UDPConn interface

type UDPConn interface {
    // LocalAddr returns the local network address
    LocalAddr() net.Addr

    // RemoteAddr returns the remote network address
    RemoteAddr() net.Addr

    // SetSecretKey sets the secret key used to encrypt packets
    SetSecretKey(encryptionMode EncryptionMode, secretKey []byte) error

    SetDeadline(t time.Time) error

    // SetReadDeadline sets the read deadline
    SetReadDeadline(t time.Time) error

    // SetWriteDeadline sets the write deadline
    SetWriteDeadline(t time.Time) error

    // Open opens the UDP connection
    Open(ctx context.Context, ip string, port int, ssrc uint32) (string, int, error)

    // Close closes the UDP connection
    Close() error

    // Read reads a packet from the UDP connection
    Read(p []byte) (int, error)

    // ReadPacket reads a packet from the UDP connection
    ReadPacket() (*Packet, error)

    // Write writes a packet to the UDP connection
    Write(p []byte) (int, error)
}

Packet

Represents a voice packet received from Discord.
type Packet struct {
    Type         byte
    Sequence     uint16
    Timestamp    uint32
    SSRC         uint32
    HasExtension bool
    ExtensionID  int
    Extension    []byte
    CSRC         []uint32
    HeaderSize   int
    Opus         []byte
}

Audio streaming

OpusFrameProvider

Provides opus frames to send to Discord.
type OpusFrameProvider interface {
    // ProvideOpusFrame provides an opus frame to the AudioSender
    ProvideOpusFrame() ([]byte, error)

    // Close closes the OpusFrameProvider
    Close()
}

OpusFrameReceiver

Receives opus frames from Discord.
type OpusFrameReceiver interface {
    // ReceiveOpusFrame receives an opus frame
    ReceiveOpusFrame(userID snowflake.ID, packet *Packet) error

    // CleanupUser cleans up any audio resources for the given user
    CleanupUser(userID snowflake.ID)

    // Close stops receiving audio
    Close()
}

NewOpusReader

Creates an OpusFrameProvider that reads opus frames from an io.Reader.
func NewOpusReader(r io.Reader) *OpusReader
Each opus frame should be prefixed with a 4-byte little-endian uint32 representing the frame length.

NewOpusWriter

Creates an OpusFrameReceiver that writes opus frames to an io.Writer.
func NewOpusWriter(w io.Writer, userFilter UserFilterFunc) *OpusWriter
w
io.Writer
required
The writer to write opus frames to
userFilter
UserFilterFunc
Optional filter function to control which users’ audio to write

Constants

Audio frame constants

const (
    // OpusFrameSizeMs is the size of an opus frame in milliseconds
    OpusFrameSizeMs = 20

    // OpusFrameSize is the size of an opus frame in samples
    OpusFrameSize = 960

    // OpusFrameSizeBytes is the size of an opus frame in bytes
    OpusFrameSizeBytes = OpusFrameSize * 2 * 2
)

SilenceAudioFrame

A 20ms opus frame of silence.
var SilenceAudioFrame = []byte{0xF8, 0xFF, 0xFE}

Encryption

EncryptionMode

Supported encryption modes for voice connections.
type EncryptionMode string

const (
    EncryptionModeNone                        EncryptionMode = "none"
    EncryptionModeAEADAES256GCMRTPSize        EncryptionMode = "aead_aes256_gcm_rtpsize"
    EncryptionModeAEADXChaCha20Poly1305RTPSize EncryptionMode = "aead_xchacha20_poly1305_rtpsize"
)

NewEncrypter

Creates a new encrypter based on the encryption mode.
func NewEncrypter(encryptionMode EncryptionMode, secretKey []byte) (Encrypter, error)

Example usage

package main

import (
    "context"
    "log"
    "os"
    "os/signal"
    "syscall"

    "github.com/disgoorg/disgo"
    "github.com/disgoorg/disgo/bot"
    "github.com/disgoorg/disgo/cache"
    "github.com/disgoorg/disgo/gateway"
    "github.com/disgoorg/disgo/voice"
    "github.com/disgoorg/snowflake/v2"
)

func main() {
    client, err := disgo.New(os.Getenv("TOKEN"),
        bot.WithGatewayConfigOpts(
            gateway.WithIntents(gateway.IntentGuilds | gateway.IntentGuildVoiceStates),
        ),
        bot.WithCacheConfigOpts(
            cache.WithCaches(cache.FlagVoiceStates),
        ),
    )
    if err != nil {
        log.Fatal("error creating client: ", err)
    }

    voiceManager := voice.NewManager(
        client.UpdateVoiceState,
        client.ApplicationID(),
    )

    // Connect to voice channel
    guildID := snowflake.ID(123456789)
    channelID := snowflake.ID(987654321)

    conn := voiceManager.CreateConn(guildID)
    if err := conn.Open(context.TODO(), channelID, false, false); err != nil {
        log.Fatal("error opening voice connection: ", err)
    }

    defer conn.Close(context.TODO())

    s := make(chan os.Signal, 1)
    signal.Notify(s, syscall.SIGINT, syscall.SIGTERM)
    <-s
}