-
Notifications
You must be signed in to change notification settings - Fork 787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VoiceStatusUpdate - Unable to determine what channel a user left from #823
Comments
I think this would be incredibly useful. Here's a thought: Discord.js's "voiceStateUpdate" event sends two states, and "old" and a "new" one. I think that gets the best of both worlds: being able to track complex states, while also keeping it simple. Here's a code example: type VoiceStateUpdate struct {
*VoiceState
} New: type VoiceStateUpdate struct {
OldState *VoiceState
NewState *VoiceState
} Technically this could be handled by the user, but functionality is looking poor. My first thought would be to just go through the guild object and read the voice states, but: // This field is only present in GUILD_CREATE events and websocket <---- here
// update events, and thus is only present in state-cached guilds.
VoiceStates []*VoiceState `json:"voice_states"` From Discord's docs, it sounds like GUILD_CREATE fires on startup anyway, so you might be able to get away with tracking each individual user's voiceState on startup, then managing it internally from there. If not, you would have to deal with losing the current voiceState on restart. If you're trying to distinguish between joining from nowhere, vs from another channel, you could keep an internal list of connected members (as mentioned above). When you receive a voiceStateUpdate from that user add them to the list. If you receive a voiceStateUpdate "disconnect", set a timer to check again, then delete them from the list. If they disconnect for more than X time, they won't be on the list. If they are on the list, then you know they probably came from another channel, or only briefly disconnected. import "time"
...
time.AfterFunc(3*time.Second, somefunction) |
To update, I've been looking deeper into this, and I've found some pretty scary stuff. Here's what really has me scratching my head: Then, I found #278, which says you have to try using I case anyone wanted to check, here's my code: func ready(s *discordgo.Session, e *discordgo.Ready) {
// Get all current voiceStates
for _, g := range e.Guilds {
gTemp, _ := s.Guild(g.ID)
for _, v := range gTemp.VoiceStates {
fmt.Println(v.ChannelID)
voiceStateList = append(voiceStateList, v)
}
}
} func guildCreate(s *discordgo.Session, e *discordgo.GuildCreate) {
for _, v := range e.VoiceStates {
fmt.Println(v.UserID)
voiceStateList = append(voiceStateList, v)
}
} And obv I swapped out |
Fetching a guild from the API is never going to work for getting a guild's voice states; see: // A list of voice states for the guild.
// This field is only present in GUILD_CREATE events and websocket
// update events, and thus is only present in state-cached guilds.
VoiceStates []*VoiceState `json:"voice_states"` Are you observing that the voice states are empty on guild creates, or that the guild create event never fires? You seemed to allude to both. What intents are you requesting, and which class of behavior are you observing? In any case, feel free to drop by our support channel (also linked in the README); I'm around at most times and would be happy to try to dig into what's going on. |
Ah yea I contradicted myself there. |
I think a better solution would be to either include the old state, like Discord.js does, or do it like it is done for the Lines 894 to 904 in 92c52f3
|
Agreed. Storing an internal table of users voice states does work, but it's so impractical. A solution like this would simplify 99% of use cases. The other 1% can still make a state list. |
Thank you for all the feedback, I'll submit an updated pull request with previous state added to the VoiceStateUpdate event. |
Add previous state to VoiceStateUpdate event (#823)
I've been using this for a while, and it's a very welcome solution. However, there's a bit of a problem. If a user is in a voice channel when the bot starts up, and the user starts sharing their screen, the event data is indistinguishable from if the user had just joined (as far as I can tell). The obvious workaround would be to check if the user is sharing their screen or not, but I can't find anything in the docs that would do that. Or maybe I'm just crazy, and this isn't happening to anyone else. I'm not 100% sure, but I don't think muting or deafening affects it the same way. Any suggestions are appreciated. EDIT: I should clarify about the streaming part. You can check see if a user is streaming via checking their Activity, but that's a in a separate event, defeating the purpose (for me at least). |
Ok I figured it out my issue. Excerpt from Discord docs:
This ultimately was my issue. Specifying The excerpt from Discord should probably be added to the discordgo docs as well to prevent confusion in the future. |
I'm trying to run an action when a user disconnects from a specific voice channel. The discord API shows the disconnect by firing a Voice State Update with a channel ID of null, as such state tracking is required to determine which server the user left from.
I've tried using the guild.voiceStates to determine what channel the user was in previous, but this information is already cleared out before the VoiceStateUpdate handler is called
I would like feedback on this potential solution before I submit a pull request:
Trigger the new event VoiceStateDisconnect from voiceStateUpdate whenever an entry is removed.
I'm still fairly new to Go so any feedback or alternative solutions are greatly appreciated.
The text was updated successfully, but these errors were encountered: