initial commit
This commit is contained in:
commit
313bd35b23
8 changed files with 591 additions and 0 deletions
9
channel.go
Normal file
9
channel.go
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
type Channel struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Channel) BucketID() string {
|
||||||
|
return u.ID
|
||||||
|
}
|
||||||
205
component.go
Normal file
205
component.go
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
type ComponentType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ComponentTypeActionRow ComponentType = 1
|
||||||
|
ComponentTypeButton ComponentType = 2
|
||||||
|
ComponentTypeSection ComponentType = 9
|
||||||
|
ComponentTypeText ComponentType = 10
|
||||||
|
ComponentTypeThumbnail ComponentType = 11
|
||||||
|
ComponentTypeSep ComponentType = 14
|
||||||
|
ComponentTypeContainer ComponentType = 17
|
||||||
|
)
|
||||||
|
|
||||||
|
type BaseComponent struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
Type ComponentType `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComponentLike interface {
|
||||||
|
Base() BaseComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccessoryLike interface {
|
||||||
|
AccessoryLike() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type TextDisplayLike interface {
|
||||||
|
TextDisplayLike() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActionRowComponent struct {
|
||||||
|
BaseComponent
|
||||||
|
Components []ComponentLike `json:"components"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ActionRowComponent) Base() BaseComponent {
|
||||||
|
return t.BaseComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActionRow(components ...ComponentLike) ActionRowComponent {
|
||||||
|
return ActionRowComponent{
|
||||||
|
BaseComponent: BaseComponent{
|
||||||
|
Type: ComponentTypeActionRow,
|
||||||
|
},
|
||||||
|
Components: components,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TextComponent struct {
|
||||||
|
BaseComponent
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TextComponent) Base() BaseComponent {
|
||||||
|
return t.BaseComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TextComponent) TextDisplayLike() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContainerComponent struct {
|
||||||
|
BaseComponent
|
||||||
|
Components any `json:"components"`
|
||||||
|
Color *int `json:"accent_color,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ContainerComponent) Base() BaseComponent {
|
||||||
|
return t.BaseComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnfurledMedia struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ThumbnailComponent struct {
|
||||||
|
BaseComponent
|
||||||
|
Media UnfurledMedia `json:"unfurledMedia"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ThumbnailComponent) Base() BaseComponent {
|
||||||
|
return t.BaseComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ThumbnailComponent) AccessoryLike() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
type SectionComponent struct {
|
||||||
|
BaseComponent
|
||||||
|
Components []TextDisplayLike `json:"components"`
|
||||||
|
Accessory AccessoryLike `json:"accessory"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t SectionComponent) Base() BaseComponent {
|
||||||
|
return t.BaseComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
func Section(text []TextDisplayLike, accessory AccessoryLike) SectionComponent {
|
||||||
|
return SectionComponent{
|
||||||
|
BaseComponent: BaseComponent{
|
||||||
|
Type: ComponentTypeSection,
|
||||||
|
},
|
||||||
|
Components: text,
|
||||||
|
Accessory: accessory,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type SeparatorComponent struct {
|
||||||
|
BaseComponent
|
||||||
|
Divider bool `json:"divider"`
|
||||||
|
Spacing int `json:"spacing"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t SeparatorComponent) Base() BaseComponent {
|
||||||
|
return t.BaseComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
type ButtonStyle int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ButtonStylePrimary ButtonStyle = iota + 1
|
||||||
|
ButtonStyleSecondary
|
||||||
|
ButtonStyleSuccess
|
||||||
|
ButtonStyleDanger
|
||||||
|
ButtonStyleLink
|
||||||
|
ButtonStylePremium
|
||||||
|
)
|
||||||
|
|
||||||
|
type ButtonComponent struct {
|
||||||
|
BaseComponent
|
||||||
|
|
||||||
|
Style ButtonStyle `json:"style"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
|
||||||
|
Emoji *PartialEmoji `json:"emoji,omitempty"`
|
||||||
|
CustomID string `json:"custom_id,omitempty"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ButtonComponent) Base() BaseComponent {
|
||||||
|
return t.BaseComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ButtonComponent) AccessoryLike() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func Container(id int, color *int, components ...any) ContainerComponent {
|
||||||
|
return ContainerComponent{
|
||||||
|
BaseComponent: BaseComponent{
|
||||||
|
ID: &id,
|
||||||
|
Type: ComponentTypeContainer,
|
||||||
|
},
|
||||||
|
Color: color,
|
||||||
|
Components: components,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Text(id int, content string) TextComponent {
|
||||||
|
return TextComponent{
|
||||||
|
BaseComponent: BaseComponent{
|
||||||
|
ID: &id,
|
||||||
|
Type: ComponentTypeText,
|
||||||
|
},
|
||||||
|
Content: content,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Separator(id int, divider bool, spacing int) SeparatorComponent {
|
||||||
|
return SeparatorComponent{
|
||||||
|
BaseComponent: BaseComponent{
|
||||||
|
ID: &id,
|
||||||
|
Type: ComponentTypeSep,
|
||||||
|
},
|
||||||
|
Divider: divider,
|
||||||
|
Spacing: spacing,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Button(style ButtonStyle, customID, label string, emoji *PartialEmoji) ButtonComponent {
|
||||||
|
return ButtonComponent{
|
||||||
|
BaseComponent: BaseComponent{
|
||||||
|
Type: ComponentTypeButton,
|
||||||
|
},
|
||||||
|
Style: style,
|
||||||
|
CustomID: customID,
|
||||||
|
Label: label,
|
||||||
|
Emoji: emoji,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func LinkButton(label, url string, emoji *PartialEmoji) ButtonComponent {
|
||||||
|
return ButtonComponent{
|
||||||
|
BaseComponent: BaseComponent{
|
||||||
|
Type: ComponentTypeButton,
|
||||||
|
},
|
||||||
|
Style: ButtonStyleLink,
|
||||||
|
URL: url,
|
||||||
|
Label: label,
|
||||||
|
Emoji: emoji,
|
||||||
|
}
|
||||||
|
}
|
||||||
30
emoji.go
Normal file
30
emoji.go
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
type PartialEmoji struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *PartialEmoji) BucketID() string {
|
||||||
|
return u.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
type Emoji struct {
|
||||||
|
PartialEmoji
|
||||||
|
Roles []string `json:"roles"`
|
||||||
|
User any `json:"user,omitempty"` // TODO: User object
|
||||||
|
RequireColons bool `json:"requires_colons"`
|
||||||
|
Managed bool `json:"managed"`
|
||||||
|
Animated bool `json:"animated"`
|
||||||
|
Available bool `json:"available"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Emoji) BucketID() string {
|
||||||
|
return u.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
func StandardEmoji(emoji string) *PartialEmoji {
|
||||||
|
return &PartialEmoji{
|
||||||
|
Name: emoji,
|
||||||
|
}
|
||||||
|
}
|
||||||
29
guild.go
Normal file
29
guild.go
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Guild struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GuildMemberFlags int
|
||||||
|
|
||||||
|
const (
|
||||||
|
GuildMemberFlagsDidRejoin GuildMemberFlags = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
type GuildMember struct {
|
||||||
|
User User `json:"user"`
|
||||||
|
Nick string `json:"nick"`
|
||||||
|
Avatar string `json:"avatar"`
|
||||||
|
Banner string `json:"banner"`
|
||||||
|
Roles []string `json:"roles"`
|
||||||
|
JoinedAt time.Time `json:"joined_at"`
|
||||||
|
PremiumSince time.Time `json:"premium_since"`
|
||||||
|
Deaf bool `json:"deaf"`
|
||||||
|
Mute bool `json:"mute"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Guild) BucketID() string {
|
||||||
|
return u.ID
|
||||||
|
}
|
||||||
34
http.go
Normal file
34
http.go
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Identifiable interface {
|
||||||
|
BucketID() string
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestWithToken(
|
||||||
|
token string,
|
||||||
|
client *http.Client,
|
||||||
|
method, url string,
|
||||||
|
body any,
|
||||||
|
) (*http.Response, error) {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := json.NewEncoder(buf).Encode(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(method, url, buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Authorization", "Bot "+token)
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
return http.DefaultClient.Do(req)
|
||||||
|
}
|
||||||
133
interaction.go
Normal file
133
interaction.go
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InteractionContextType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
InteractionContextTypeGuild InteractionContextType = iota
|
||||||
|
InteractionContextTypeBotDM
|
||||||
|
InteractionContextTypePrivateChannel
|
||||||
|
)
|
||||||
|
|
||||||
|
type InteractionType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
InteractionTypePing InteractionType = iota + 1
|
||||||
|
InteractionTypeApplicationCommand
|
||||||
|
InteractionTypeMessageComponent
|
||||||
|
InteractionTypeApplicationCommandAutocomplete
|
||||||
|
InteractionTypeModalSubmit
|
||||||
|
)
|
||||||
|
|
||||||
|
type Interaction[T any] struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
ApplicationID string `json:"application_id"`
|
||||||
|
Type InteractionType `json:"type"`
|
||||||
|
Data T `json:"data"`
|
||||||
|
Guild any `json:"guild"` // TODO: Partial guilds
|
||||||
|
GuildID string `json:"guild_id"`
|
||||||
|
Channel any `json:"channel"` // TODO: Partial channels
|
||||||
|
ChannelID string `json:"channel_id"`
|
||||||
|
Member GuildMember `json:"member"` // TODO: Guild member object
|
||||||
|
User User `json:"user"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
Message any `json:"message"` // TODO: Message object
|
||||||
|
AppPermissions string `json:"app_permissions"`
|
||||||
|
GuildLocale string `json:"guild_locale"`
|
||||||
|
Entitlements []any `json:"entitlements"` // TODO: Entitlements
|
||||||
|
|
||||||
|
Context InteractionContextType `json:"context"`
|
||||||
|
AttachmentSizeLimit int `json:"attachment_size_limit"`
|
||||||
|
|
||||||
|
AuthorizingIntegrationOwners map[string]any `json:"authorizing_integration_owners"` // TODO: Yeah maybe not?
|
||||||
|
|
||||||
|
followupCount int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Interaction[T]) CallbackURL() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"https://discord.com/api/v10/interactions/%s/%s/callback",
|
||||||
|
i.ID, i.Token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Interaction[T]) FollowupURL() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"https://discord.com/api/v10/webhooks/%s/%s", i.ApplicationID, i.Token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Interaction[T]) Reply(token string, message ComponentsV2Message) (*http.Response, error) {
|
||||||
|
return requestWithToken(
|
||||||
|
token, http.DefaultClient, "POST", i.CallbackURL(),
|
||||||
|
InteractionResponse[ComponentsV2Message]{
|
||||||
|
Type: InteractionResponseTypeChannelMessageWithSource,
|
||||||
|
Data: message,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Interaction[T]) Defer(token string) (*http.Response, error) {
|
||||||
|
return requestWithToken(
|
||||||
|
token, http.DefaultClient, "POST", i.CallbackURL(),
|
||||||
|
InteractionResponse[any]{
|
||||||
|
Type: InteractionResponseTypeDeferredChannelMessageWithSource,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Interaction[T]) Followup(msg ComponentsV2Message) (*http.Response, error) {
|
||||||
|
if i.followupCount >= 5 {
|
||||||
|
return nil, errors.New("too many followups")
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := json.NewEncoder(buf).Encode(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
url := "https://discord.com/api/v10/webhooks/" + i.ApplicationID + "/" + i.Token
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", url, buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
i.followupCount++
|
||||||
|
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type InteractionResponseType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
InteractionResponseTypePong InteractionResponseType = 1
|
||||||
|
|
||||||
|
InteractionResponseTypeChannelMessageWithSource InteractionResponseType = iota + 3
|
||||||
|
InteractionResponseTypeDeferredChannelMessageWithSource
|
||||||
|
InteractionResponseTypeDeferredUpdateMessage
|
||||||
|
InteractionResponseTypeUpdateMessage
|
||||||
|
InteractionResponseTypeApplicationCommandAutocompleteResult
|
||||||
|
InteractionResponseTypeModal
|
||||||
|
|
||||||
|
InteractionResponseTypePremiumRequired // deprecated
|
||||||
|
|
||||||
|
InteractionResponseTypeLaunchActivity InteractionResponseType = 12
|
||||||
|
)
|
||||||
|
|
||||||
|
type InteractionResponse[T any] struct {
|
||||||
|
Type InteractionResponseType `json:"type"`
|
||||||
|
Data T `json:"data,omitempty"`
|
||||||
|
}
|
||||||
27
message.go
Normal file
27
message.go
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
type MessageFlags int
|
||||||
|
|
||||||
|
const (
|
||||||
|
MessageFlagsEphemeral MessageFlags = 1 << 6
|
||||||
|
MessageFlagsComponentsV2 MessageFlags = 1 << 15
|
||||||
|
)
|
||||||
|
|
||||||
|
type ComponentsV2Message struct {
|
||||||
|
Components []ComponentLike `json:"components"`
|
||||||
|
Flags MessageFlags `json:"flags"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ComponentsMessage(components ...ComponentLike) ComponentsV2Message {
|
||||||
|
return ComponentsV2Message{
|
||||||
|
Components: components,
|
||||||
|
Flags: MessageFlagsComponentsV2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func EphemeralComponentsMessage(components ...ComponentLike) ComponentsV2Message {
|
||||||
|
return ComponentsV2Message{
|
||||||
|
Components: components,
|
||||||
|
Flags: MessageFlagsComponentsV2 | MessageFlagsEphemeral,
|
||||||
|
}
|
||||||
|
}
|
||||||
124
user.go
Normal file
124
user.go
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
package discord
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type CacheStatus int
|
||||||
|
|
||||||
|
const (
|
||||||
|
CacheStatusNotFound CacheStatus = iota
|
||||||
|
CacheStatusFound
|
||||||
|
CacheStatusRefresh
|
||||||
|
CacheStatusRemove
|
||||||
|
)
|
||||||
|
|
||||||
|
type cacheUser struct {
|
||||||
|
lastUpdated time.Time
|
||||||
|
user *User
|
||||||
|
remove bool // if true, references to this should be removed
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserCache struct {
|
||||||
|
guildID string
|
||||||
|
lastUpdated time.Time
|
||||||
|
frequency time.Duration
|
||||||
|
users map[string]*cacheUser
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserCache(guildID string, updateFrequency time.Duration) *UserCache {
|
||||||
|
return &UserCache{
|
||||||
|
guildID: guildID,
|
||||||
|
lastUpdated: time.Unix(0, 0),
|
||||||
|
frequency: updateFrequency,
|
||||||
|
users: make(map[string]*cacheUser),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserCache) Insert(user *User) {
|
||||||
|
cu, ok := u.users[user.ID]
|
||||||
|
if ok {
|
||||||
|
cu.user = user
|
||||||
|
cu.lastUpdated = time.Now()
|
||||||
|
cu.remove = false
|
||||||
|
}
|
||||||
|
u.users[user.ID] = &cacheUser{
|
||||||
|
user: user,
|
||||||
|
lastUpdated: time.Now(),
|
||||||
|
remove: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserCache) Find(userID string) (*User, CacheStatus) {
|
||||||
|
cu, ok := u.users[userID]
|
||||||
|
if !ok {
|
||||||
|
return nil, CacheStatusNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
if cu.remove {
|
||||||
|
return nil, CacheStatusRemove
|
||||||
|
}
|
||||||
|
|
||||||
|
if time.Since(cu.lastUpdated) > u.frequency {
|
||||||
|
return cu.user, CacheStatusRefresh
|
||||||
|
}
|
||||||
|
|
||||||
|
return cu.user, CacheStatusFound
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserFlags int
|
||||||
|
|
||||||
|
const (
|
||||||
|
UserFlagsStaff UserFlags = 1 << 1
|
||||||
|
UserFlagsPartner UserFlags = 1 << 2
|
||||||
|
UserFlagsHypesquad UserFlags = 1 << 3
|
||||||
|
UserFlagsBugHunterLevel1 UserFlags = 1 << 4
|
||||||
|
UserFlagsHypesquadOnlineHouse1 UserFlags = 1 << 6
|
||||||
|
UserFlagsHypesquadOnlineHouse2 UserFlags = 1 << 7
|
||||||
|
UserFlagsHypesquadOnlineHouse3 UserFlags = 1 << 8
|
||||||
|
UserFlagsPremiumEarlySupporter UserFlags = 1 << 9
|
||||||
|
UserFlagsTeamPseudoUser UserFlags = 1 << 10
|
||||||
|
UserFlagsBugHunterLevel2 UserFlags = 1 << 14
|
||||||
|
UserFlagsVerifiedBot UserFlags = 1 << 16
|
||||||
|
UserFlagsVerifiedDeveloper UserFlags = 1 << 17
|
||||||
|
UserFlagsCertifiedModerator UserFlags = 1 << 18
|
||||||
|
UserFlagsBotHTTPInteractions UserFlags = 1 << 19
|
||||||
|
UserFlagsActiveDeveloper UserFlags = 1 << 22
|
||||||
|
)
|
||||||
|
|
||||||
|
type PremiumType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
PremiumTypeNone PremiumType = iota
|
||||||
|
PremiumTypeNitroClassic
|
||||||
|
PremiumTypeNitro
|
||||||
|
PremiumTypeNitroBasic
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: more fields
|
||||||
|
type User struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
GlobalName string `json:"global_name"`
|
||||||
|
Avatar string `json:"avatar"`
|
||||||
|
Bot bool `json:"bot"`
|
||||||
|
System bool `json:"system"`
|
||||||
|
MFAEnabled bool `json:"mfa_enabled"`
|
||||||
|
Banner string `json:"banner"`
|
||||||
|
AccentColor int `json:"accent_color"`
|
||||||
|
Locale string `json:"locale"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Flags UserFlags `json:"flags"`
|
||||||
|
PublicFlags UserFlags `json:"public_flags"`
|
||||||
|
PremiumType PremiumType `json:"premium_type"`
|
||||||
|
|
||||||
|
AvatarDecorationData AvatarDecorationData `json:"avatar_decoration_data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) BucketID() string {
|
||||||
|
return u.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
type AvatarDecorationData struct {
|
||||||
|
Asset string `json:"asset"`
|
||||||
|
SkuID string `json:"sku_id"`
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue