Skip to main content
Everything exported from @cloak-software/bot-sdk for voice. For the concepts behind these, start at Voice overview.
The interface behind client.voiceKeys is called VoiceKeyAccess in the source and is not exported. Do not write an import for it. Reach the lane through client.voiceKeys.

Client surface

These live on Client, not in the voice modules. Documented in full on Joining voice. client.guild(serverId) binds joinVoice(channelId, opts?) and refreshVoiceRoster(). Events: voiceJoin, voiceLeave, voiceStateUpdate, voiceConnectionState, voiceDisconnect, voiceKeyUpdate. See Events.

livekitUrlFor

The media signalling URL for a Cloak deployment, derived from the transport URL: same host, port 7880, wss: (or ws: when the transport itself is insecure). Returns '' for an unparseable URL. This is what VoiceConnection.url defaults to. Override it with ClientOptions.livekitUrl. The SDK never connects to that URL. It is passed through for the media layer.

Types

VoiceConnection

token is a live credential. Never log it or put it in an error message.

VoiceParticipant

p2pWebcam and p2pStream are dead API. Peer-to-peer video has been removed from the platform. The fields remain so the wire column map stays stable, and they are permanently false.
serverMuted and serverDeafened are best-effort in the initial roster snapshot: the backend appends them from a separate query whose row order is not guaranteed to line up. The delta events correct them.

VoiceKey

VoiceKeyScope

Read from an authenticated tag inside the sealed key, never computed and never defaulted. See Voice keys and scopes.

VoiceStateFlag

The state field on voiceStateUpdate. The last two are deprecated and never change.

VoiceMediaSession

Requires the optional native engine. See Voice runtime.
Promise<VoiceMediaSession>
Connects, installs frame keys, and publishes one microphone track. Fails closed on every precondition. Full walkthrough on Publishing audio.
string
The identity the SFU knows this bot by. Asserted equal to the normalized bot id at attach time.
'participant' | 'room'
The scope the key arrived with. Read-only.
readonly string[]
Every identity this session has filed a key for. In participant scope this is exactly one, the bot’s own.
Promise<void>
Re-pin after a voiceKeyUpdate. Detaches the session and throws when the new scope differs from the attached one.
Promise<void>
Stops the player, unpublishes, and disconnects. Idempotent.

VoiceMediaOptions

VoiceKeyValue

A voice key exactly as the key lane hands it over. VoiceKey satisfies it structurally.

VoiceFrameKeySource

The one seam the media session gets frame keys from. client.voiceKeys satisfies it. It exists so the publish path never sees a scope.

VoicePlayer

You get one on session.player. Constructing your own is only for testing.
Promise<void>
Pumps a resource to completion. Resolves when the resource ends or stop() is called. Rejects when the source throws, including a non-zero decoder exit. Throws immediately if a resource is already playing.
void
Ends the current resource. The in-flight frame is still awaited.

VoicePlayerEvents

VoicePlayerDeps

Injected rather than imported, so the player is testable with no native code on disk.

Audio resources

AudioResource

Interleaved signed 16-bit PCM. Each chunk must contain a whole number of frames. close() is called once when the pump ends for any reason, including stop() and errors.

pcmChunks

Adapts a byte stream to frame-aligned chunks. Handles chunks that end mid-sample and buffers whose offset is not two-byte aligned. A trailing partial frame is dropped.

ffmpegResource

Decodes a file path or a direct media URL. Synchronous. Throws a CloakEnvironmentError at play time when the decoder cannot start or exits non-zero.

ytdlpResource

Resolves a streaming-site page URL with yt-dlp, then decodes it with ffmpeg. Async, unlike ffmpegResource.
--no-playlist is always passed.

resolveMediaUrl

Resolves a page URL to a direct media URL and returns it, so you can log, cache, or inspect it yourself.
The result is signed, expiring, and usually bound to this host’s IP address. Resolve at play time. Do not persist it and do not hand it to another machine.

DecoderChild, DecoderSpawn, ExtractorRun

Test seams for the decoder and extractor plumbing, exported so the failure paths are reachable offline. DecoderChild is a narrow structural view of a spawned process. Not version-stable.

Runtime

probeVoiceRuntime

Tries to load the engine and reports what happened. Never throws.

voiceEnvError

Maps an engine load failure onto an actionable error. Recognises old glibc, musl hosts, and a missing package, and attaches a remedy naming what to change on the machine.

Runtime constants

Encryption

These are a cross-platform contract shared with the Cloak desktop, web, and mobile clients. Treat them like a wire format, not like configuration.

deriveParticipantVoiceKey

Derives one participant’s key from the room key. Throws unless roomKey is exactly 32 bytes. Derives downward only: there is no inverse, and that absence is what makes a publish-only bot structurally deaf. Pinned by a golden test vector shared across repos.

voiceKeyMaterial

Asserts a key is exactly 32 bytes and returns it. A 33-byte value gets its own error message: the sealed plaintext is a 1-byte scope tag followed by 32 key bytes, and a 33-byte value here means the tag was never stripped. Slicing it off at this point would install a byte-shifted key that the provider accepts without complaint and that no peer can decrypt.

voiceKeyProviderOptions

The frame-key provider options the SDK configures the engine with. Exported so the contract is inspectable. There is deliberately no shared key and no shared-key field: per-participant mode is the absence of that field.

Constants

Next

Voice overview

What a voice bot can and cannot do.

Publishing audio

The media session in practice.

Voice runtime

Engine setup and the symptom-to-cause table.

Client

The rest of the client surface.