bwmarrin / discordgo

(Golang) Go bindings for Discord
BSD 3-Clause "New" or "Revised" License
5.02k stars 796 forks source link

Can't get guild members: discord.Guild(id) returns Guild struct with empty member slice and 0 MemberCount. #841

Open FlameInTheDark opened 3 years ago

FlameInTheDark commented 3 years ago

When I try to get the guild by id, I got a structure with an empty Members slice and MemberCount == 0. But the guild has members and the following code returns the correct MemberCount, but the Members slice has only one member and that is a bot.

for _,g := range r.Discord.State.Guilds {
    fmt.Println(g.Name, g.MemberCount)
    for _, m := range g.Members {
        fmt.Printf("    %s | %s\n", m.User.Username, m.User.ID)
    }
}

Perhaps this is due to changes in the API or something similar. Right now I don't have any idea why it happens.

naezith commented 3 years ago

I confirm, our bot is broken because of this.

CarsonHoffman commented 3 years ago

I imagine there are two separate changes compounding here:

  1. (*Session).Guild no longer checks the state before hitting the API. This method was an oddity; it was the only such method to do so, and was thus inconsistent with the remainder of the library. This change was detailed in the v0.21.0 release notes.
  2. Member information is no longer automatically sent over the gateway. This change was announced in February with a 6 month grace period, with messages sent via email and DMs to all Discord users who own a bot, as well as notification on our end in the same v0.21.0 release notes. We also have a frequently asked questions entry on the topic; please read this before proceeding.
MrGeorgen commented 3 years ago

(s *Session) GuildMembers is also broken. I'm guessing for the same reason

syrm commented 3 years ago

    // Approximate number of members in this guild, returned from the GET /guild/<id> endpoint when with_counts is true
    ApproximateMemberCount int `json:"approximate_member_count"`

    // Approximate number of non-offline members in this guild, returned from the GET /guild/<id> endpoint when with_counts is true
    ApproximatePresenceCount int `json:"approximate_presence_count"```

with_counts is never passed, and there is no option to pass it to guild.
FoksVHox commented 3 years ago

Any update on this?

syrm commented 3 years ago

I use this work around for the moment

guildJson, err := discord.RequestWithBucketID("GET", discordgo.EndpointGuild(strconv.Itoa(guild.ExternalID))+"?with_counts=true", nil, discordgo.EndpointGuild(strconv.Itoa(guild.ExternalID)))
guildDiscord := &discordgo.Guild{}

if err == nil {
    err = json.Unmarshal(guildJson, guildDiscord)
}

guildDiscord.ApproximateMemberCount
Zamiell commented 2 years ago

Even with using the new intents system, it seems impossible to get the current guild members. Does anyone have a working code snippet that does this?

MrGeorgen commented 2 years ago

Even with using the new intents system, it seems impossible to get the current guild members. Does anyone have a working code snippet that does this?

allUsers, err := discord.GuildMembers(DiscordServerID, "0", 1000)

returns the first 1000 users. I guess you could get more by running the function again with the userid of the last user in the array instead of "0", but I haven't tried that