From 5f8e59b0f1f0d1ebc1b5ea021fe3da3371f31fef Mon Sep 17 00:00:00 2001 From: Michel Belleau Date: Tue, 5 May 2026 13:50:18 -0700 Subject: [PATCH] docs(discord): fix Server Members Intent + SSRC-mapping drift; add /voice join slash Choice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Salvage of #11350. Kept: - Code: add an explicit /voice join Choice in the slash UI (runner accepts both 'join' and 'channel' but only 'channel' was in autocomplete). - Docs: Server Members Intent is conditional (only needed if DISCORD_ALLOWED_USERS contains usernames); SSRC → user_id mapping uses the voice websocket SPEAKING opcode, not the Members intent. Dropped from the original PR: - HERMES_DISCORD_VOICE_PACKET_DUMP — this env var doesn't exist on main (it was in a different PR that isn't merged). - DISCORD_PROXY docs — already documented on current main. - DISCORD_ALLOW_MENTION_* docs — already on main. - "barge-in mode" rewrite — current main actually does pause the listener during TTS (VoiceReceiver.pause() at discord.py:192); there is no barge_in_guard/barge_in_rms on main. Co-authored-by: Michel Belleau --- gateway/platforms/discord.py | 9 +++++++-- website/docs/user-guide/features/voice-mode.md | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/gateway/platforms/discord.py b/gateway/platforms/discord.py index ecfa38c723..e30c4478ef 100644 --- a/gateway/platforms/discord.py +++ b/gateway/platforms/discord.py @@ -2654,9 +2654,14 @@ class DiscordAdapter(BasePlatformAdapter): await self._run_simple_slash(interaction, "/reload-skills") @tree.command(name="voice", description="Toggle voice reply mode") - @discord.app_commands.describe(mode="Voice mode: on, off, tts, channel, leave, or status") + @discord.app_commands.describe(mode="Voice mode: join, channel, leave, on, tts, off, or status") @discord.app_commands.choices(mode=[ - discord.app_commands.Choice(name="channel — join your voice channel", value="channel"), + # `join` and `channel` both route to _handle_voice_channel_join in + # gateway/run.py — expose both in the slash UI so autocomplete + # matches what the docs advertise and what the runner accepts when + # the command is typed as plain text. + discord.app_commands.Choice(name="join — join your voice channel", value="join"), + discord.app_commands.Choice(name="channel — join your voice channel (alias)", value="channel"), discord.app_commands.Choice(name="leave — leave voice channel", value="leave"), discord.app_commands.Choice(name="on — voice reply to voice messages", value="on"), discord.app_commands.Choice(name="tts — voice reply to all messages", value="tts"), diff --git a/website/docs/user-guide/features/voice-mode.md b/website/docs/user-guide/features/voice-mode.md index 2b45141d07..90997e09f6 100644 --- a/website/docs/user-guide/features/voice-mode.md +++ b/website/docs/user-guide/features/voice-mode.md @@ -281,10 +281,10 @@ In the [Developer Portal](https://discord.com/developers/applications) → your | Intent | Purpose | |--------|---------| | **Presence Intent** | Detect user online/offline status | -| **Server Members Intent** | Map voice SSRC identifiers to Discord user IDs | +| **Server Members Intent** | Resolve usernames in `DISCORD_ALLOWED_USERS` to numeric IDs (conditional) | | **Message Content Intent** | Read text message content in channels | -All three are required for full voice channel functionality. **Server Members Intent** is especially critical — without it, the bot cannot identify who is speaking in the voice channel. +**Message Content Intent** is required. **Server Members Intent** is only needed if your `DISCORD_ALLOWED_USERS` list uses usernames — if you use numeric user IDs, you can leave it OFF. Voice-channel SSRC → user_id mapping comes from Discord's SPEAKING opcode on the voice websocket and does **not** require the Server Members Intent. #### 3. Opus Codec