Files
Veskslop-t/docs/voice.md
T

68 lines
2.8 KiB
Markdown

# Voice
Voice state reads exist. Voice actions do not. This document records the plan and the decisions.
## Current
| Part | Status |
| --- | --- |
| `voice.get` | Implemented. One user's voice channel and its members. Without `guildId` it searches all guilds. |
| `voice.overview` | Implemented. Occupied voice channels and members for one guild. |
| `VOICE_STATE_UPDATE` events | Normalized and pushed. Mock-verified. Live check pending. |
| Join and leave | Not started. |
| Audio in and out | Not started. |
| Video | Not started. |
The core reads `VoiceStateStore` only. It never joins a call on its own.
## Planned actions
| Action | Parameters | Result |
| --- | --- | --- |
| `voice.join` | `channelId`, optional `mute` (default true) | `{ channelId, joined: true }` |
| `voice.leave` | none | `{ left: true }` |
| `voice.move` | `channelId` | `{ channelId, moved: true }` |
Rules:
- The channel must be a voice channel. The core validates the snowflake and the channel type.
- Join joins the call muted. The bot does not capture or send audio.
- Voice actions are state changes, not send floods. They stay out of the message pacing queue, but
the daemon rate limits them separately.
- The join implementation goes through Discord's internal channel action, located at runtime. The
lookup is unverified until the first live run. This is the same pattern as `reaction.add`.
The plan for later audio: the bot unmutes only while it plays an audio stream, then mutes again.
Audio playback is a later feature.
## Lifecycle
The bot leaves a call on its own in two cases.
1. **Owner leaves.** When the owner leaves the call, the bot waits `voiceLeaveDelaySeconds` and
then leaves. A rejoin inside the window cancels the leave.
2. **A stay target leaves.** The `stay @user` command pins the bot to a user. When that user
leaves, the bot waits the same delay and then leaves.
`stay @user` needs a chat command. Chat commands are paused at this time, so the command waits for
the voice backend. The default delay is proposed as 30 seconds and lives in the config.
The bot never leaves while the owner or the stay target is present. A manual `voice.leave` wins
over both rules.
## Collector account
The collector account is a stripped-down client with read-only voice membership. The daemon uses it
when the puppet cannot see a user's voice channel or the channel members. It stays deferred. See
[TODO.md](../TODO.md).
## Verification list
A live run must confirm these points.
1. The internal `selectVoiceChannel` lookup exists and joins the given channel.
2. The internal disconnect action leaves the call.
3. `VOICE_STATE_UPDATE` carries the fields that the core normalizes.
4. The join is muted and Discord shows the mute state.
5. The auto-leave timer works across a client restart. The timer is daemon state, not core state.