Add GET voice-state REST wrappers#3265
Merged
Misha-133 merged 3 commits intoMay 31, 2026
Merged
Conversation
Wraps GET /guilds/{guild.id}/voice-states/@me and
GET /guilds/{guild.id}/voice-states/{user.id}, symmetric with the
existing ModifyMyVoiceState / ModifyUserVoiceState PATCH wrappers.
Returns null on 404 (user not in any voice channel of the guild).
Exposed as GetMyVoiceStateAsync / GetUserVoiceStateAsync on RestGuild
and SocketGuild, returning a new RestVoiceState entity that carries
the user's voice channel id and state flags from the REST response.
Member
|
I think we should still reuse the Also thanks for the contribution :)) |
Misha-133
approved these changes
May 31, 2026
ROBdk97
reviewed
Jun 7, 2026
| internal SocketVoiceState(SocketVoiceChannel voiceChannel, DateTimeOffset? requestToSpeak, string sessionId, bool isSelfMuted, bool isSelfDeafened, bool isMuted, bool isDeafened, bool isSuppressed, bool isStream, bool isVideo) | ||
| { | ||
| VoiceChannel = voiceChannel; | ||
| VoiceChannelId = voiceChannel.Id; |
There was a problem hiding this comment.
Suggested change
| VoiceChannelId = voiceChannel.Id; | |
| VoiceChannelId = voiceChannel?.Id; |
Missing null check
This is causing a error for me if you join to/from no voice channel
Error handling Dispatch (VOICE_STATE_UPDATE)
System.TypeInitializationException: The type initializer for 'Discord.WebSocket.SocketVoiceState' threw an exception.
---> System.NullReferenceException: Object reference not set to an instance of an object.
at Discord.WebSocket.SocketVoiceState..ctor(SocketVoiceChannel voiceChannel, Nullable`1 requestToSpeak, String sessionId, Boolean isSelfMuted, Boolean isSelfDeafened, Boolean isMuted, Boolean isDeafened, Boolean isSuppressed, Boolean isStream, Boolean isVideo)
at Discord.WebSocket.SocketVoiceState..cctor()
--- End of inner exception stack trace ---
at Discord.WebSocket.DiscordSocketClient.ProcessMessageAsync(GatewayOpCode opCode, Nullable`1 seq, String type, Object payload)
System.NullReferenceException: Object reference not set to an instance of an object.
at Discord.WebSocket.SocketVoiceState..ctor(SocketVoiceChannel voiceChannel, Nullable`1 requestToSpeak, String sessionId, Boolean isSelfMuted, Boolean isSelfDeafened, Boolean isMuted, Boolean isDeafened, Boolean isSuppressed, Boolean isStream, Boolean isVideo)
at Discord.WebSocket.SocketVoiceState..cctor()
I will create a Issue
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wraps two voice-state GET endpoints that round out the PATCH pair already in
DiscordRestApiClient:GET /guilds/{guild.id}/voice-states/@meGET /guilds/{guild.id}/voice-states/{user.id}Both return
nullon 404 (the user is not currently in any voice channel of the guild).Exposed as
GetMyVoiceStateAsyncandGetUserVoiceStateAsynconRestGuildandSocketGuild, returning a newRestVoiceStateentity that mirrors the relevant fields from the REST response (channel id, mute/deaf/suppress/streaming/video flags, voice-session id, request-to-speak timestamp).Why a new
RestVoiceStaterather than reusingIVoiceStateThe REST response carries
channel_id, not a full channel object. ImplementingIVoiceStatewould require returningnullforIVoiceChannel VoiceChanneleven when the user is in voice (sincenullalready means "not in voice" per the existing interface contract), which would be misleading. ExposingVoiceChannelId : ulong?directly avoids that ambiguity; callers who need the channel can resolve it viaguild.GetVoiceChannelAsync(state.VoiceChannelId.Value).Happy to revisit if maintainers prefer a different shape (e.g. implementing
IVoiceStatewith a documented null contract, or pre-fetching the channel via an extra REST call insideGuildHelper).Tests
Skipped — the change is REST glue and the 404→null mapping isn't reachable from the unit-test project's public surface. Live integration coverage exists in spirit via the existing
RestGuildFixtureflow but I did not add a test there to keep the patch self-contained. Happy to add tests if maintainers point at the right entry point.