-
Notifications
You must be signed in to change notification settings - Fork 35
/
cdn_endpoints.go
145 lines (115 loc) · 4.65 KB
/
cdn_endpoints.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package discord
import (
"strings"
)
const CDN = "https://cdn.discordapp.com"
var (
CustomEmoji = NewCDN("/emojis/{emote.id}", ImageFormatPNG, ImageFormatGIF)
GuildIcon = NewCDN("/icons/{guild.id}/{guild.icon.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP, ImageFormatGIF)
GuildSplash = NewCDN("/splashes/{guild.id}/{guild.splash.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP)
GuildDiscoverySplash = NewCDN("/discovery-splashes/{guild.id}/{guild.discovery.splash.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP)
GuildBanner = NewCDN("/banners/{guild.id}/{guild.banner.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP, ImageFormatGIF)
RoleIcon = NewCDN("/role-icons/{role.id}/{role.icon.hash}", ImageFormatPNG, ImageFormatJPEG)
UserBanner = NewCDN("/banners/{user.id}/{user.banner.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP, ImageFormatGIF)
UserAvatar = NewCDN("/avatars/{user.id}/{user.avatar.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP, ImageFormatGIF)
DefaultUserAvatar = NewCDN("/embed/avatars/{user.discriminator%5}", ImageFormatPNG)
ChannelIcon = NewCDN("/channel-icons/{channel.id}/{channel.icon.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP)
MemberAvatar = NewCDN("/guilds/{guild.id}/users/{user.id}/avatars/{member.avatar.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP, ImageFormatGIF)
ApplicationIcon = NewCDN("/app-icons/{application.id}/{icon.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP)
ApplicationCover = NewCDN("/app-assets/{application.id}/{cover.image.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP)
ApplicationAsset = NewCDN("/app-assets/{application.id}/{asset.id}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP)
AchievementIcon = NewCDN("/app-assets/{application.id}/achievements/{achievement.id}/icons/{icon.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP)
TeamIcon = NewCDN("/team-icons/{team.id}/{team.icon.hash}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP)
StickerPackBanner = NewCDN("app-assets/710982414301790216/store/{banner.asset.id}", ImageFormatPNG, ImageFormatJPEG, ImageFormatWebP)
CustomSticker = NewCDN("/stickers/{sticker.id}", ImageFormatPNG, ImageFormatLottie)
AttachmentFile = NewCDN("/attachments/{channel.id}/{attachment.id}/{file.name}", ImageFormatNone)
)
// ImageFormat is the type of image on Discord's CDN (https://discord.com/developers/docs/reference#image-formatting-image-formats)
type ImageFormat string
// The available ImageFormat(s)
const (
ImageFormatNone ImageFormat = ""
ImageFormatPNG ImageFormat = "png"
ImageFormatJPEG ImageFormat = "jpg"
ImageFormatWebP ImageFormat = "webp"
ImageFormatGIF ImageFormat = "gif"
ImageFormatLottie ImageFormat = "json"
)
// String returns the string representation of the ImageFormat
func (f ImageFormat) String() string {
return string(f)
}
// Animated returns true if the ImageFormat is animated
func (f ImageFormat) Animated() bool {
switch f {
case ImageFormatWebP, ImageFormatGIF:
return true
default:
return false
}
}
func NewCDN(route string, imageFormats ...ImageFormat) *CDNEndpoint {
return &CDNEndpoint{
Route: route,
Formats: imageFormats,
}
}
type CDNEndpoint struct {
Route string
Formats []ImageFormat
}
func (e CDNEndpoint) URL(format ImageFormat, values QueryValues, params ...any) string {
query := values.Encode()
if query != "" {
query = "?" + query
}
return urlPrint(CDN+e.Route+"."+format.String(), params...) + query
}
func DefaultCDNConfig() *CDNConfig {
return &CDNConfig{
Format: ImageFormatPNG,
Values: QueryValues{},
}
}
type CDNConfig struct {
Format ImageFormat
Values QueryValues
}
// Apply applies the given ConfigOpt(s) to the Config
func (c *CDNConfig) Apply(opts []CDNOpt) {
for _, opt := range opts {
opt(c)
}
}
type CDNOpt func(config *CDNConfig)
func WithSize(size int) CDNOpt {
return func(config *CDNConfig) {
config.Values["size"] = size
}
}
func WithFormat(format ImageFormat) CDNOpt {
return func(config *CDNConfig) {
config.Format = format
}
}
func formatAssetURL(cdnRoute *CDNEndpoint, opts []CDNOpt, params ...any) string {
config := DefaultCDNConfig()
config.Apply(opts)
var lastStringParam string
lastParam := params[len(params)-1]
if str, ok := lastParam.(string); ok {
if str == "" {
return ""
}
lastStringParam = str
} else if ptrStr, ok := lastParam.(*string); ok {
if ptrStr == nil {
return ""
}
lastStringParam = *ptrStr
}
if strings.HasPrefix(lastStringParam, "a_") && !config.Format.Animated() {
config.Format = ImageFormatGIF
}
return cdnRoute.URL(config.Format, config.Values, params...)
}