From dd5b9c6c05b0757bb39be74d95825a8cc2133aa6 Mon Sep 17 00:00:00 2001 From: Andres Perez <1676612+andresperezl@users.noreply.github.com> Date: Fri, 25 Feb 2022 16:26:51 -0500 Subject: [PATCH] Add Guild Member avatar (#1077) * Add guild member avatar * add avatar field on Member struct * add endpoints for guild avatars * add avatarURL util function for *User.AvatarURL and *Member.AvatarURL * set GuildID on after GuildMember request * fix Member.Avatar comment * fix: gofmt Co-authored-by: Fedor Lapshin --- endpoints.go | 7 +++++++ restapi.go | 2 ++ structs.go | 17 +++++++++++++++++ user.go | 17 ++--------------- util.go | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/endpoints.go b/endpoints.go index f0a7315..c51916c 100644 --- a/endpoints.go +++ b/endpoints.go @@ -40,6 +40,7 @@ var ( EndpointCDNSplashes = EndpointCDN + "splashes/" EndpointCDNChannelIcons = EndpointCDN + "channel-icons/" EndpointCDNBanners = EndpointCDN + "banners/" + EndpointCDNGuilds = EndpointCDN + "guilds/" EndpointVoice = EndpointAPI + "/voice/" EndpointVoiceRegions = EndpointVoice + "regions" @@ -90,6 +91,12 @@ var ( EndpointGuildTemplate = func(tID string) string { return EndpointGuilds + "/templates/" + tID } EndpointGuildTemplates = func(gID string) string { return EndpointGuilds + gID + "/templates" } EndpointGuildTemplateSync = func(gID, tID string) string { return EndpointGuilds + gID + "/templates/" + tID } + EndpointGuildMemberAvatar = func(gId, uID, aID string) string { + return EndpointCDNGuilds + gId + "/users/" + uID + "/avatars/" + aID + ".png" + } + EndpointGuildMemberAvatarAnimated = func(gId, uID, aID string) string { + return EndpointCDNGuilds + gId + "/users/" + uID + "/avatars/" + aID + ".gif" + } EndpointChannel = func(cID string) string { return EndpointChannels + cID } EndpointChannelThreads = func(cID string) string { return EndpointChannel(cID) + "/threads" } diff --git a/restapi.go b/restapi.go index cfe9dd8..0f2a161 100644 --- a/restapi.go +++ b/restapi.go @@ -642,6 +642,8 @@ func (s *Session) GuildMember(guildID, userID string) (st *Member, err error) { } err = unmarshal(body, &st) + // The returned object doesn't have the GuildID attribute so we will set it here. + st.GuildID = guildID return } diff --git a/structs.go b/structs.go index 19e711d..02adaa1 100644 --- a/structs.go +++ b/structs.go @@ -985,6 +985,9 @@ type Member struct { // Whether the member is muted at a guild level. Mute bool `json:"mute"` + // The hash of the avatar for the guild member, if any. + Avatar string `json:"avatar"` + // The underlying user on which the member is based. User *User `json:"user"` @@ -1010,6 +1013,20 @@ func (m *Member) Mention() string { return "<@!" + m.User.ID + ">" } +// AvatarURL returns the URL of the member's avatar +// size: The size of the user's avatar as a power of two +// if size is an empty string, no size parameter will +// be added to the URL. +func (m *Member) AvatarURL(size string) string { + if m.Avatar == "" { + return m.User.AvatarURL(size) + } + // The default/empty avatar case should be handled by the above condition + return avatarURL(m.Avatar, "", EndpointGuildMemberAvatar(m.GuildID, m.User.ID, m.Avatar), + EndpointGuildMemberAvatarAnimated(m.GuildID, m.User.ID, m.Avatar), size) + +} + // A Settings stores data for a specific users Discord client settings. type Settings struct { RenderEmbeds bool `json:"render_embeds"` diff --git a/user.go b/user.go index 1e502ac..69c30e5 100644 --- a/user.go +++ b/user.go @@ -1,7 +1,5 @@ package discordgo -import "strings" - // UserFlags is the flags of "user" (see UserFlags* consts) // https://discord.com/developers/docs/resources/user#user-object-user-flags type UserFlags int @@ -91,17 +89,6 @@ func (u *User) Mention() string { // if size is an empty string, no size parameter will // be added to the URL. func (u *User) AvatarURL(size string) string { - var URL string - if u.Avatar == "" { - URL = EndpointDefaultUserAvatar(u.Discriminator) - } else if strings.HasPrefix(u.Avatar, "a_") { - URL = EndpointUserAvatarAnimated(u.ID, u.Avatar) - } else { - URL = EndpointUserAvatar(u.ID, u.Avatar) - } - - if size != "" { - return URL + "?size=" + size - } - return URL + return avatarURL(u.Avatar, EndpointDefaultUserAvatar(u.Discriminator), + EndpointUserAvatar(u.ID, u.Avatar), EndpointUserAvatarAnimated(u.ID, u.Avatar), size) } diff --git a/util.go b/util.go index fae34f7..f3a97c7 100644 --- a/util.go +++ b/util.go @@ -8,6 +8,7 @@ import ( "mime/multipart" "net/textproto" "strconv" + "strings" "time" ) @@ -75,3 +76,19 @@ func MultipartBodyWithJSON(data interface{}, files []*File) (requestContentType return bodywriter.FormDataContentType(), body.Bytes(), nil } + +func avatarURL(avatarHash, defaultAvatarURL, staticAvatarURL, animatedAvatarURL, size string) string { + var URL string + if avatarHash == "" { + URL = defaultAvatarURL + } else if strings.HasPrefix(avatarHash, "a_") { + URL = animatedAvatarURL + } else { + URL = staticAvatarURL + } + + if size != "" { + return URL + "?size=" + size + } + return URL +}