diff --git a/discord/emoji.go b/discord/emoji.go index 9110514..62eb987 100644 --- a/discord/emoji.go +++ b/discord/emoji.go @@ -3,7 +3,7 @@ package discord import "strings" type Emoji struct { - ID Snowflake `json:"id,string"` // 0 for Unicode emojis + ID Snowflake `json:"id,string"` // NullSnowflake for unicode emojis Name string `json:"name"` // These fields are optional @@ -16,6 +16,26 @@ type Emoji struct { Animated bool `json:"animated,omitempty"` } +// EmojiURL returns the URL of the emoji. +// +// This will only work for custom emojis. +func (e Emoji) EmojiURL() string { + return e.EmojiURLWithType(AutoImage) +} + +// EmojiURLWithType returns the URL to the emoji's image. +// +// This will only work for custom emojis. +// +// Supported ImageTypes: PNG, GIF +func (e Emoji) EmojiURLWithType(t ImageType) string { + if e.ID == NullSnowflake { + return "" + } + + return "https://cdn.discordapp.com/emojis/" + t.format(e.ID.String()) +} + // APIString returns a string usable for sending over to the API. func (e Emoji) APIString() string { if !e.ID.Valid() { diff --git a/discord/guild.go b/discord/guild.go index 4163e33..ad176f7 100644 --- a/discord/guild.go +++ b/discord/guild.go @@ -1,7 +1,5 @@ package discord -import "strings" - type Guild struct { ID Snowflake `json:"id,string"` Name string `json:"name"` @@ -57,36 +55,45 @@ type Guild struct { ApproximatePresences uint64 `json:"approximate_presence_count,omitempty"` } -// IconURL returns the URL to the guild icon. An empty string is removed if -// there's no icon. +// IconURL returns the URL to the guild icon and auto detects a suitable type. +// An empty string is returned if there's no icon. func (g Guild) IconURL() string { + return g.IconURLWithType(AutoImage) +} + +// IconURLWithType returns the URL to the guild icon using the passed ImageType. An +// empty string is returned if there's no icon. +// +// Supported ImageTypes: PNG, JPEG, WebP, GIF +func (g Guild) IconURLWithType(t ImageType) string { if g.Icon == "" { return "" } - base := "https://cdn.discordapp.com/icons/" + - g.ID.String() + "/" + g.Icon - - if len(g.Icon) > 2 && g.Icon[:2] == "a_" { - return base + ".gif" - } - - return base + ".png" + return "https://cdn.discordapp.com/icons/" + g.ID.String() + "/" + t.format(g.Icon) } // BannerURL returns the URL to the banner, which is the image on top of the -// channels list. +// channels list. This will always return a link to a PNG file. func (g Guild) BannerURL() string { + return g.BannerURLWithType(PNGImage) +} + +// BannerURLWithType returns the URL to the banner, which is the image on top of the +// channels list using the passed image type. +// +// Supported ImageTypes: PNG, JPEG, WebP +func (g Guild) BannerURLWithType(t ImageType) string { if g.Banner == "" { return "" } return "https://cdn.discordapp.com/banners/" + - g.ID.String() + "/" + g.Banner + ".png" + g.ID.String() + "/" + t.format(g.Banner) } // SplashURL returns the URL to the guild splash, which is the invite page's -// background. +// background. This will always return a link to a PNG file. func (g Guild) SplashURL() string { if g.Splash == "" { return "" @@ -96,6 +103,19 @@ func (g Guild) SplashURL() string { g.ID.String() + "/" + g.Splash + ".png" } +// SplashURLWithType returns the URL to the guild splash, which is the invite page's +// background, using the passed ImageType. +// +// Supported ImageTypes: PNG, JPEG, WebP +func (g Guild) SplashURLWithType(t ImageType) string { + if g.Splash == "" { + return "" + } + + return "https://cdn.discordapp.com/splashes/" + + g.ID.String() + "/" + t.format(g.Splash) +} + // https://discord.com/developers/docs/resources/guild#guild-preview-object type GuildPreview struct { // ID is the guild id. @@ -125,41 +145,70 @@ type GuildPreview struct { Description string `json:"description,omitempty"` } -// IconURL returns the URL to the guild icon. An empty string is removed if -// there's no icon. +// IconURL returns the URL to the guild icon and auto detects a suitable type. +// An empty string is returned if there's no icon. func (g GuildPreview) IconURL() string { + return g.IconURLWithType(AutoImage) +} + +// IconURLWithType returns the URL to the guild icon using the passed ImageType. An +// empty string is returned if there's no icon. +// +// Supported ImageTypes: PNG, JPEG, WebP, GIF +func (g GuildPreview) IconURLWithType(t ImageType) string { if g.Icon == "" { return "" } - base := "https://cdn.discordapp.com/icons/" + g.ID.String() + "/" + g.Icon - - if strings.HasPrefix(g.Icon, "a_") { - return base + ".gif" - } - - return base + ".png" + return "https://cdn.discordapp.com/icons/" + g.ID.String() + "/" + t.format(g.Icon) } // SplashURL returns the URL to the guild splash, which is the invite page's -// background. +// background. This will always return a link to a PNG file. func (g GuildPreview) SplashURL() string { if g.Splash == "" { return "" } - return "https://cdn.discordapp.com/splashes/" + g.ID.String() + "/" + g.Splash + ".png" + return "https://cdn.discordapp.com/splashes/" + + g.ID.String() + "/" + g.Splash + ".png" } -// SplashURL returns the URL to the guild splash, which is the invite page's -// background. +// SplashURLWithType returns the URL to the guild splash, which is the invite page's +// background, using the passed ImageType. +// +// Supported ImageTypes: PNG, JPEG, WebP +func (g GuildPreview) SplashURLWithType(t ImageType) string { + if g.Splash == "" { + return "" + } + + return "https://cdn.discordapp.com/splashes/" + + g.ID.String() + "/" + t.format(g.Splash) +} + +// DiscoverySplashURL returns the URL to the guild splash, which is the invite page's +// background. This will always return a link to a PNG file. func (g GuildPreview) DiscoverySplashURL() string { if g.Splash == "" { return "" } - return "https://cdn.discordapp.com/discovery-splashes/" + - g.ID.String() + "/" + g.DiscoverySplash + ".png" + return "https://cdn.discordapp.com/splashes/" + + g.ID.String() + "/" + g.Splash + ".png" +} + +// DiscoverySplashURLWithType returns the URL to the guild splash, which is the invite page's +// background, using the passed ImageType. +// +// Supported ImageTypes: PNG, JPEG, WebP +func (g GuildPreview) DiscoverySplashURLWithType(t ImageType) string { + if g.Splash == "" { + return "" + } + + return "https://cdn.discordapp.com/splashes/" + + g.ID.String() + "/" + t.format(g.Splash) } type Role struct { diff --git a/discord/user.go b/discord/user.go index a1178c1..91c37d5 100644 --- a/discord/user.go +++ b/discord/user.go @@ -1,10 +1,8 @@ package discord -import "strings" - -// DefaultAvatarURL is the link to the default green avatar on Discord. It's -// returned from AvatarURL() if the user doesn't have an avatar. -var DefaultAvatarURL = "https://discordapp.com/assets/dd4dbc0016779df1378e7812eabaa04d.png" +import ( + "strconv" +) type User struct { ID Snowflake `json:"id,string"` @@ -32,19 +30,32 @@ func (u User) Mention() string { return "<@" + u.ID.String() + ">" } +// AvatarURL returns the URL of the Avatar Image. It automatically detects a +// suitable type. func (u User) AvatarURL() string { + return u.AvatarURLWithType(AutoImage) +} + +// AvatarURLWithType returns the URL of the Avatar Image using the passed type. +// If the user has no Avatar, his default avatar will be returned. This +// requires ImageType Auto or PNG +// +// Supported Image Types: PNG, JPEG, WebP, GIF (read above for caveat) +func (u User) AvatarURLWithType(t ImageType) string { if u.Avatar == "" { - return DefaultAvatarURL + if t != PNGImage && t != AutoImage { + return "" + } + + disc, err := strconv.Atoi(u.Discriminator) + if err != nil { // this should never happen + return "" + } + + return "https://cdn.discordapp.com/embed/avatars/" + string(disc%5) + ".png" } - base := "https://cdn.discordapp.com" - base += "/avatars/" + u.ID.String() + "/" + u.Avatar - - if strings.HasPrefix(u.Avatar, "a_") { - return base + ".gif" - } else { - return base + ".png" - } + return "https://cdn.discordapp.com/avatars/" + u.ID.String() + "/" + t.format(u.Avatar) } type UserFlags uint32