@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 onClient, 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
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
VoiceParticipant
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
VoiceStateFlag
state field on voiceStateUpdate. The last two are deprecated and never change.
VoiceMediaSession
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
VoiceKey satisfies it structurally.
VoiceFrameKeySource
client.voiceKeys satisfies it. It exists so the publish path never sees a scope.
VoicePlayer
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
Audio resources
AudioResource
close() is called once when the pump ends for any reason, including stop() and errors.
pcmChunks
ffmpegResource
CloakEnvironmentError at play time when the decoder cannot start or exits non-zero.
ytdlpResource
ffmpegResource.
--no-playlist is always passed.
resolveMediaUrl
DecoderChild, DecoderSpawn, ExtractorRun
DecoderChild is a narrow structural view of a spawned process. Not version-stable.
Runtime
probeVoiceRuntime
voiceEnvError
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
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
voiceKeyProviderOptions
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.