Voice
Zrzur voice runs on LiveKit. The API hands out tickets; the audio itself goes through a LiveKit client.
What works
| Capability | Status |
|---|---|
Get a ticket for a voice channel (POST /channels/{target}/join_call) | Supported, verified live with a bot token |
| Connect to LiveKit with the ticket and publish audio | Supported. Verified end to end with @livekit/rtc-node: a second participant received and measured the bot's audio |
| Receive other participants' audio | Possible with a LiveKit client; needs Listen. Not covered by our tests |
Move, mute and deafen members (PATCH /servers/{server_id}/members/{member_id}) | Supported with Move Members, Mute Members, Deafen Members |
| Video and screen sharing from a bot | Not tested; tickets follow the Video permission |
force_disconnect when joining | Not for bots (IsBot) |
Join
Ask for a ticket over plain HTTP:
curl -X POST "https://api.zrzur.com/channels/CHANNEL_ID/join_call" \
-H "x-bot-token: YOUR_BOT_TOKEN" \
-H "content-type: application/json" \
-d '{}'
# answer: { "token": "LIVEKIT_TOKEN", "url": "wss://voice.zrzur.com" }Then connect with a LiveKit client. With the SDK (not published yet) and @livekit/rtc-node:
const ticket = await bot.voice.join(channelId); // { url, token, node }
const room = new Room(); // from @livekit/rtc-node
await room.connect(ticket.url, ticket.token, { autoSubscribe: false });Then create an AudioSource at 48 kHz, wrap it in a LocalAudioTrack, publish it with room.localParticipant.publishTrack(...) and feed it 10 ms frames. Other members see VoiceChannelJoin when the bot is in the room.
The bot needs Connect to join and Speak to be heard. GET / lists the voice nodes under features.livekit.nodes.
The voice tutorial has a complete /join command.
Reference
PUT /channels/{target}/end_ring/{target_user}
Stop Ring. Stops ringing a specific user in a dm call. You must be in the call to use this endpoint, returns NotConnected otherwise. Only valid in DM/Group channels, will return NoEffect in servers. Returns NotFound if the user is not in the dm/group channel
Rate limit: channels, 15 / 10 s
POST /channels/{target}/join_call
Join Call. Asks the voice server for a token to join the call.
Permissions: Channel:Connect, Channel:ManageChannel · Rate limit: channels, 15 / 10 s
POST /channels/{target}/soundboard/{sound_id}
Play Sound. Play a sound of this server into the voice channel you are in. Needs Use Soundboard and Speak there, and not being server-muted; on a stage only speakers play sounds. Limited to a few sounds every ten seconds.
Permissions: Channel:UseSoundboard, Channel:Speak · Rate limit: channels, 15 / 10 s
DELETE /channels/{target}/stage
End Stage. Closes the stage: everyone leaves the call and the topic, speakers and raised hands are cleared. Needs Mute Members and Move Members.
Permissions: Channel:MuteMembers, Channel:MoveMembers · Rate limit: channels, 15 / 10 s
GET /channels/{target}/stage
Fetch Stage. Topic, speakers and raised hands of a stage channel.
Rate limit: channels, 15 / 10 s
PATCH /channels/{target}/stage
Edit Stage. Set or clear the topic of a stage (needs Mute Members).
Permissions: Channel:MuteMembers · Rate limit: channels, 15 / 10 s
PUT /channels/{target}/stage/hand
Raise Hand. Ask to speak on a stage you are listening to (once every 20 seconds).
Permissions: Channel:Connect · Rate limit: channels, 15 / 10 s
DELETE /channels/{target}/stage/hands/{member}
Lower Hand. Lower your own raised hand, or (with Mute Members) someone else's.
Permissions: Channel:MuteMembers · Rate limit: channels, 15 / 10 s
DELETE /channels/{target}/stage/speakers/{member}
Move To Audience. Stop speaking yourself, or (with Mute Members and a higher rank) send a speaker back to the listeners. When the voice server can't be told, the speaker is taken out of the call rather than left able to talk.
Permissions: Channel:MuteMembers · Rate limit: channels, 15 / 10 s
PUT /channels/{target}/stage/speakers/{member}
Invite To Speak. Give someone in the stage the floor (needs Mute Members, and a higher rank than theirs). Their raised hand goes down.
Permissions: Channel:MuteMembers · Rate limit: channels, 15 / 10 s
PUT /channels/{target}/stream_preview
Send Stream Preview. Replace the preview of your screen share in this voice channel (a JPEG or WebP of at most 20 KB, base64). Only while you share your screen there; a new one is taken at most every 25 seconds (NoEffect before that).
Rate limit: channels, 15 / 10 s
GET /channels/{target}/stream_preview/{member}
Fetch Stream Preview. The latest still of someone's screen share in a voice channel you can see.
Permissions: Channel:ViewChannel, Channel:Listen · Rate limit: channels, 15 / 10 s