Fancy replies using rich embeds on Discord side
Some checks failed
Development / golangci-lint (push) Has been cancelled
Development / test-build-upload (1.22.x, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
2025-11-03 15:17:34 -08:00
parent 186d28858b
commit f73bee90ab
17 changed files with 1706 additions and 128 deletions

View File

@@ -353,7 +353,15 @@ func (b *Bdiscord) handleEventBotUser(msg *config.Message, channelID string) (st
for _, msgPart := range msgParts { for _, msgPart := range msgParts {
m := discordgo.MessageSend{ m := discordgo.MessageSend{
Content: msg.Username + msgPart, Embeds: []*discordgo.MessageEmbed{
{
Description: msgPart,
Author: &discordgo.MessageEmbedAuthor{
Name: msg.Username,
IconURL: msg.Avatar,
},
},
},
AllowedMentions: b.getAllowedMentions(), AllowedMentions: b.getAllowedMentions(),
} }

View File

@@ -46,6 +46,7 @@ func (b *Bdiscord) maybeGetLocalAvatar(msg *config.Message) string {
func (b *Bdiscord) webhookSendTextOnly(msg *config.Message, channelID string) (string, error) { func (b *Bdiscord) webhookSendTextOnly(msg *config.Message, channelID string) (string, error) {
msgParts := helper.ClipOrSplitMessage(msg.Text, MessageLength, b.GetString("MessageClipped"), b.GetInt("MessageSplitMaxCount")) msgParts := helper.ClipOrSplitMessage(msg.Text, MessageLength, b.GetString("MessageClipped"), b.GetInt("MessageSplitMaxCount"))
msgIds := []string{} msgIds := []string{}
b.Log.Debugf("Final avatar URL: %s", msg.Avatar)
for _, msgPart := range msgParts { for _, msgPart := range msgParts {
res, err := b.transmitter.Send( res, err := b.transmitter.Send(
channelID, channelID,

2
go.mod
View File

@@ -6,7 +6,7 @@ require (
github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560 github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560
github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c
github.com/SevereCloud/vksdk/v2 v2.17.0 github.com/SevereCloud/vksdk/v2 v2.17.0
github.com/bwmarrin/discordgo v0.28.1 github.com/bwmarrin/discordgo v0.29.0
github.com/d5/tengo/v2 v2.17.0 github.com/d5/tengo/v2 v2.17.0
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/fsnotify/fsnotify v1.7.0 github.com/fsnotify/fsnotify v1.7.0

2
go.sum
View File

@@ -44,6 +44,8 @@ github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/bwmarrin/discordgo v0.28.1 h1:gXsuo2GBO7NbR6uqmrrBDplPUx2T3nzu775q/Rd1aG4= github.com/bwmarrin/discordgo v0.28.1 h1:gXsuo2GBO7NbR6uqmrrBDplPUx2T3nzu775q/Rd1aG4=
github.com/bwmarrin/discordgo v0.28.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= github.com/bwmarrin/discordgo v0.28.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
github.com/bwmarrin/discordgo v0.29.0 h1:FmWeXFaKUwrcL3Cx65c20bTRW+vOb6k8AnaP+EgjDno=
github.com/bwmarrin/discordgo v0.29.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=

View File

@@ -18,6 +18,13 @@ const (
RoleSelectMenuComponent ComponentType = 6 RoleSelectMenuComponent ComponentType = 6
MentionableSelectMenuComponent ComponentType = 7 MentionableSelectMenuComponent ComponentType = 7
ChannelSelectMenuComponent ComponentType = 8 ChannelSelectMenuComponent ComponentType = 8
SectionComponent ComponentType = 9
TextDisplayComponent ComponentType = 10
ThumbnailComponent ComponentType = 11
MediaGalleryComponent ComponentType = 12
FileComponentType ComponentType = 13
SeparatorComponent ComponentType = 14
ContainerComponent ComponentType = 17
) )
// MessageComponent is a base interface for all message components. // MessageComponent is a base interface for all message components.
@@ -50,6 +57,20 @@ func (umc *unmarshalableMessageComponent) UnmarshalJSON(src []byte) error {
umc.MessageComponent = &SelectMenu{} umc.MessageComponent = &SelectMenu{}
case TextInputComponent: case TextInputComponent:
umc.MessageComponent = &TextInput{} umc.MessageComponent = &TextInput{}
case SectionComponent:
umc.MessageComponent = &Section{}
case TextDisplayComponent:
umc.MessageComponent = &TextDisplay{}
case ThumbnailComponent:
umc.MessageComponent = &Thumbnail{}
case MediaGalleryComponent:
umc.MessageComponent = &MediaGallery{}
case FileComponentType:
umc.MessageComponent = &FileComponent{}
case SeparatorComponent:
umc.MessageComponent = &Separator{}
case ContainerComponent:
umc.MessageComponent = &Container{}
default: default:
return fmt.Errorf("unknown component type: %d", v.Type) return fmt.Errorf("unknown component type: %d", v.Type)
} }
@@ -66,9 +87,13 @@ func MessageComponentFromJSON(b []byte) (MessageComponent, error) {
return u.MessageComponent, nil return u.MessageComponent, nil
} }
// ActionsRow is a container for components within one row. // ActionsRow is a top-level container component for displaying a row of interactive components.
type ActionsRow struct { type ActionsRow struct {
// Can contain Button, SelectMenu and TextInput.
// NOTE: maximum of 5.
Components []MessageComponent `json:"components"` Components []MessageComponent `json:"components"`
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
} }
// MarshalJSON is a method for marshaling ActionsRow to a JSON object. // MarshalJSON is a method for marshaling ActionsRow to a JSON object.
@@ -86,13 +111,17 @@ func (r ActionsRow) MarshalJSON() ([]byte, error) {
// UnmarshalJSON is a helper function to unmarshal Actions Row. // UnmarshalJSON is a helper function to unmarshal Actions Row.
func (r *ActionsRow) UnmarshalJSON(data []byte) error { func (r *ActionsRow) UnmarshalJSON(data []byte) error {
type actionsRow ActionsRow
var v struct { var v struct {
actionsRow
RawComponents []unmarshalableMessageComponent `json:"components"` RawComponents []unmarshalableMessageComponent `json:"components"`
} }
err := json.Unmarshal(data, &v) err := json.Unmarshal(data, &v)
if err != nil { if err != nil {
return err return err
} }
*r = ActionsRow(v.actionsRow)
r.Components = make([]MessageComponent, len(v.RawComponents)) r.Components = make([]MessageComponent, len(v.RawComponents))
for i, v := range v.RawComponents { for i, v := range v.RawComponents {
r.Components[i] = v.MessageComponent r.Components[i] = v.MessageComponent
@@ -121,6 +150,8 @@ const (
DangerButton ButtonStyle = 4 DangerButton ButtonStyle = 4
// LinkButton is a special type of button which navigates to a URL. Has grey color. // LinkButton is a special type of button which navigates to a URL. Has grey color.
LinkButton ButtonStyle = 5 LinkButton ButtonStyle = 5
// PremiumButton is a special type of button with a blurple color that links to a SKU.
PremiumButton ButtonStyle = 6
) )
// ComponentEmoji represents button emoji, if it does have one. // ComponentEmoji represents button emoji, if it does have one.
@@ -140,6 +171,10 @@ type Button struct {
// NOTE: Only button with LinkButton style can have link. Also, URL is mutually exclusive with CustomID. // NOTE: Only button with LinkButton style can have link. Also, URL is mutually exclusive with CustomID.
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`
CustomID string `json:"custom_id,omitempty"` CustomID string `json:"custom_id,omitempty"`
// Identifier for a purchasable SKU. Only available when using premium-style buttons.
SKUID string `json:"sku_id,omitempty"`
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
} }
// MarshalJSON is a method for marshaling Button to a JSON object. // MarshalJSON is a method for marshaling Button to a JSON object.
@@ -226,6 +261,9 @@ type SelectMenu struct {
// NOTE: Can only be used in SelectMenu with Channel menu type. // NOTE: Can only be used in SelectMenu with Channel menu type.
ChannelTypes []ChannelType `json:"channel_types,omitempty"` ChannelTypes []ChannelType `json:"channel_types,omitempty"`
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
} }
// Type is a method to get the type of a component. // Type is a method to get the type of a component.
@@ -259,6 +297,9 @@ type TextInput struct {
Required bool `json:"required"` Required bool `json:"required"`
MinLength int `json:"min_length,omitempty"` MinLength int `json:"min_length,omitempty"`
MaxLength int `json:"max_length,omitempty"` MaxLength int `json:"max_length,omitempty"`
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
} }
// Type is a method to get the type of a component. // Type is a method to get the type of a component.
@@ -287,3 +328,277 @@ const (
TextInputShort TextInputStyle = 1 TextInputShort TextInputStyle = 1
TextInputParagraph TextInputStyle = 2 TextInputParagraph TextInputStyle = 2
) )
// Section is a top-level layout component that allows you to join text contextually with an accessory.
type Section struct {
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
// Array of text display components; max of 3.
Components []MessageComponent `json:"components"`
// Can be Button or Thumbnail
Accessory MessageComponent `json:"accessory"`
}
// UnmarshalJSON is a method for unmarshaling Section from JSON
func (s *Section) UnmarshalJSON(data []byte) error {
type section Section
var v struct {
section
RawComponents []unmarshalableMessageComponent `json:"components"`
RawAccessory unmarshalableMessageComponent `json:"accessory"`
}
err := json.Unmarshal(data, &v)
if err != nil {
return err
}
*s = Section(v.section)
s.Accessory = v.RawAccessory.MessageComponent
s.Components = make([]MessageComponent, len(v.RawComponents))
for i, v := range v.RawComponents {
s.Components[i] = v.MessageComponent
}
return nil
}
// Type is a method to get the type of a component.
func (Section) Type() ComponentType {
return SectionComponent
}
// MarshalJSON is a method for marshaling Section to a JSON object.
func (s Section) MarshalJSON() ([]byte, error) {
type section Section
return Marshal(struct {
section
Type ComponentType `json:"type"`
}{
section: section(s),
Type: s.Type(),
})
}
// TextDisplay is a top-level component that allows you to add markdown-formatted text to the message.
type TextDisplay struct {
Content string `json:"content"`
}
// Type is a method to get the type of a component.
func (TextDisplay) Type() ComponentType {
return TextDisplayComponent
}
// MarshalJSON is a method for marshaling TextDisplay to a JSON object.
func (t TextDisplay) MarshalJSON() ([]byte, error) {
type textDisplay TextDisplay
return Marshal(struct {
textDisplay
Type ComponentType `json:"type"`
}{
textDisplay: textDisplay(t),
Type: t.Type(),
})
}
// Thumbnail component can be used as an accessory for a section component.
type Thumbnail struct {
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
Media UnfurledMediaItem `json:"media"`
Description *string `json:"description,omitempty"`
Spoiler bool `json:"spoiler,omitemoty"`
}
// Type is a method to get the type of a component.
func (Thumbnail) Type() ComponentType {
return ThumbnailComponent
}
// MarshalJSON is a method for marshaling Thumbnail to a JSON object.
func (t Thumbnail) MarshalJSON() ([]byte, error) {
type thumbnail Thumbnail
return Marshal(struct {
thumbnail
Type ComponentType `json:"type"`
}{
thumbnail: thumbnail(t),
Type: t.Type(),
})
}
// MediaGallery is a top-level component allows you to group images, videos or gifs into a gallery grid.
type MediaGallery struct {
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
// Array of media gallery items; max of 10.
Items []MediaGalleryItem `json:"items"`
}
// Type is a method to get the type of a component.
func (MediaGallery) Type() ComponentType {
return MediaGalleryComponent
}
// MarshalJSON is a method for marshaling MediaGallery to a JSON object.
func (m MediaGallery) MarshalJSON() ([]byte, error) {
type mediaGallery MediaGallery
return Marshal(struct {
mediaGallery
Type ComponentType `json:"type"`
}{
mediaGallery: mediaGallery(m),
Type: m.Type(),
})
}
// MediaGalleryItem represents an item used in MediaGallery.
type MediaGalleryItem struct {
Media UnfurledMediaItem `json:"media"`
Description *string `json:"description,omitempty"`
Spoiler bool `json:"spoiler"`
}
// FileComponent is a top-level component that allows you to display an uploaded file as an attachment to the message and reference it in the component.
type FileComponent struct {
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
File UnfurledMediaItem `json:"file"`
Spoiler bool `json:"spoiler"`
}
// Type is a method to get the type of a component.
func (FileComponent) Type() ComponentType {
return FileComponentType
}
// MarshalJSON is a method for marshaling FileComponent to a JSON object.
func (f FileComponent) MarshalJSON() ([]byte, error) {
type fileComponent FileComponent
return Marshal(struct {
fileComponent
Type ComponentType `json:"type"`
}{
fileComponent: fileComponent(f),
Type: f.Type(),
})
}
// SeparatorSpacingSize represents spacing size around the separator.
type SeparatorSpacingSize uint
// Separator spacing sizes.
const (
SeparatorSpacingSizeSmall SeparatorSpacingSize = 1
SeparatorSpacingSizeLarge SeparatorSpacingSize = 2
)
// Separator is a top-level layout component that adds vertical padding and visual division between other components.
type Separator struct {
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
Divider *bool `json:"divider,omitempty"`
Spacing *SeparatorSpacingSize `json:"spacing,omitempty"`
}
// Type is a method to get the type of a component.
func (Separator) Type() ComponentType {
return SeparatorComponent
}
// MarshalJSON is a method for marshaling Separator to a JSON object.
func (s Separator) MarshalJSON() ([]byte, error) {
type separator Separator
return Marshal(struct {
separator
Type ComponentType `json:"type"`
}{
separator: separator(s),
Type: s.Type(),
})
}
// Container is a top-level layout component.
// Containers are visually distinct from surrounding components and have an optional customizable color bar (similar to embeds).
type Container struct {
// Unique identifier for the component; auto populated through increment if not provided.
ID int `json:"id,omitempty"`
AccentColor *int `json:"accent_color,omitempty"`
Spoiler bool `json:"spoiler"`
Components []MessageComponent `json:"components"`
}
// Type is a method to get the type of a component.
func (Container) Type() ComponentType {
return ContainerComponent
}
// UnmarshalJSON is a method for unmarshaling Container from JSON
func (c *Container) UnmarshalJSON(data []byte) error {
type container Container
var v struct {
container
RawComponents []unmarshalableMessageComponent `json:"components"`
}
err := json.Unmarshal(data, &v)
if err != nil {
return err
}
*c = Container(v.container)
c.Components = make([]MessageComponent, len(v.RawComponents))
for i, v := range v.RawComponents {
c.Components[i] = v.MessageComponent
}
return nil
}
// MarshalJSON is a method for marshaling Container to a JSON object.
func (c Container) MarshalJSON() ([]byte, error) {
type container Container
return Marshal(struct {
container
Type ComponentType `json:"type"`
}{
container: container(c),
Type: c.Type(),
})
}
// UnfurledMediaItem represents an unfurled media item.
type UnfurledMediaItem struct {
URL string `json:"url"`
}
// UnfurledMediaItemLoadingState is the loading state of the unfurled media item.
type UnfurledMediaItemLoadingState uint
// Unfurled media item loading states.
const (
UnfurledMediaItemLoadingStateUnknown UnfurledMediaItemLoadingState = 0
UnfurledMediaItemLoadingStateLoading UnfurledMediaItemLoadingState = 1
UnfurledMediaItemLoadingStateLoadingSuccess UnfurledMediaItemLoadingState = 2
UnfurledMediaItemLoadingStateLoadedNotFound UnfurledMediaItemLoadingState = 3
)
// ResolvedUnfurledMediaItem represents a resolved unfurled media item.
type ResolvedUnfurledMediaItem struct {
URL string `json:"url"`
ProxyURL string `json:"proxy_url"`
Width int `json:"width"`
Height int `json:"height"`
ContentType string `json:"content_type"`
}

View File

@@ -22,7 +22,7 @@ import (
) )
// VERSION of DiscordGo, follows Semantic Versioning. (http://semver.org/) // VERSION of DiscordGo, follows Semantic Versioning. (http://semver.org/)
const VERSION = "0.28.1" const VERSION = "0.29.0"
// New creates a new Discord session with provided token. // New creates a new Discord session with provided token.
// If the token is for a bot, it must be prefixed with "Bot " // If the token is for a bot, it must be prefixed with "Bot "

View File

@@ -33,6 +33,7 @@ var (
EndpointWebhooks = EndpointAPI + "webhooks/" EndpointWebhooks = EndpointAPI + "webhooks/"
EndpointStickers = EndpointAPI + "stickers/" EndpointStickers = EndpointAPI + "stickers/"
EndpointStageInstances = EndpointAPI + "stage-instances" EndpointStageInstances = EndpointAPI + "stage-instances"
EndpointSKUs = EndpointAPI + "skus"
EndpointCDN = "https://cdn.discordapp.com/" EndpointCDN = "https://cdn.discordapp.com/"
EndpointCDNAttachments = EndpointCDN + "attachments/" EndpointCDNAttachments = EndpointCDN + "attachments/"
@@ -114,6 +115,12 @@ var (
EndpointGuildMemberAvatarAnimated = func(gId, uID, aID string) string { EndpointGuildMemberAvatarAnimated = func(gId, uID, aID string) string {
return EndpointCDNGuilds + gId + "/users/" + uID + "/avatars/" + aID + ".gif" return EndpointCDNGuilds + gId + "/users/" + uID + "/avatars/" + aID + ".gif"
} }
EndpointGuildMemberBanner = func(gId, uID, hash string) string {
return EndpointCDNGuilds + gId + "/users/" + uID + "/banners/" + hash + ".png"
}
EndpointGuildMemberBannerAnimated = func(gId, uID, hash string) string {
return EndpointCDNGuilds + gId + "/users/" + uID + "/banners/" + hash + ".gif"
}
EndpointRoleIcon = func(rID, hash string) string { EndpointRoleIcon = func(rID, hash string) string {
return EndpointCDNRoleIcons + rID + "/" + hash + ".png" return EndpointCDNRoleIcons + rID + "/" + hash + ".png"
@@ -162,6 +169,37 @@ var (
return EndpointMessageReactions(cID, mID, eID) + "/" + uID return EndpointMessageReactions(cID, mID, eID) + "/" + uID
} }
EndpointPoll = func(cID, mID string) string {
return EndpointChannel(cID) + "/polls/" + mID
}
EndpointPollAnswerVoters = func(cID, mID string, aID int) string {
return EndpointPoll(cID, mID) + "/answers/" + strconv.Itoa(aID)
}
EndpointPollExpire = func(cID, mID string) string {
return EndpointPoll(cID, mID) + "/expire"
}
EndpointApplicationSKUs = func(aID string) string {
return EndpointApplication(aID) + "/skus"
}
EndpointEntitlements = func(aID string) string {
return EndpointApplication(aID) + "/entitlements"
}
EndpointEntitlement = func(aID, eID string) string {
return EndpointEntitlements(aID) + "/" + eID
}
EndpointEntitlementConsume = func(aID, eID string) string {
return EndpointEntitlement(aID, eID) + "/consume"
}
EndpointSubscriptions = func(skuID string) string {
return EndpointSKUs + "/" + skuID + "/subscriptions"
}
EndpointSubscription = func(skuID, subID string) string {
return EndpointSubscriptions(skuID) + "/" + subID
}
EndpointApplicationGlobalCommands = func(aID string) string { EndpointApplicationGlobalCommands = func(aID string) string {
return EndpointApplication(aID) + "/commands" return EndpointApplication(aID) + "/commands"
} }
@@ -208,6 +246,9 @@ var (
EndpointApplication = func(aID string) string { return EndpointApplications + "/" + aID } EndpointApplication = func(aID string) string { return EndpointApplications + "/" + aID }
EndpointApplicationRoleConnectionMetadata = func(aID string) string { return EndpointApplication(aID) + "/role-connections/metadata" } EndpointApplicationRoleConnectionMetadata = func(aID string) string { return EndpointApplication(aID) + "/role-connections/metadata" }
EndpointApplicationEmojis = func(aID string) string { return EndpointApplication(aID) + "/emojis" }
EndpointApplicationEmoji = func(aID, eID string) string { return EndpointApplication(aID) + "/emojis/" + eID }
EndpointOAuth2 = EndpointAPI + "oauth2/" EndpointOAuth2 = EndpointAPI + "oauth2/"
EndpointOAuth2Applications = EndpointOAuth2 + "applications" EndpointOAuth2Applications = EndpointOAuth2 + "applications"
EndpointOAuth2Application = func(aID string) string { return EndpointOAuth2Applications + "/" + aID } EndpointOAuth2Application = func(aID string) string { return EndpointOAuth2Applications + "/" + aID }

View File

@@ -18,6 +18,9 @@ const (
channelUpdateEventType = "CHANNEL_UPDATE" channelUpdateEventType = "CHANNEL_UPDATE"
connectEventType = "__CONNECT__" connectEventType = "__CONNECT__"
disconnectEventType = "__DISCONNECT__" disconnectEventType = "__DISCONNECT__"
entitlementCreateEventType = "ENTITLEMENT_CREATE"
entitlementDeleteEventType = "ENTITLEMENT_DELETE"
entitlementUpdateEventType = "ENTITLEMENT_UPDATE"
eventEventType = "__EVENT__" eventEventType = "__EVENT__"
guildAuditLogEntryCreateEventType = "GUILD_AUDIT_LOG_ENTRY_CREATE" guildAuditLogEntryCreateEventType = "GUILD_AUDIT_LOG_ENTRY_CREATE"
guildBanAddEventType = "GUILD_BAN_ADD" guildBanAddEventType = "GUILD_BAN_ADD"
@@ -38,13 +41,19 @@ const (
guildScheduledEventUpdateEventType = "GUILD_SCHEDULED_EVENT_UPDATE" guildScheduledEventUpdateEventType = "GUILD_SCHEDULED_EVENT_UPDATE"
guildScheduledEventUserAddEventType = "GUILD_SCHEDULED_EVENT_USER_ADD" guildScheduledEventUserAddEventType = "GUILD_SCHEDULED_EVENT_USER_ADD"
guildScheduledEventUserRemoveEventType = "GUILD_SCHEDULED_EVENT_USER_REMOVE" guildScheduledEventUserRemoveEventType = "GUILD_SCHEDULED_EVENT_USER_REMOVE"
guildStickersUpdateEventType = "GUILD_STICKERS_UPDATE"
guildUpdateEventType = "GUILD_UPDATE" guildUpdateEventType = "GUILD_UPDATE"
integrationCreateEventType = "INTEGRATION_CREATE"
integrationDeleteEventType = "INTEGRATION_DELETE"
integrationUpdateEventType = "INTEGRATION_UPDATE"
interactionCreateEventType = "INTERACTION_CREATE" interactionCreateEventType = "INTERACTION_CREATE"
inviteCreateEventType = "INVITE_CREATE" inviteCreateEventType = "INVITE_CREATE"
inviteDeleteEventType = "INVITE_DELETE" inviteDeleteEventType = "INVITE_DELETE"
messageCreateEventType = "MESSAGE_CREATE" messageCreateEventType = "MESSAGE_CREATE"
messageDeleteEventType = "MESSAGE_DELETE" messageDeleteEventType = "MESSAGE_DELETE"
messageDeleteBulkEventType = "MESSAGE_DELETE_BULK" messageDeleteBulkEventType = "MESSAGE_DELETE_BULK"
messagePollVoteAddEventType = "MESSAGE_POLL_VOTE_ADD"
messagePollVoteRemoveEventType = "MESSAGE_POLL_VOTE_REMOVE"
messageReactionAddEventType = "MESSAGE_REACTION_ADD" messageReactionAddEventType = "MESSAGE_REACTION_ADD"
messageReactionRemoveEventType = "MESSAGE_REACTION_REMOVE" messageReactionRemoveEventType = "MESSAGE_REACTION_REMOVE"
messageReactionRemoveAllEventType = "MESSAGE_REACTION_REMOVE_ALL" messageReactionRemoveAllEventType = "MESSAGE_REACTION_REMOVE_ALL"
@@ -57,6 +66,9 @@ const (
stageInstanceEventCreateEventType = "STAGE_INSTANCE_EVENT_CREATE" stageInstanceEventCreateEventType = "STAGE_INSTANCE_EVENT_CREATE"
stageInstanceEventDeleteEventType = "STAGE_INSTANCE_EVENT_DELETE" stageInstanceEventDeleteEventType = "STAGE_INSTANCE_EVENT_DELETE"
stageInstanceEventUpdateEventType = "STAGE_INSTANCE_EVENT_UPDATE" stageInstanceEventUpdateEventType = "STAGE_INSTANCE_EVENT_UPDATE"
subscriptionCreateEventType = "SUBSCRIPTION_CREATE"
subscriptionDeleteEventType = "SUBSCRIPTION_DELETE"
subscriptionUpdateEventType = "SUBSCRIPTION_UPDATE"
threadCreateEventType = "THREAD_CREATE" threadCreateEventType = "THREAD_CREATE"
threadDeleteEventType = "THREAD_DELETE" threadDeleteEventType = "THREAD_DELETE"
threadListSyncEventType = "THREAD_LIST_SYNC" threadListSyncEventType = "THREAD_LIST_SYNC"
@@ -280,6 +292,66 @@ func (eh disconnectEventHandler) Handle(s *Session, i interface{}) {
} }
} }
// entitlementCreateEventHandler is an event handler for EntitlementCreate events.
type entitlementCreateEventHandler func(*Session, *EntitlementCreate)
// Type returns the event type for EntitlementCreate events.
func (eh entitlementCreateEventHandler) Type() string {
return entitlementCreateEventType
}
// New returns a new instance of EntitlementCreate.
func (eh entitlementCreateEventHandler) New() interface{} {
return &EntitlementCreate{}
}
// Handle is the handler for EntitlementCreate events.
func (eh entitlementCreateEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*EntitlementCreate); ok {
eh(s, t)
}
}
// entitlementDeleteEventHandler is an event handler for EntitlementDelete events.
type entitlementDeleteEventHandler func(*Session, *EntitlementDelete)
// Type returns the event type for EntitlementDelete events.
func (eh entitlementDeleteEventHandler) Type() string {
return entitlementDeleteEventType
}
// New returns a new instance of EntitlementDelete.
func (eh entitlementDeleteEventHandler) New() interface{} {
return &EntitlementDelete{}
}
// Handle is the handler for EntitlementDelete events.
func (eh entitlementDeleteEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*EntitlementDelete); ok {
eh(s, t)
}
}
// entitlementUpdateEventHandler is an event handler for EntitlementUpdate events.
type entitlementUpdateEventHandler func(*Session, *EntitlementUpdate)
// Type returns the event type for EntitlementUpdate events.
func (eh entitlementUpdateEventHandler) Type() string {
return entitlementUpdateEventType
}
// New returns a new instance of EntitlementUpdate.
func (eh entitlementUpdateEventHandler) New() interface{} {
return &EntitlementUpdate{}
}
// Handle is the handler for EntitlementUpdate events.
func (eh entitlementUpdateEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*EntitlementUpdate); ok {
eh(s, t)
}
}
// eventEventHandler is an event handler for Event events. // eventEventHandler is an event handler for Event events.
type eventEventHandler func(*Session, *Event) type eventEventHandler func(*Session, *Event)
@@ -675,6 +747,26 @@ func (eh guildScheduledEventUserRemoveEventHandler) Handle(s *Session, i interfa
} }
} }
// guildStickersUpdateEventHandler is an event handler for GuildStickersUpdate events.
type guildStickersUpdateEventHandler func(*Session, *GuildStickersUpdate)
// Type returns the event type for GuildStickersUpdate events.
func (eh guildStickersUpdateEventHandler) Type() string {
return guildStickersUpdateEventType
}
// New returns a new instance of GuildStickersUpdate.
func (eh guildStickersUpdateEventHandler) New() interface{} {
return &GuildStickersUpdate{}
}
// Handle is the handler for GuildStickersUpdate events.
func (eh guildStickersUpdateEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*GuildStickersUpdate); ok {
eh(s, t)
}
}
// guildUpdateEventHandler is an event handler for GuildUpdate events. // guildUpdateEventHandler is an event handler for GuildUpdate events.
type guildUpdateEventHandler func(*Session, *GuildUpdate) type guildUpdateEventHandler func(*Session, *GuildUpdate)
@@ -695,6 +787,66 @@ func (eh guildUpdateEventHandler) Handle(s *Session, i interface{}) {
} }
} }
// integrationCreateEventHandler is an event handler for IntegrationCreate events.
type integrationCreateEventHandler func(*Session, *IntegrationCreate)
// Type returns the event type for IntegrationCreate events.
func (eh integrationCreateEventHandler) Type() string {
return integrationCreateEventType
}
// New returns a new instance of IntegrationCreate.
func (eh integrationCreateEventHandler) New() interface{} {
return &IntegrationCreate{}
}
// Handle is the handler for IntegrationCreate events.
func (eh integrationCreateEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*IntegrationCreate); ok {
eh(s, t)
}
}
// integrationDeleteEventHandler is an event handler for IntegrationDelete events.
type integrationDeleteEventHandler func(*Session, *IntegrationDelete)
// Type returns the event type for IntegrationDelete events.
func (eh integrationDeleteEventHandler) Type() string {
return integrationDeleteEventType
}
// New returns a new instance of IntegrationDelete.
func (eh integrationDeleteEventHandler) New() interface{} {
return &IntegrationDelete{}
}
// Handle is the handler for IntegrationDelete events.
func (eh integrationDeleteEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*IntegrationDelete); ok {
eh(s, t)
}
}
// integrationUpdateEventHandler is an event handler for IntegrationUpdate events.
type integrationUpdateEventHandler func(*Session, *IntegrationUpdate)
// Type returns the event type for IntegrationUpdate events.
func (eh integrationUpdateEventHandler) Type() string {
return integrationUpdateEventType
}
// New returns a new instance of IntegrationUpdate.
func (eh integrationUpdateEventHandler) New() interface{} {
return &IntegrationUpdate{}
}
// Handle is the handler for IntegrationUpdate events.
func (eh integrationUpdateEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*IntegrationUpdate); ok {
eh(s, t)
}
}
// interactionCreateEventHandler is an event handler for InteractionCreate events. // interactionCreateEventHandler is an event handler for InteractionCreate events.
type interactionCreateEventHandler func(*Session, *InteractionCreate) type interactionCreateEventHandler func(*Session, *InteractionCreate)
@@ -815,6 +967,46 @@ func (eh messageDeleteBulkEventHandler) Handle(s *Session, i interface{}) {
} }
} }
// messagePollVoteAddEventHandler is an event handler for MessagePollVoteAdd events.
type messagePollVoteAddEventHandler func(*Session, *MessagePollVoteAdd)
// Type returns the event type for MessagePollVoteAdd events.
func (eh messagePollVoteAddEventHandler) Type() string {
return messagePollVoteAddEventType
}
// New returns a new instance of MessagePollVoteAdd.
func (eh messagePollVoteAddEventHandler) New() interface{} {
return &MessagePollVoteAdd{}
}
// Handle is the handler for MessagePollVoteAdd events.
func (eh messagePollVoteAddEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*MessagePollVoteAdd); ok {
eh(s, t)
}
}
// messagePollVoteRemoveEventHandler is an event handler for MessagePollVoteRemove events.
type messagePollVoteRemoveEventHandler func(*Session, *MessagePollVoteRemove)
// Type returns the event type for MessagePollVoteRemove events.
func (eh messagePollVoteRemoveEventHandler) Type() string {
return messagePollVoteRemoveEventType
}
// New returns a new instance of MessagePollVoteRemove.
func (eh messagePollVoteRemoveEventHandler) New() interface{} {
return &MessagePollVoteRemove{}
}
// Handle is the handler for MessagePollVoteRemove events.
func (eh messagePollVoteRemoveEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*MessagePollVoteRemove); ok {
eh(s, t)
}
}
// messageReactionAddEventHandler is an event handler for MessageReactionAdd events. // messageReactionAddEventHandler is an event handler for MessageReactionAdd events.
type messageReactionAddEventHandler func(*Session, *MessageReactionAdd) type messageReactionAddEventHandler func(*Session, *MessageReactionAdd)
@@ -1050,6 +1242,66 @@ func (eh stageInstanceEventUpdateEventHandler) Handle(s *Session, i interface{})
} }
} }
// subscriptionCreateEventHandler is an event handler for SubscriptionCreate events.
type subscriptionCreateEventHandler func(*Session, *SubscriptionCreate)
// Type returns the event type for SubscriptionCreate events.
func (eh subscriptionCreateEventHandler) Type() string {
return subscriptionCreateEventType
}
// New returns a new instance of SubscriptionCreate.
func (eh subscriptionCreateEventHandler) New() interface{} {
return &SubscriptionCreate{}
}
// Handle is the handler for SubscriptionCreate events.
func (eh subscriptionCreateEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*SubscriptionCreate); ok {
eh(s, t)
}
}
// subscriptionDeleteEventHandler is an event handler for SubscriptionDelete events.
type subscriptionDeleteEventHandler func(*Session, *SubscriptionDelete)
// Type returns the event type for SubscriptionDelete events.
func (eh subscriptionDeleteEventHandler) Type() string {
return subscriptionDeleteEventType
}
// New returns a new instance of SubscriptionDelete.
func (eh subscriptionDeleteEventHandler) New() interface{} {
return &SubscriptionDelete{}
}
// Handle is the handler for SubscriptionDelete events.
func (eh subscriptionDeleteEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*SubscriptionDelete); ok {
eh(s, t)
}
}
// subscriptionUpdateEventHandler is an event handler for SubscriptionUpdate events.
type subscriptionUpdateEventHandler func(*Session, *SubscriptionUpdate)
// Type returns the event type for SubscriptionUpdate events.
func (eh subscriptionUpdateEventHandler) Type() string {
return subscriptionUpdateEventType
}
// New returns a new instance of SubscriptionUpdate.
func (eh subscriptionUpdateEventHandler) New() interface{} {
return &SubscriptionUpdate{}
}
// Handle is the handler for SubscriptionUpdate events.
func (eh subscriptionUpdateEventHandler) Handle(s *Session, i interface{}) {
if t, ok := i.(*SubscriptionUpdate); ok {
eh(s, t)
}
}
// threadCreateEventHandler is an event handler for ThreadCreate events. // threadCreateEventHandler is an event handler for ThreadCreate events.
type threadCreateEventHandler func(*Session, *ThreadCreate) type threadCreateEventHandler func(*Session, *ThreadCreate)
@@ -1296,6 +1548,12 @@ func handlerForInterface(handler interface{}) EventHandler {
return connectEventHandler(v) return connectEventHandler(v)
case func(*Session, *Disconnect): case func(*Session, *Disconnect):
return disconnectEventHandler(v) return disconnectEventHandler(v)
case func(*Session, *EntitlementCreate):
return entitlementCreateEventHandler(v)
case func(*Session, *EntitlementDelete):
return entitlementDeleteEventHandler(v)
case func(*Session, *EntitlementUpdate):
return entitlementUpdateEventHandler(v)
case func(*Session, *Event): case func(*Session, *Event):
return eventEventHandler(v) return eventEventHandler(v)
case func(*Session, *GuildAuditLogEntryCreate): case func(*Session, *GuildAuditLogEntryCreate):
@@ -1336,8 +1594,16 @@ func handlerForInterface(handler interface{}) EventHandler {
return guildScheduledEventUserAddEventHandler(v) return guildScheduledEventUserAddEventHandler(v)
case func(*Session, *GuildScheduledEventUserRemove): case func(*Session, *GuildScheduledEventUserRemove):
return guildScheduledEventUserRemoveEventHandler(v) return guildScheduledEventUserRemoveEventHandler(v)
case func(*Session, *GuildStickersUpdate):
return guildStickersUpdateEventHandler(v)
case func(*Session, *GuildUpdate): case func(*Session, *GuildUpdate):
return guildUpdateEventHandler(v) return guildUpdateEventHandler(v)
case func(*Session, *IntegrationCreate):
return integrationCreateEventHandler(v)
case func(*Session, *IntegrationDelete):
return integrationDeleteEventHandler(v)
case func(*Session, *IntegrationUpdate):
return integrationUpdateEventHandler(v)
case func(*Session, *InteractionCreate): case func(*Session, *InteractionCreate):
return interactionCreateEventHandler(v) return interactionCreateEventHandler(v)
case func(*Session, *InviteCreate): case func(*Session, *InviteCreate):
@@ -1350,6 +1616,10 @@ func handlerForInterface(handler interface{}) EventHandler {
return messageDeleteEventHandler(v) return messageDeleteEventHandler(v)
case func(*Session, *MessageDeleteBulk): case func(*Session, *MessageDeleteBulk):
return messageDeleteBulkEventHandler(v) return messageDeleteBulkEventHandler(v)
case func(*Session, *MessagePollVoteAdd):
return messagePollVoteAddEventHandler(v)
case func(*Session, *MessagePollVoteRemove):
return messagePollVoteRemoveEventHandler(v)
case func(*Session, *MessageReactionAdd): case func(*Session, *MessageReactionAdd):
return messageReactionAddEventHandler(v) return messageReactionAddEventHandler(v)
case func(*Session, *MessageReactionRemove): case func(*Session, *MessageReactionRemove):
@@ -1374,6 +1644,12 @@ func handlerForInterface(handler interface{}) EventHandler {
return stageInstanceEventDeleteEventHandler(v) return stageInstanceEventDeleteEventHandler(v)
case func(*Session, *StageInstanceEventUpdate): case func(*Session, *StageInstanceEventUpdate):
return stageInstanceEventUpdateEventHandler(v) return stageInstanceEventUpdateEventHandler(v)
case func(*Session, *SubscriptionCreate):
return subscriptionCreateEventHandler(v)
case func(*Session, *SubscriptionDelete):
return subscriptionDeleteEventHandler(v)
case func(*Session, *SubscriptionUpdate):
return subscriptionUpdateEventHandler(v)
case func(*Session, *ThreadCreate): case func(*Session, *ThreadCreate):
return threadCreateEventHandler(v) return threadCreateEventHandler(v)
case func(*Session, *ThreadDelete): case func(*Session, *ThreadDelete):
@@ -1411,6 +1687,9 @@ func init() {
registerInterfaceProvider(channelDeleteEventHandler(nil)) registerInterfaceProvider(channelDeleteEventHandler(nil))
registerInterfaceProvider(channelPinsUpdateEventHandler(nil)) registerInterfaceProvider(channelPinsUpdateEventHandler(nil))
registerInterfaceProvider(channelUpdateEventHandler(nil)) registerInterfaceProvider(channelUpdateEventHandler(nil))
registerInterfaceProvider(entitlementCreateEventHandler(nil))
registerInterfaceProvider(entitlementDeleteEventHandler(nil))
registerInterfaceProvider(entitlementUpdateEventHandler(nil))
registerInterfaceProvider(guildAuditLogEntryCreateEventHandler(nil)) registerInterfaceProvider(guildAuditLogEntryCreateEventHandler(nil))
registerInterfaceProvider(guildBanAddEventHandler(nil)) registerInterfaceProvider(guildBanAddEventHandler(nil))
registerInterfaceProvider(guildBanRemoveEventHandler(nil)) registerInterfaceProvider(guildBanRemoveEventHandler(nil))
@@ -1430,13 +1709,19 @@ func init() {
registerInterfaceProvider(guildScheduledEventUpdateEventHandler(nil)) registerInterfaceProvider(guildScheduledEventUpdateEventHandler(nil))
registerInterfaceProvider(guildScheduledEventUserAddEventHandler(nil)) registerInterfaceProvider(guildScheduledEventUserAddEventHandler(nil))
registerInterfaceProvider(guildScheduledEventUserRemoveEventHandler(nil)) registerInterfaceProvider(guildScheduledEventUserRemoveEventHandler(nil))
registerInterfaceProvider(guildStickersUpdateEventHandler(nil))
registerInterfaceProvider(guildUpdateEventHandler(nil)) registerInterfaceProvider(guildUpdateEventHandler(nil))
registerInterfaceProvider(integrationCreateEventHandler(nil))
registerInterfaceProvider(integrationDeleteEventHandler(nil))
registerInterfaceProvider(integrationUpdateEventHandler(nil))
registerInterfaceProvider(interactionCreateEventHandler(nil)) registerInterfaceProvider(interactionCreateEventHandler(nil))
registerInterfaceProvider(inviteCreateEventHandler(nil)) registerInterfaceProvider(inviteCreateEventHandler(nil))
registerInterfaceProvider(inviteDeleteEventHandler(nil)) registerInterfaceProvider(inviteDeleteEventHandler(nil))
registerInterfaceProvider(messageCreateEventHandler(nil)) registerInterfaceProvider(messageCreateEventHandler(nil))
registerInterfaceProvider(messageDeleteEventHandler(nil)) registerInterfaceProvider(messageDeleteEventHandler(nil))
registerInterfaceProvider(messageDeleteBulkEventHandler(nil)) registerInterfaceProvider(messageDeleteBulkEventHandler(nil))
registerInterfaceProvider(messagePollVoteAddEventHandler(nil))
registerInterfaceProvider(messagePollVoteRemoveEventHandler(nil))
registerInterfaceProvider(messageReactionAddEventHandler(nil)) registerInterfaceProvider(messageReactionAddEventHandler(nil))
registerInterfaceProvider(messageReactionRemoveEventHandler(nil)) registerInterfaceProvider(messageReactionRemoveEventHandler(nil))
registerInterfaceProvider(messageReactionRemoveAllEventHandler(nil)) registerInterfaceProvider(messageReactionRemoveAllEventHandler(nil))
@@ -1448,6 +1733,9 @@ func init() {
registerInterfaceProvider(stageInstanceEventCreateEventHandler(nil)) registerInterfaceProvider(stageInstanceEventCreateEventHandler(nil))
registerInterfaceProvider(stageInstanceEventDeleteEventHandler(nil)) registerInterfaceProvider(stageInstanceEventDeleteEventHandler(nil))
registerInterfaceProvider(stageInstanceEventUpdateEventHandler(nil)) registerInterfaceProvider(stageInstanceEventUpdateEventHandler(nil))
registerInterfaceProvider(subscriptionCreateEventHandler(nil))
registerInterfaceProvider(subscriptionDeleteEventHandler(nil))
registerInterfaceProvider(subscriptionUpdateEventHandler(nil))
registerInterfaceProvider(threadCreateEventHandler(nil)) registerInterfaceProvider(threadCreateEventHandler(nil))
registerInterfaceProvider(threadDeleteEventHandler(nil)) registerInterfaceProvider(threadDeleteEventHandler(nil))
registerInterfaceProvider(threadListSyncEventHandler(nil)) registerInterfaceProvider(threadListSyncEventHandler(nil))

View File

@@ -53,6 +53,7 @@ type ChannelCreate struct {
// ChannelUpdate is the data for a ChannelUpdate event. // ChannelUpdate is the data for a ChannelUpdate event.
type ChannelUpdate struct { type ChannelUpdate struct {
*Channel *Channel
BeforeUpdate *Channel `json:"-"`
} }
// ChannelDelete is the data for a ChannelDelete event. // ChannelDelete is the data for a ChannelDelete event.
@@ -180,6 +181,12 @@ type GuildEmojisUpdate struct {
Emojis []*Emoji `json:"emojis"` Emojis []*Emoji `json:"emojis"`
} }
// A GuildStickersUpdate is the data for a GuildStickersUpdate event.
type GuildStickersUpdate struct {
GuildID string `json:"guild_id"`
Stickers []*Sticker `json:"stickers"`
}
// A GuildMembersChunk is the data for a GuildMembersChunk event. // A GuildMembersChunk is the data for a GuildMembersChunk event.
type GuildMembersChunk struct { type GuildMembersChunk struct {
GuildID string `json:"guild_id"` GuildID string `json:"guild_id"`
@@ -240,6 +247,25 @@ type GuildScheduledEventUserRemove struct {
GuildID string `json:"guild_id"` GuildID string `json:"guild_id"`
} }
// IntegrationCreate is the data for a IntegrationCreate event.
type IntegrationCreate struct {
*Integration
GuildID string `json:"guild_id"`
}
// IntegrationUpdate is the data for a IntegrationUpdate event.
type IntegrationUpdate struct {
*Integration
GuildID string `json:"guild_id"`
}
// IntegrationDelete is the data for a IntegrationDelete event.
type IntegrationDelete struct {
ID string `json:"id"`
GuildID string `json:"guild_id"`
ApplicationID string `json:"application_id,omitempty"`
}
// MessageCreate is the data for a MessageCreate event. // MessageCreate is the data for a MessageCreate event.
type MessageCreate struct { type MessageCreate struct {
*Message *Message
@@ -405,4 +431,57 @@ type AutoModerationActionExecution struct {
// GuildAuditLogEntryCreate is the data for a GuildAuditLogEntryCreate event. // GuildAuditLogEntryCreate is the data for a GuildAuditLogEntryCreate event.
type GuildAuditLogEntryCreate struct { type GuildAuditLogEntryCreate struct {
*AuditLogEntry *AuditLogEntry
GuildID string `json:"guild_id"`
}
// MessagePollVoteAdd is the data for a MessagePollVoteAdd event.
type MessagePollVoteAdd struct {
UserID string `json:"user_id"`
ChannelID string `json:"channel_id"`
MessageID string `json:"message_id"`
GuildID string `json:"guild_id,omitempty"`
AnswerID int `json:"answer_id"`
}
// MessagePollVoteRemove is the data for a MessagePollVoteRemove event.
type MessagePollVoteRemove struct {
UserID string `json:"user_id"`
ChannelID string `json:"channel_id"`
MessageID string `json:"message_id"`
GuildID string `json:"guild_id,omitempty"`
AnswerID int `json:"answer_id"`
}
// EntitlementCreate is the data for an EntitlementCreate event.
type EntitlementCreate struct {
*Entitlement
}
// EntitlementUpdate is the data for an EntitlementUpdate event.
type EntitlementUpdate struct {
*Entitlement
}
// EntitlementDelete is the data for an EntitlementDelete event.
// NOTE: Entitlements are not deleted when they expire.
type EntitlementDelete struct {
*Entitlement
}
// SubscriptionCreate is the data for an SubscriptionCreate event.
// https://discord.com/developers/docs/monetization/implementing-app-subscriptions#using-subscription-events-for-the-subscription-lifecycle
type SubscriptionCreate struct {
*Subscription
}
// SubscriptionUpdate is the data for an SubscriptionUpdate event.
// https://discord.com/developers/docs/monetization/implementing-app-subscriptions#using-subscription-events-for-the-subscription-lifecycle
type SubscriptionUpdate struct {
*Subscription
}
// SubscriptionDelete is the data for an SubscriptionDelete event.
// https://discord.com/developers/docs/monetization/implementing-app-subscriptions#using-subscription-events-for-the-subscription-lifecycle
type SubscriptionDelete struct {
*Subscription
} }

View File

@@ -38,12 +38,17 @@ type ApplicationCommand struct {
Type ApplicationCommandType `json:"type,omitempty"` Type ApplicationCommandType `json:"type,omitempty"`
Name string `json:"name"` Name string `json:"name"`
NameLocalizations *map[Locale]string `json:"name_localizations,omitempty"` NameLocalizations *map[Locale]string `json:"name_localizations,omitempty"`
// NOTE: DefaultPermission will be soon deprecated. Use DefaultMemberPermissions and DMPermission instead.
// NOTE: DefaultPermission will be soon deprecated. Use DefaultMemberPermissions and Contexts instead.
DefaultPermission *bool `json:"default_permission,omitempty"` DefaultPermission *bool `json:"default_permission,omitempty"`
DefaultMemberPermissions *int64 `json:"default_member_permissions,string,omitempty"` DefaultMemberPermissions *int64 `json:"default_member_permissions,string,omitempty"`
DMPermission *bool `json:"dm_permission,omitempty"`
NSFW *bool `json:"nsfw,omitempty"` NSFW *bool `json:"nsfw,omitempty"`
// Deprecated: use Contexts instead.
DMPermission *bool `json:"dm_permission,omitempty"`
Contexts *[]InteractionContextType `json:"contexts,omitempty"`
IntegrationTypes *[]ApplicationIntegrationType `json:"integration_types,omitempty"`
// NOTE: Chat commands only. Otherwise it mustn't be set. // NOTE: Chat commands only. Otherwise it mustn't be set.
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
@@ -200,6 +205,18 @@ func (t InteractionType) String() string {
return fmt.Sprintf("InteractionType(%d)", t) return fmt.Sprintf("InteractionType(%d)", t)
} }
// InteractionContextType represents the context in which interaction can be used or was triggered from.
type InteractionContextType uint
const (
// InteractionContextGuild indicates that interaction can be used within guilds.
InteractionContextGuild InteractionContextType = 0
// InteractionContextBotDM indicates that interaction can be used within DMs with the bot.
InteractionContextBotDM InteractionContextType = 1
// InteractionContextPrivateChannel indicates that interaction can be used within group DMs and DMs with other users.
InteractionContextPrivateChannel InteractionContextType = 2
)
// Interaction represents data of an interaction. // Interaction represents data of an interaction.
type Interaction struct { type Interaction struct {
ID string `json:"id"` ID string `json:"id"`
@@ -233,8 +250,15 @@ type Interaction struct {
// NOTE: this field is only filled when the interaction was invoked in a guild. // NOTE: this field is only filled when the interaction was invoked in a guild.
GuildLocale *Locale `json:"guild_locale"` GuildLocale *Locale `json:"guild_locale"`
Context InteractionContextType `json:"context"`
AuthorizingIntegrationOwners map[ApplicationIntegrationType]string `json:"authorizing_integration_owners"`
Token string `json:"token"` Token string `json:"token"`
Version int `json:"version"` Version int `json:"version"`
// Any entitlements for the invoking user, representing access to premium SKUs.
// NOTE: this field is only filled in monetized apps
Entitlements []*Entitlement `json:"entitlements"`
} }
type interaction Interaction type interaction Interaction
@@ -326,6 +350,18 @@ type ApplicationCommandInteractionData struct {
TargetID string `json:"target_id"` TargetID string `json:"target_id"`
} }
// GetOption finds and returns an application command option by its name.
func (d ApplicationCommandInteractionData) GetOption(name string) (option *ApplicationCommandInteractionDataOption) {
for _, opt := range d.Options {
if opt.Name == name {
option = opt
break
}
}
return
}
// ApplicationCommandInteractionDataResolved contains resolved data of command execution. // ApplicationCommandInteractionDataResolved contains resolved data of command execution.
// Partial Member objects are missing user, deaf and mute fields. // Partial Member objects are missing user, deaf and mute fields.
// Partial Channel objects only have id, name, type and permissions fields. // Partial Channel objects only have id, name, type and permissions fields.
@@ -408,6 +444,18 @@ type ApplicationCommandInteractionDataOption struct {
Focused bool `json:"focused,omitempty"` Focused bool `json:"focused,omitempty"`
} }
// GetOption finds and returns an application command option by its name.
func (o ApplicationCommandInteractionDataOption) GetOption(name string) (option *ApplicationCommandInteractionDataOption) {
for _, opt := range o.Options {
if opt.Name == name {
option = opt
break
}
}
return
}
// IntValue is a utility function for casting option value to integer // IntValue is a utility function for casting option value to integer
func (o ApplicationCommandInteractionDataOption) IntValue() int64 { func (o ApplicationCommandInteractionDataOption) IntValue() int64 {
if o.Type != ApplicationCommandOptionInteger { if o.Type != ApplicationCommandOptionInteger {
@@ -555,6 +603,7 @@ type InteractionResponseData struct {
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"` AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
Files []*File `json:"-"` Files []*File `json:"-"`
Attachments *[]*MessageAttachment `json:"attachments,omitempty"` Attachments *[]*MessageAttachment `json:"attachments,omitempty"`
Poll *Poll `json:"poll,omitempty"`
// NOTE: only MessageFlagsSuppressEmbeds and MessageFlagsEphemeral can be set. // NOTE: only MessageFlagsSuppressEmbeds and MessageFlagsEphemeral can be set.
Flags MessageFlags `json:"flags,omitempty"` Flags MessageFlags `json:"flags,omitempty"`

View File

@@ -135,11 +135,19 @@ type Message struct {
// If the field exists but is null, the referenced message was deleted. // If the field exists but is null, the referenced message was deleted.
ReferencedMessage *Message `json:"referenced_message"` ReferencedMessage *Message `json:"referenced_message"`
// The message associated with the message_reference.
// This is a minimal subset of fields in a message (e.g. Author is excluded)
// NOTE: This field is only returned when referenced when MessageReference.Type is MessageReferenceTypeForward.
MessageSnapshots []MessageSnapshot `json:"message_snapshots"`
// Deprecated, use InteractionMetadata.
// Is sent when the message is a response to an Interaction, without an existing message. // Is sent when the message is a response to an Interaction, without an existing message.
// This means responses to message component interactions do not include this property, // This means responses to message component interactions do not include this property,
// instead including a MessageReference, as components exist on preexisting messages. // instead including a MessageReference, as components exist on preexisting messages.
Interaction *MessageInteraction `json:"interaction"` Interaction *MessageInteraction `json:"interaction"`
InteractionMetadata *MessageInteractionMetadata `json:"interaction_metadata"`
// The flags of the message, which describe extra features of a message. // The flags of the message, which describe extra features of a message.
// This is a combination of bit masks; the presence of a certain permission can // This is a combination of bit masks; the presence of a certain permission can
// be checked by performing a bitwise AND between this int and the flag. // be checked by performing a bitwise AND between this int and the flag.
@@ -150,6 +158,9 @@ type Message struct {
// An array of StickerItem objects, representing sent stickers, if there were any. // An array of StickerItem objects, representing sent stickers, if there were any.
StickerItems []*StickerItem `json:"sticker_items"` StickerItems []*StickerItem `json:"sticker_items"`
// A poll object.
Poll *Poll `json:"poll"`
} }
// UnmarshalJSON is a helper function to unmarshal the Message. // UnmarshalJSON is a helper function to unmarshal the Message.
@@ -219,6 +230,8 @@ const (
MessageFlagsSuppressNotifications MessageFlags = 1 << 12 MessageFlagsSuppressNotifications MessageFlags = 1 << 12
// MessageFlagsIsVoiceMessage this message is a voice message. // MessageFlagsIsVoiceMessage this message is a voice message.
MessageFlagsIsVoiceMessage MessageFlags = 1 << 13 MessageFlagsIsVoiceMessage MessageFlags = 1 << 13
// MessageFlagsIsComponentsV2 this message uses the new components system. Disables the ability of sending `content` & `embeds`
MessageFlagsIsComponentsV2 MessageFlags = 1 << 15
) )
// File stores info about files you e.g. send in messages. // File stores info about files you e.g. send in messages.
@@ -239,6 +252,7 @@ type MessageSend struct {
Reference *MessageReference `json:"message_reference,omitempty"` Reference *MessageReference `json:"message_reference,omitempty"`
StickerIDs []string `json:"sticker_ids"` StickerIDs []string `json:"sticker_ids"`
Flags MessageFlags `json:"flags,omitempty"` Flags MessageFlags `json:"flags,omitempty"`
Poll *Poll `json:"poll,omitempty"`
// TODO: Remove this when compatibility is not required. // TODO: Remove this when compatibility is not required.
File *File `json:"-"` File *File `json:"-"`
@@ -338,17 +352,28 @@ type MessageAllowedMentions struct {
// A MessageAttachment stores data for message attachments. // A MessageAttachment stores data for message attachments.
type MessageAttachment struct { type MessageAttachment struct {
ID string `json:"id"` ID string `json:"id"`
URL string `json:"url"` URL string `json:"url"`
ProxyURL string `json:"proxy_url"` ProxyURL string `json:"proxy_url"`
Filename string `json:"filename"` Filename string `json:"filename"`
ContentType string `json:"content_type"` ContentType string `json:"content_type"`
Width int `json:"width"` Width int `json:"width"`
Height int `json:"height"` Height int `json:"height"`
Size int `json:"size"` Size int `json:"size"`
Ephemeral bool `json:"ephemeral"` Ephemeral bool `json:"ephemeral"`
DurationSecs float64 `json:"duration_secs"`
Waveform string `json:"waveform"`
Flags MessageAttachmentFlags `json:"flags"`
} }
// MessageAttachmentFlags is the flags of a message attachment.
type MessageAttachmentFlags int
// Valid MessageAttachmentFlags values.
const (
MessageAttachmentFlagsIsRemix MessageAttachmentFlags = 1 << 2
)
// MessageEmbedFooter is a part of a MessageEmbed struct. // MessageEmbedFooter is a part of a MessageEmbed struct.
type MessageEmbedFooter struct { type MessageEmbedFooter struct {
Text string `json:"text,omitempty"` Text string `json:"text,omitempty"`
@@ -464,16 +489,34 @@ type MessageApplication struct {
Name string `json:"name"` Name string `json:"name"`
} }
// MessageReference contains reference data sent with crossposted messages // MessageSnapshot represents a snapshot of a forwarded message.
type MessageReference struct { // https://discord.com/developers/docs/resources/message#message-snapshot-object
MessageID string `json:"message_id"` type MessageSnapshot struct {
ChannelID string `json:"channel_id,omitempty"` Message *Message `json:"message"`
GuildID string `json:"guild_id,omitempty"`
FailIfNotExists *bool `json:"fail_if_not_exists,omitempty"`
} }
func (m *Message) reference(failIfNotExists bool) *MessageReference { // MessageReferenceType is a type of MessageReference
type MessageReferenceType int
// Known valid MessageReferenceType values
// https://discord.com/developers/docs/resources/message#message-reference-types
const (
MessageReferenceTypeDefault MessageReferenceType = 0
MessageReferenceTypeForward MessageReferenceType = 1
)
// MessageReference contains reference data sent with crossposted messages
type MessageReference struct {
Type MessageReferenceType `json:"type,omitempty"`
MessageID string `json:"message_id"`
ChannelID string `json:"channel_id,omitempty"`
GuildID string `json:"guild_id,omitempty"`
FailIfNotExists *bool `json:"fail_if_not_exists,omitempty"`
}
func (m *Message) reference(refType MessageReferenceType, failIfNotExists bool) *MessageReference {
return &MessageReference{ return &MessageReference{
Type: refType,
GuildID: m.GuildID, GuildID: m.GuildID,
ChannelID: m.ChannelID, ChannelID: m.ChannelID,
MessageID: m.ID, MessageID: m.ID,
@@ -483,13 +526,18 @@ func (m *Message) reference(failIfNotExists bool) *MessageReference {
// Reference returns a MessageReference of the given message. // Reference returns a MessageReference of the given message.
func (m *Message) Reference() *MessageReference { func (m *Message) Reference() *MessageReference {
return m.reference(true) return m.reference(MessageReferenceTypeDefault, true)
} }
// SoftReference returns a MessageReference of the given message. // SoftReference returns a MessageReference of the given message.
// If the message doesn't exist it will instead be sent as a non-reply message. // If the message doesn't exist it will instead be sent as a non-reply message.
func (m *Message) SoftReference() *MessageReference { func (m *Message) SoftReference() *MessageReference {
return m.reference(false) return m.reference(MessageReferenceTypeDefault, false)
}
// Forward returns a MessageReference for a forwarded message.
func (m *Message) Forward() *MessageReference {
return m.reference(MessageReferenceTypeForward, true)
} }
// ContentWithMentionsReplaced will replace all @<id> mentions with the // ContentWithMentionsReplaced will replace all @<id> mentions with the
@@ -567,3 +615,24 @@ type MessageInteraction struct {
// Member is only present when the interaction is from a guild. // Member is only present when the interaction is from a guild.
Member *Member `json:"member"` Member *Member `json:"member"`
} }
// MessageInteractionMetadata contains metadata of an interaction, including relevant user info.
type MessageInteractionMetadata struct {
// ID of the interaction.
ID string `json:"id"`
// Type of the interaction.
Type InteractionType `json:"type"`
// User who triggered the interaction.
User *User `json:"user"`
// IDs for installation context(s) related to an interaction.
AuthorizingIntegrationOwners map[ApplicationIntegrationType]string `json:"authorizing_integration_owners"`
// ID of the original response message.
// NOTE: present only on followup messages.
OriginalResponseMessageID string `json:"original_response_message_id,omitempty"`
// ID of the message that contained interactive component.
// NOTE: present only on message component interactions.
InteractedMessageID string `json:"interacted_message_id,omitempty"`
// Metadata for interaction that was used to open a modal.
// NOTE: present only on modal submit interactions.
TriggeringInteractionMetadata *MessageInteractionMetadata `json:"triggering_interaction_metadata,omitempty"`
}

View File

@@ -178,13 +178,14 @@ func (s *Session) RequestWithBucketID(method, urlStr string, data interface{}, b
} }
} }
return s.request(method, urlStr, "application/json", body, bucketID, 0, options...) return s.RequestRaw(method, urlStr, "application/json", body, bucketID, 0, options...)
} }
// request makes a (GET/POST/...) Requests to Discord REST API. // RequestRaw makes a (GET/POST/...) Requests to Discord REST API.
// Preferably use the other Request* methods but this lets you send JSON directly if that's what you have.
// Sequence is the sequence number, if it fails with a 502 it will // Sequence is the sequence number, if it fails with a 502 it will
// retry with sequence+1 until it either succeeds or sequence >= session.MaxRestRetries // retry with sequence+1 until it either succeeds or sequence >= session.MaxRestRetries
func (s *Session) request(method, urlStr, contentType string, b []byte, bucketID string, sequence int, options ...RequestOption) (response []byte, err error) { func (s *Session) RequestRaw(method, urlStr, contentType string, b []byte, bucketID string, sequence int, options ...RequestOption) (response []byte, err error) {
if bucketID == "" { if bucketID == "" {
bucketID = strings.SplitN(urlStr, "?", 2)[0] bucketID = strings.SplitN(urlStr, "?", 2)[0]
} }
@@ -358,7 +359,7 @@ func (s *Session) UserAvatarDecode(u *User, options ...RequestOption) (img image
} }
// UserUpdate updates current user settings. // UserUpdate updates current user settings.
func (s *Session) UserUpdate(username, avatar string, options ...RequestOption) (st *User, err error) { func (s *Session) UserUpdate(username, avatar, banner string, options ...RequestOption) (st *User, err error) {
// NOTE: Avatar must be either the hash/id of existing Avatar or // NOTE: Avatar must be either the hash/id of existing Avatar or
// data:image/png;base64,BASE64_STRING_OF_NEW_AVATAR_PNG // data:image/png;base64,BASE64_STRING_OF_NEW_AVATAR_PNG
@@ -368,7 +369,8 @@ func (s *Session) UserUpdate(username, avatar string, options ...RequestOption)
data := struct { data := struct {
Username string `json:"username,omitempty"` Username string `json:"username,omitempty"`
Avatar string `json:"avatar,omitempty"` Avatar string `json:"avatar,omitempty"`
}{username, avatar} Banner string `json:"banner,omitempty"`
}{username, avatar, banner}
body, err := s.RequestWithBucketID("PATCH", EndpointUser("@me"), data, EndpointUsers, options...) body, err := s.RequestWithBucketID("PATCH", EndpointUser("@me"), data, EndpointUsers, options...)
if err != nil { if err != nil {
@@ -1011,7 +1013,7 @@ func (s *Session) GuildMemberRoleRemove(guildID, userID, roleID string, options
// guildID : The ID of a Guild. // guildID : The ID of a Guild.
func (s *Session) GuildChannels(guildID string, options ...RequestOption) (st []*Channel, err error) { func (s *Session) GuildChannels(guildID string, options ...RequestOption) (st []*Channel, err error) {
body, err := s.request("GET", EndpointGuildChannels(guildID), "", nil, EndpointGuildChannels(guildID), 0, options...) body, err := s.RequestRaw("GET", EndpointGuildChannels(guildID), "", nil, EndpointGuildChannels(guildID), 0, options...)
if err != nil { if err != nil {
return return
} }
@@ -1453,6 +1455,76 @@ func (s *Session) GuildEmojiDelete(guildID, emojiID string, options ...RequestOp
return return
} }
// ApplicationEmojis returns all emojis for the given application
// appID : ID of the application
func (s *Session) ApplicationEmojis(appID string, options ...RequestOption) (emojis []*Emoji, err error) {
body, err := s.RequestWithBucketID("GET", EndpointApplicationEmojis(appID), nil, EndpointApplicationEmojis(appID), options...)
if err != nil {
return
}
var temp struct {
Items []*Emoji `json:"items"`
}
err = unmarshal(body, &temp)
if err != nil {
return
}
emojis = temp.Items
return
}
// ApplicationEmoji returns the emoji for the given application.
// appID : ID of the application
// emojiID : ID of an Emoji to retrieve
func (s *Session) ApplicationEmoji(appID, emojiID string, options ...RequestOption) (emoji *Emoji, err error) {
var body []byte
body, err = s.RequestWithBucketID("GET", EndpointApplicationEmoji(appID, emojiID), nil, EndpointApplicationEmoji(appID, emojiID), options...)
if err != nil {
return
}
err = unmarshal(body, &emoji)
return
}
// ApplicationEmojiCreate creates a new Emoji for the given application.
// appID : ID of the application
// data : New Emoji data
func (s *Session) ApplicationEmojiCreate(appID string, data *EmojiParams, options ...RequestOption) (emoji *Emoji, err error) {
body, err := s.RequestWithBucketID("POST", EndpointApplicationEmojis(appID), data, EndpointApplicationEmojis(appID), options...)
if err != nil {
return
}
err = unmarshal(body, &emoji)
return
}
// ApplicationEmojiEdit modifies and returns updated Emoji for the given application.
// appID : ID of the application
// emojiID : ID of an Emoji
// data : Updated Emoji data
func (s *Session) ApplicationEmojiEdit(appID string, emojiID string, data *EmojiParams, options ...RequestOption) (emoji *Emoji, err error) {
body, err := s.RequestWithBucketID("PATCH", EndpointApplicationEmoji(appID, emojiID), data, EndpointApplicationEmojis(appID), options...)
if err != nil {
return
}
err = unmarshal(body, &emoji)
return
}
// ApplicationEmojiDelete deletes an Emoji for the given application.
// appID : ID of the application
// emojiID : ID of an Emoji
func (s *Session) ApplicationEmojiDelete(appID, emojiID string, options ...RequestOption) (err error) {
_, err = s.RequestWithBucketID("DELETE", EndpointApplicationEmoji(appID, emojiID), nil, EndpointApplicationEmojis(appID), options...)
return
}
// GuildTemplate returns a GuildTemplate for the given code // GuildTemplate returns a GuildTemplate for the given code
// templateCode: The Code of a GuildTemplate // templateCode: The Code of a GuildTemplate
func (s *Session) GuildTemplate(templateCode string, options ...RequestOption) (st *GuildTemplate, err error) { func (s *Session) GuildTemplate(templateCode string, options ...RequestOption) (st *GuildTemplate, err error) {
@@ -1712,7 +1784,7 @@ func (s *Session) ChannelMessageSendComplex(channelID string, data *MessageSend,
if encodeErr != nil { if encodeErr != nil {
return st, encodeErr return st, encodeErr
} }
response, err = s.request("POST", endpoint, contentType, body, endpoint, 0, options...) response, err = s.RequestRaw("POST", endpoint, contentType, body, endpoint, 0, options...)
} else { } else {
response, err = s.RequestWithBucketID("POST", endpoint, data, endpoint, options...) response, err = s.RequestWithBucketID("POST", endpoint, data, endpoint, options...)
} }
@@ -1824,7 +1896,7 @@ func (s *Session) ChannelMessageEditComplex(m *MessageEdit, options ...RequestOp
if encodeErr != nil { if encodeErr != nil {
return st, encodeErr return st, encodeErr
} }
response, err = s.request("PATCH", endpoint, contentType, body, EndpointChannelMessage(m.Channel, ""), 0, options...) response, err = s.RequestRaw("PATCH", endpoint, contentType, body, EndpointChannelMessage(m.Channel, ""), 0, options...)
} else { } else {
response, err = s.RequestWithBucketID("PATCH", endpoint, m, EndpointChannelMessage(m.Channel, ""), options...) response, err = s.RequestWithBucketID("PATCH", endpoint, m, EndpointChannelMessage(m.Channel, ""), options...)
} }
@@ -2361,7 +2433,7 @@ func (s *Session) webhookExecute(webhookID, token string, wait bool, threadID st
return st, encodeErr return st, encodeErr
} }
response, err = s.request("POST", uri, contentType, body, uri, 0, options...) response, err = s.RequestRaw("POST", uri, contentType, body, uri, 0, options...)
} else { } else {
response, err = s.RequestWithBucketID("POST", uri, data, uri, options...) response, err = s.RequestWithBucketID("POST", uri, data, uri, options...)
} }
@@ -2421,7 +2493,7 @@ func (s *Session) WebhookMessageEdit(webhookID, token, messageID string, data *W
return nil, err return nil, err
} }
response, err = s.request("PATCH", uri, contentType, body, uri, 0, options...) response, err = s.RequestRaw("PATCH", uri, contentType, body, uri, 0, options...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -2641,7 +2713,7 @@ func (s *Session) ForumThreadStartComplex(channelID string, threadData *ThreadSt
return th, encodeErr return th, encodeErr
} }
response, err = s.request("POST", endpoint, contentType, body, endpoint, 0, options...) response, err = s.RequestRaw("POST", endpoint, contentType, body, endpoint, 0, options...)
} else { } else {
response, err = s.RequestWithBucketID("POST", endpoint, data, endpoint, options...) response, err = s.RequestWithBucketID("POST", endpoint, data, endpoint, options...)
} }
@@ -3071,7 +3143,7 @@ func (s *Session) InteractionRespond(interaction *Interaction, resp *Interaction
return err return err
} }
_, err = s.request("POST", endpoint, contentType, body, endpoint, 0, options...) _, err = s.RequestRaw("POST", endpoint, contentType, body, endpoint, 0, options...)
return err return err
} }
@@ -3453,3 +3525,183 @@ func (s *Session) UserApplicationRoleConnectionUpdate(appID string, rconn *Appli
err = unmarshal(body, &st) err = unmarshal(body, &st)
return return
} }
// ----------------------------------------------------------------------
// Functions specific to polls
// ----------------------------------------------------------------------
// PollAnswerVoters returns users who voted for a particular answer in a poll on the specified message.
// channelID : ID of the channel.
// messageID : ID of the message.
// answerID : ID of the answer.
func (s *Session) PollAnswerVoters(channelID, messageID string, answerID int) (voters []*User, err error) {
endpoint := EndpointPollAnswerVoters(channelID, messageID, answerID)
var body []byte
body, err = s.RequestWithBucketID("GET", endpoint, nil, endpoint)
if err != nil {
return
}
var r struct {
Users []*User `json:"users"`
}
err = unmarshal(body, &r)
if err != nil {
return
}
voters = r.Users
return
}
// PollExpire expires poll on the specified message.
// channelID : ID of the channel.
// messageID : ID of the message.
func (s *Session) PollExpire(channelID, messageID string) (msg *Message, err error) {
endpoint := EndpointPollExpire(channelID, messageID)
var body []byte
body, err = s.RequestWithBucketID("POST", endpoint, nil, endpoint)
if err != nil {
return
}
err = unmarshal(body, &msg)
return
}
// ----------------------------------------------------------------------
// Functions specific to monetization
// ----------------------------------------------------------------------
// SKUs returns all SKUs for a given application.
// appID : The ID of the application.
func (s *Session) SKUs(appID string) (skus []*SKU, err error) {
endpoint := EndpointApplicationSKUs(appID)
body, err := s.RequestWithBucketID("GET", endpoint, nil, endpoint)
if err != nil {
return
}
err = unmarshal(body, &skus)
return
}
// Entitlements returns all Entitlements for a given app, active and expired.
// appID : The ID of the application.
// filterOptions : Optional filter options; otherwise set it to nil.
func (s *Session) Entitlements(appID string, filterOptions *EntitlementFilterOptions, options ...RequestOption) (entitlements []*Entitlement, err error) {
endpoint := EndpointEntitlements(appID)
queryParams := url.Values{}
if filterOptions != nil {
if filterOptions.UserID != "" {
queryParams.Set("user_id", filterOptions.UserID)
}
if filterOptions.SkuIDs != nil && len(filterOptions.SkuIDs) > 0 {
queryParams.Set("sku_ids", strings.Join(filterOptions.SkuIDs, ","))
}
if filterOptions.Before != nil {
queryParams.Set("before", filterOptions.Before.Format(time.RFC3339))
}
if filterOptions.After != nil {
queryParams.Set("after", filterOptions.After.Format(time.RFC3339))
}
if filterOptions.Limit > 0 {
queryParams.Set("limit", strconv.Itoa(filterOptions.Limit))
}
if filterOptions.GuildID != "" {
queryParams.Set("guild_id", filterOptions.GuildID)
}
if filterOptions.ExcludeEnded {
queryParams.Set("exclude_ended", "true")
}
}
body, err := s.RequestWithBucketID("GET", endpoint+"?"+queryParams.Encode(), nil, endpoint, options...)
if err != nil {
return
}
err = unmarshal(body, &entitlements)
return
}
// EntitlementConsume marks a given One-Time Purchase for the user as consumed.
func (s *Session) EntitlementConsume(appID, entitlementID string, options ...RequestOption) (err error) {
_, err = s.RequestWithBucketID("POST", EndpointEntitlementConsume(appID, entitlementID), nil, EndpointEntitlementConsume(appID, ""), options...)
return
}
// EntitlementTestCreate creates a test entitlement to a given SKU for a given guild or user.
// Discord will act as though that user or guild has entitlement to your premium offering.
func (s *Session) EntitlementTestCreate(appID string, data *EntitlementTest, options ...RequestOption) (err error) {
endpoint := EndpointEntitlements(appID)
_, err = s.RequestWithBucketID("POST", endpoint, data, endpoint, options...)
return
}
// EntitlementTestDelete deletes a currently-active test entitlement. Discord will act as though
// that user or guild no longer has entitlement to your premium offering.
func (s *Session) EntitlementTestDelete(appID, entitlementID string, options ...RequestOption) (err error) {
_, err = s.RequestWithBucketID("DELETE", EndpointEntitlement(appID, entitlementID), nil, EndpointEntitlement(appID, ""), options...)
return
}
// Subscriptions returns all subscriptions containing the SKU.
// skuID : The ID of the SKU.
// userID : User ID for which to return subscriptions. Required except for OAuth queries.
// before : Optional timestamp to retrieve subscriptions before this time.
// after : Optional timestamp to retrieve subscriptions after this time.
// limit : Optional maximum number of subscriptions to return (1-100, default 50).
func (s *Session) Subscriptions(skuID string, userID string, before, after *time.Time, limit int, options ...RequestOption) (subscriptions []*Subscription, err error) {
endpoint := EndpointSubscriptions(skuID)
queryParams := url.Values{}
if before != nil {
queryParams.Set("before", before.Format(time.RFC3339))
}
if after != nil {
queryParams.Set("after", after.Format(time.RFC3339))
}
if userID != "" {
queryParams.Set("user_id", userID)
}
if limit > 0 {
queryParams.Set("limit", strconv.Itoa(limit))
}
body, err := s.RequestWithBucketID("GET", endpoint+"?"+queryParams.Encode(), nil, endpoint, options...)
if err != nil {
return
}
err = unmarshal(body, &subscriptions)
return
}
// Subscription returns a subscription by its SKU and subscription ID.
// skuID : The ID of the SKU.
// subscriptionID : The ID of the subscription.
// userID : User ID for which to return the subscription. Required except for OAuth queries.
func (s *Session) Subscription(skuID, subscriptionID, userID string, options ...RequestOption) (subscription *Subscription, err error) {
endpoint := EndpointSubscription(skuID, subscriptionID)
queryParams := url.Values{}
if userID != "" {
// Unlike stated in the documentation, the user_id parameter is required here.
queryParams.Set("user_id", userID)
}
body, err := s.RequestWithBucketID("GET", endpoint+"?"+queryParams.Encode(), nil, endpoint, options...)
if err != nil {
return
}
err = unmarshal(body, &subscription)
return
}

View File

@@ -42,6 +42,7 @@ type State struct {
TrackChannels bool TrackChannels bool
TrackThreads bool TrackThreads bool
TrackEmojis bool TrackEmojis bool
TrackStickers bool
TrackMembers bool TrackMembers bool
TrackThreadMembers bool TrackThreadMembers bool
TrackRoles bool TrackRoles bool
@@ -63,6 +64,7 @@ func NewState() *State {
TrackChannels: true, TrackChannels: true,
TrackThreads: true, TrackThreads: true,
TrackEmojis: true, TrackEmojis: true,
TrackStickers: true,
TrackMembers: true, TrackMembers: true,
TrackThreadMembers: true, TrackThreadMembers: true,
TrackRoles: true, TrackRoles: true,
@@ -175,8 +177,8 @@ func (s *State) GuildRemove(guild *Guild) error {
// Guild gets a guild by ID. // Guild gets a guild by ID.
// Useful for querying if @me is in a guild: // Useful for querying if @me is in a guild:
// _, err := discordgo.Session.State.Guild(guildID) // _, err := discordgo.Session.State.Guild(guildID)
// isInGuild := err == nil // isInGuild := err == nil
func (s *State) Guild(guildID string) (*Guild, error) { func (s *State) Guild(guildID string) (*Guild, error) {
if s == nil { if s == nil {
return nil, ErrNilState return nil, ErrNilState
@@ -1050,12 +1052,28 @@ func (s *State) OnInterface(se *Session, i interface{}) (err error) {
defer s.Unlock() defer s.Unlock()
guild.Emojis = t.Emojis guild.Emojis = t.Emojis
} }
case *GuildStickersUpdate:
if s.TrackStickers {
var guild *Guild
guild, err = s.Guild(t.GuildID)
if err != nil {
return err
}
s.Lock()
defer s.Unlock()
guild.Stickers = t.Stickers
}
case *ChannelCreate: case *ChannelCreate:
if s.TrackChannels { if s.TrackChannels {
err = s.ChannelAdd(t.Channel) err = s.ChannelAdd(t.Channel)
} }
case *ChannelUpdate: case *ChannelUpdate:
if s.TrackChannels { if s.TrackChannels {
old, err := s.Channel(t.ID)
if err == nil {
oldCopy := *old
t.BeforeUpdate = &oldCopy
}
err = s.ChannelAdd(t.Channel) err = s.ChannelAdd(t.Channel)
} }
case *ChannelDelete: case *ChannelDelete:

View File

@@ -136,26 +136,49 @@ type Session struct {
wsMutex sync.Mutex wsMutex sync.Mutex
} }
// ApplicationIntegrationType dictates where application can be installed and its available interaction contexts.
type ApplicationIntegrationType uint
const (
// ApplicationIntegrationGuildInstall indicates that app is installable to guilds.
ApplicationIntegrationGuildInstall ApplicationIntegrationType = 0
// ApplicationIntegrationUserInstall indicates that app is installable to users.
ApplicationIntegrationUserInstall ApplicationIntegrationType = 1
)
// ApplicationInstallParams represents application's installation parameters
// for default in-app oauth2 authorization link.
type ApplicationInstallParams struct {
Scopes []string `json:"scopes"`
Permissions int64 `json:"permissions,string"`
}
// ApplicationIntegrationTypeConfig represents application's configuration for a particular integration type.
type ApplicationIntegrationTypeConfig struct {
OAuth2InstallParams *ApplicationInstallParams `json:"oauth2_install_params,omitempty"`
}
// Application stores values for a Discord Application // Application stores values for a Discord Application
type Application struct { type Application struct {
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
Name string `json:"name"` Name string `json:"name"`
Icon string `json:"icon,omitempty"` Icon string `json:"icon,omitempty"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
RPCOrigins []string `json:"rpc_origins,omitempty"` RPCOrigins []string `json:"rpc_origins,omitempty"`
BotPublic bool `json:"bot_public,omitempty"` BotPublic bool `json:"bot_public,omitempty"`
BotRequireCodeGrant bool `json:"bot_require_code_grant,omitempty"` BotRequireCodeGrant bool `json:"bot_require_code_grant,omitempty"`
TermsOfServiceURL string `json:"terms_of_service_url"` TermsOfServiceURL string `json:"terms_of_service_url"`
PrivacyProxyURL string `json:"privacy_policy_url"` PrivacyProxyURL string `json:"privacy_policy_url"`
Owner *User `json:"owner"` Owner *User `json:"owner"`
Summary string `json:"summary"` Summary string `json:"summary"`
VerifyKey string `json:"verify_key"` VerifyKey string `json:"verify_key"`
Team *Team `json:"team"` Team *Team `json:"team"`
GuildID string `json:"guild_id"` GuildID string `json:"guild_id"`
PrimarySKUID string `json:"primary_sku_id"` PrimarySKUID string `json:"primary_sku_id"`
Slug string `json:"slug"` Slug string `json:"slug"`
CoverImage string `json:"cover_image"` CoverImage string `json:"cover_image"`
Flags int `json:"flags,omitempty"` Flags int `json:"flags,omitempty"`
IntegrationTypesConfig map[ApplicationIntegrationType]*ApplicationIntegrationTypeConfig `json:"integration_types,omitempty"`
} }
// ApplicationRoleConnectionMetadataType represents the type of application role connection metadata. // ApplicationRoleConnectionMetadataType represents the type of application role connection metadata.
@@ -233,9 +256,13 @@ type IntegrationAccount struct {
} }
// A VoiceRegion stores data for a specific voice region server. // A VoiceRegion stores data for a specific voice region server.
// https://discord.com/developers/docs/resources/voice#voice-region-object
type VoiceRegion struct { type VoiceRegion struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Optimal bool `json:"optimal"`
Deprecated bool `json:"deprecated"`
Custom bool `json:"custom"`
} }
// InviteTargetType indicates the type of target of an invite // InviteTargetType indicates the type of target of an invite
@@ -585,7 +612,7 @@ type Emoji struct {
// EmojiRegex is the regex used to find and identify emojis in messages // EmojiRegex is the regex used to find and identify emojis in messages
var ( var (
EmojiRegex = regexp.MustCompile(`<(a|):[A-z0-9_~]+:[0-9]{18,20}>`) EmojiRegex = regexp.MustCompile(`<(a|):[A-Za-z0-9_~]+:[0-9]{18,20}>`)
) )
// MessageFormat returns a correctly formatted Emoji for use in Message content and embeds // MessageFormat returns a correctly formatted Emoji for use in Message content and embeds
@@ -620,6 +647,7 @@ type EmojiParams struct {
// NOTE: can be only set on creation. // NOTE: can be only set on creation.
Image string `json:"image,omitempty"` Image string `json:"image,omitempty"`
// Roles for which this emoji will be available. // Roles for which this emoji will be available.
// NOTE: can not be used with application emoji endpoints.
Roles []string `json:"roles,omitempty"` Roles []string `json:"roles,omitempty"`
} }
@@ -1291,27 +1319,35 @@ type GuildFeature string
// Constants for GuildFeature // Constants for GuildFeature
const ( const (
GuildFeatureAnimatedBanner GuildFeature = "ANIMATED_BANNER" GuildFeatureAnimatedBanner GuildFeature = "ANIMATED_BANNER"
GuildFeatureAnimatedIcon GuildFeature = "ANIMATED_ICON" GuildFeatureAnimatedIcon GuildFeature = "ANIMATED_ICON"
GuildFeatureAutoModeration GuildFeature = "AUTO_MODERATION" GuildFeatureApplicationCommandPermissionV2 GuildFeature = "APPLICATION_COMMAND_PERMISSIONS_V2"
GuildFeatureBanner GuildFeature = "BANNER" GuildFeatureAutoModeration GuildFeature = "AUTO_MODERATION"
GuildFeatureCommunity GuildFeature = "COMMUNITY" GuildFeatureBanner GuildFeature = "BANNER"
GuildFeatureDiscoverable GuildFeature = "DISCOVERABLE" GuildFeatureCommunity GuildFeature = "COMMUNITY"
GuildFeatureFeaturable GuildFeature = "FEATURABLE" GuildFeatureCreatorMonetizableProvisional GuildFeature = "CREATOR_MONETIZABLE_PROVISIONAL"
GuildFeatureInviteSplash GuildFeature = "INVITE_SPLASH" GuildFeatureCreatorStorePage GuildFeature = "CREATOR_STORE_PAGE"
GuildFeatureMemberVerificationGateEnabled GuildFeature = "MEMBER_VERIFICATION_GATE_ENABLED" GuildFeatureDeveloperSupportServer GuildFeature = "DEVELOPER_SUPPORT_SERVER"
GuildFeatureMonetizationEnabled GuildFeature = "MONETIZATION_ENABLED" GuildFeatureDiscoverable GuildFeature = "DISCOVERABLE"
GuildFeatureMoreStickers GuildFeature = "MORE_STICKERS" GuildFeatureFeaturable GuildFeature = "FEATURABLE"
GuildFeatureNews GuildFeature = "NEWS" GuildFeatureInvitesDisabled GuildFeature = "INVITES_DISABLED"
GuildFeaturePartnered GuildFeature = "PARTNERED" GuildFeatureInviteSplash GuildFeature = "INVITE_SPLASH"
GuildFeaturePreviewEnabled GuildFeature = "PREVIEW_ENABLED" GuildFeatureMemberVerificationGateEnabled GuildFeature = "MEMBER_VERIFICATION_GATE_ENABLED"
GuildFeaturePrivateThreads GuildFeature = "PRIVATE_THREADS" GuildFeatureMoreSoundboard GuildFeature = "MORE_SOUNDBOARD"
GuildFeatureRoleIcons GuildFeature = "ROLE_ICONS" GuildFeatureMoreStickers GuildFeature = "MORE_STICKERS"
GuildFeatureTicketedEventsEnabled GuildFeature = "TICKETED_EVENTS_ENABLED" GuildFeatureNews GuildFeature = "NEWS"
GuildFeatureVanityURL GuildFeature = "VANITY_URL" GuildFeaturePartnered GuildFeature = "PARTNERED"
GuildFeatureVerified GuildFeature = "VERIFIED" GuildFeaturePreviewEnabled GuildFeature = "PREVIEW_ENABLED"
GuildFeatureVipRegions GuildFeature = "VIP_REGIONS" GuildFeatureRaidAlertsDisabled GuildFeature = "RAID_ALERTS_DISABLED"
GuildFeatureWelcomeScreenEnabled GuildFeature = "WELCOME_SCREEN_ENABLED" GuildFeatureRoleIcons GuildFeature = "ROLE_ICONS"
GuildFeatureRoleSubscriptionsAvailableForPurchase GuildFeature = "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE"
GuildFeatureRoleSubscriptionsEnabled GuildFeature = "ROLE_SUBSCRIPTIONS_ENABLED"
GuildFeatureSoundboard GuildFeature = "SOUNDBOARD"
GuildFeatureTicketedEventsEnabled GuildFeature = "TICKETED_EVENTS_ENABLED"
GuildFeatureVanityURL GuildFeature = "VANITY_URL"
GuildFeatureVerified GuildFeature = "VERIFIED"
GuildFeatureVipRegions GuildFeature = "VIP_REGIONS"
GuildFeatureWelcomeScreenEnabled GuildFeature = "WELCOME_SCREEN_ENABLED"
) )
// A GuildParams stores all the data needed to update discord guild settings // A GuildParams stores all the data needed to update discord guild settings
@@ -1538,6 +1574,9 @@ type Member struct {
// The hash of the avatar for the guild member, if any. // The hash of the avatar for the guild member, if any.
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
// The hash of the banner for the guild member, if any.
Banner string `json:"banner"`
// The underlying user on which the member is based. // The underlying user on which the member is based.
User *User `json:"user"` User *User `json:"user"`
@@ -1582,13 +1621,29 @@ func (m *Member) AvatarURL(size string) string {
} }
// BannerURL returns the URL of the member's banner image.
//
// size: The size of the desired banner image as a power of two
// Image size can be any power of two between 16 and 4096.
func (m *Member) BannerURL(size string) string {
if m.Banner == "" {
return m.User.BannerURL(size)
}
return bannerURL(
m.Banner,
EndpointGuildMemberBanner(m.GuildID, m.User.ID, m.Banner),
EndpointGuildMemberBannerAnimated(m.GuildID, m.User.ID, m.Banner),
size,
)
}
// DisplayName returns the member's guild nickname if they have one, // DisplayName returns the member's guild nickname if they have one,
// otherwise it returns their discord display name. // otherwise it returns their discord display name.
func (m *Member) DisplayName() string { func (m *Member) DisplayName() string {
if m.Nick != "" { if m.Nick != "" {
return m.Nick return m.Nick
} }
return m.User.GlobalName return m.User.DisplayName()
} }
// ClientStatus stores the online, offline, idle, or dnd status of each device of a Guild member. // ClientStatus stores the online, offline, idle, or dnd status of each device of a Guild member.
@@ -1743,6 +1798,10 @@ type AutoModerationActionMetadata struct {
// Timeout duration in seconds (maximum of 2419200 - 4 weeks). // Timeout duration in seconds (maximum of 2419200 - 4 weeks).
// NOTE: should be only used with timeout action type. // NOTE: should be only used with timeout action type.
Duration int `json:"duration_seconds,omitempty"` Duration int `json:"duration_seconds,omitempty"`
// Additional explanation that will be shown to members whenever their message is blocked (maximum of 150 characters).
// NOTE: should be only used with block message action type.
CustomMessage string `json:"custom_message,omitempty"`
} }
// AutoModerationAction stores data for an auto moderation action. // AutoModerationAction stores data for an auto moderation action.
@@ -1891,8 +1950,8 @@ const (
AuditLogChangeKeyPrivacylevel AuditLogChangeKey = "privacy_level" AuditLogChangeKeyPrivacylevel AuditLogChangeKey = "privacy_level"
// AuditLogChangeKeyPruneDeleteDays is sent when number of days after which inactive and role-unassigned members are kicked changed (int) - guild // AuditLogChangeKeyPruneDeleteDays is sent when number of days after which inactive and role-unassigned members are kicked changed (int) - guild
AuditLogChangeKeyPruneDeleteDays AuditLogChangeKey = "prune_delete_days" AuditLogChangeKeyPruneDeleteDays AuditLogChangeKey = "prune_delete_days"
// AuditLogChangeKeyPulibUpdatesChannelID is sent when id of the public updates channel changed (snowflake) - guild // AuditLogChangeKeyPublicUpdatesChannelID is sent when id of the public updates channel changed (snowflake) - guild
AuditLogChangeKeyPulibUpdatesChannelID AuditLogChangeKey = "public_updates_channel_id" AuditLogChangeKeyPublicUpdatesChannelID AuditLogChangeKey = "public_updates_channel_id"
// AuditLogChangeKeyRateLimitPerUser is sent when amount of seconds a user has to wait before sending another message changed (int) - channel // AuditLogChangeKeyRateLimitPerUser is sent when amount of seconds a user has to wait before sending another message changed (int) - channel
AuditLogChangeKeyRateLimitPerUser AuditLogChangeKey = "rate_limit_per_user" AuditLogChangeKeyRateLimitPerUser AuditLogChangeKey = "rate_limit_per_user"
// AuditLogChangeKeyRegion is sent when region changed (string) - guild // AuditLogChangeKeyRegion is sent when region changed (string) - guild
@@ -2038,6 +2097,15 @@ const (
AuditLogActionCreatorMonetizationRequestCreated AuditLogAction = 150 AuditLogActionCreatorMonetizationRequestCreated AuditLogAction = 150
AuditLogActionCreatorMonetizationTermsAccepted AuditLogAction = 151 AuditLogActionCreatorMonetizationTermsAccepted AuditLogAction = 151
AuditLogActionOnboardingPromptCreate AuditLogAction = 163
AuditLogActionOnboardingPromptUpdate AuditLogAction = 164
AuditLogActionOnboardingPromptDelete AuditLogAction = 165
AuditLogActionOnboardingCreate AuditLogAction = 166
AuditLogActionOnboardingUpdate AuditLogAction = 167
AuditLogActionHomeSettingsCreate = 190
AuditLogActionHomeSettingsUpdate = 191
) )
// GuildMemberParams stores data needed to update a member // GuildMemberParams stores data needed to update a member
@@ -2176,7 +2244,7 @@ func (activity *Activity) UnmarshalJSON(b []byte) error {
Type ActivityType `json:"type"` Type ActivityType `json:"type"`
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`
CreatedAt int64 `json:"created_at"` CreatedAt int64 `json:"created_at"`
ApplicationID string `json:"application_id,omitempty"` ApplicationID json.Number `json:"application_id,omitempty"`
State string `json:"state,omitempty"` State string `json:"state,omitempty"`
Details string `json:"details,omitempty"` Details string `json:"details,omitempty"`
Timestamps TimeStamps `json:"timestamps,omitempty"` Timestamps TimeStamps `json:"timestamps,omitempty"`
@@ -2191,8 +2259,8 @@ func (activity *Activity) UnmarshalJSON(b []byte) error {
if err != nil { if err != nil {
return err return err
} }
activity.ApplicationID = temp.ApplicationID.String()
activity.CreatedAt = time.Unix(0, temp.CreatedAt*1000000) activity.CreatedAt = time.Unix(0, temp.CreatedAt*1000000)
activity.ApplicationID = temp.ApplicationID
activity.Assets = temp.Assets activity.Assets = temp.Assets
activity.Details = temp.Details activity.Details = temp.Details
activity.Emoji = temp.Emoji activity.Emoji = temp.Emoji
@@ -2302,63 +2370,426 @@ const (
StageInstancePrivacyLevelGuildOnly StageInstancePrivacyLevel = 2 StageInstancePrivacyLevelGuildOnly StageInstancePrivacyLevel = 2
) )
// PollLayoutType represents the layout of a poll.
type PollLayoutType int
// Valid PollLayoutType values.
const (
PollLayoutTypeDefault PollLayoutType = 1
)
// PollMedia contains common data used by question and answers.
type PollMedia struct {
Text string `json:"text,omitempty"`
Emoji *ComponentEmoji `json:"emoji,omitempty"` // TODO: rename the type
}
// PollAnswer represents a single answer in a poll.
type PollAnswer struct {
// NOTE: should not be set on creation.
AnswerID int `json:"answer_id,omitempty"`
Media *PollMedia `json:"poll_media"`
}
// PollAnswerCount stores counted poll votes for a single answer.
type PollAnswerCount struct {
ID int `json:"id"`
Count int `json:"count"`
MeVoted bool `json:"me_voted"`
}
// PollResults contains voting results on a poll.
type PollResults struct {
Finalized bool `json:"is_finalized"`
AnswerCounts []*PollAnswerCount `json:"answer_counts"`
}
// Poll contains all poll related data.
type Poll struct {
Question PollMedia `json:"question"`
Answers []PollAnswer `json:"answers"`
AllowMultiselect bool `json:"allow_multiselect"`
LayoutType PollLayoutType `json:"layout_type,omitempty"`
// NOTE: should be set only on creation, when fetching use Expiry.
Duration int `json:"duration,omitempty"`
// NOTE: available only when fetching.
Results *PollResults `json:"results,omitempty"`
// NOTE: as Discord documentation notes, this field might be null even when fetching.
Expiry *time.Time `json:"expiry,omitempty"`
}
// SKUType is the type of SKU (see SKUType* consts)
// https://discord.com/developers/docs/monetization/skus
type SKUType int
// Valid SKUType values
const (
SKUTypeDurable SKUType = 2
SKUTypeConsumable SKUType = 3
SKUTypeSubscription SKUType = 5
// SKUTypeSubscriptionGroup is a system-generated group for each subscription SKU.
SKUTypeSubscriptionGroup SKUType = 6
)
// SKUFlags is a bitfield of flags used to differentiate user and server subscriptions (see SKUFlag* consts)
// https://discord.com/developers/docs/monetization/skus#sku-object-sku-flags
type SKUFlags int
const (
// SKUFlagAvailable indicates that the SKU is available for purchase.
SKUFlagAvailable SKUFlags = 1 << 2
// SKUFlagGuildSubscription indicates that the SKU is a guild subscription.
SKUFlagGuildSubscription SKUFlags = 1 << 7
// SKUFlagUserSubscription indicates that the SKU is a user subscription.
SKUFlagUserSubscription SKUFlags = 1 << 8
)
// SKU (stock-keeping units) represent premium offerings
type SKU struct {
// The ID of the SKU
ID string `json:"id"`
// The Type of the SKU
Type SKUType `json:"type"`
// The ID of the parent application
ApplicationID string `json:"application_id"`
// Customer-facing name of the SKU.
Name string `json:"name"`
// System-generated URL slug based on the SKU's name.
Slug string `json:"slug"`
// SKUFlags combined as a bitfield. The presence of a certain flag can be checked
// by performing a bitwise AND operation between this int and the flag.
Flags SKUFlags `json:"flags"`
}
// Subscription represents a user making recurring payments for at least one SKU over an ongoing period.
// https://discord.com/developers/docs/resources/subscription#subscription-object
type Subscription struct {
// ID of the subscription
ID string `json:"id"`
// ID of the user who is subscribed
UserID string `json:"user_id"`
// List of SKUs subscribed to
SKUIDs []string `json:"sku_ids"`
// List of entitlements granted for this subscription
EntitlementIDs []string `json:"entitlement_ids"`
// List of SKUs that this user will be subscribed to at renewal
RenewalSKUIDs []string `json:"renewal_sku_ids,omitempty"`
// Start of the current subscription period
CurrentPeriodStart time.Time `json:"current_period_start"`
// End of the current subscription period
CurrentPeriodEnd time.Time `json:"current_period_end"`
// Current status of the subscription
Status SubscriptionStatus `json:"status"`
// When the subscription was canceled. Only present if the subscription has been canceled.
CanceledAt *time.Time `json:"canceled_at,omitempty"`
// ISO3166-1 alpha-2 country code of the payment source used to purchase the subscription. Missing unless queried with a private OAuth scope.
Country string `json:"country,omitempty"`
}
// SubscriptionStatus is the current status of a Subscription Object
// https://discord.com/developers/docs/resources/subscription#subscription-statuses
type SubscriptionStatus int
// Valid SubscriptionStatus values
const (
SubscriptionStatusActive = 0
SubscriptionStatusEnding = 1
SubscriptionStatusInactive = 2
)
// EntitlementType is the type of entitlement (see EntitlementType* consts)
// https://discord.com/developers/docs/monetization/entitlements#entitlement-object-entitlement-types
type EntitlementType int
// Valid EntitlementType values
const (
EntitlementTypePurchase = 1
EntitlementTypePremiumSubscription = 2
EntitlementTypeDeveloperGift = 3
EntitlementTypeTestModePurchase = 4
EntitlementTypeFreePurchase = 5
EntitlementTypeUserGift = 6
EntitlementTypePremiumPurchase = 7
EntitlementTypeApplicationSubscription = 8
)
// Entitlement represents that a user or guild has access to a premium offering
// in your application.
type Entitlement struct {
// The ID of the entitlement
ID string `json:"id"`
// The ID of the SKU
SKUID string `json:"sku_id"`
// The ID of the parent application
ApplicationID string `json:"application_id"`
// The ID of the user that is granted access to the entitlement's sku
// Only available for user subscriptions.
UserID string `json:"user_id,omitempty"`
// The type of the entitlement
Type EntitlementType `json:"type"`
// The entitlement was deleted
Deleted bool `json:"deleted"`
// The start date at which the entitlement is valid.
// Not present when using test entitlements.
StartsAt *time.Time `json:"starts_at,omitempty"`
// The date at which the entitlement is no longer valid.
// Not present when using test entitlements or when receiving an ENTITLEMENT_CREATE event.
EndsAt *time.Time `json:"ends_at,omitempty"`
// The ID of the guild that is granted access to the entitlement's sku.
// Only available for guild subscriptions.
GuildID string `json:"guild_id,omitempty"`
// Whether or not the entitlement has been consumed.
// Only available for consumable items.
Consumed *bool `json:"consumed,omitempty"`
// The SubscriptionID of the entitlement.
// Not present when using test entitlements.
SubscriptionID string `json:"subscription_id,omitempty"`
}
// EntitlementOwnerType is the type of entitlement (see EntitlementOwnerType* consts)
type EntitlementOwnerType int
// Valid EntitlementOwnerType values
const (
EntitlementOwnerTypeGuildSubscription EntitlementOwnerType = 1
EntitlementOwnerTypeUserSubscription EntitlementOwnerType = 2
)
// EntitlementTest is used to test granting an entitlement to a user or guild
type EntitlementTest struct {
// The ID of the SKU to grant the entitlement to
SKUID string `json:"sku_id"`
// The ID of the guild or user to grant the entitlement to
OwnerID string `json:"owner_id"`
// OwnerType is the type of which the entitlement should be created
OwnerType EntitlementOwnerType `json:"owner_type"`
}
// EntitlementFilterOptions are the options for filtering Entitlements
type EntitlementFilterOptions struct {
// Optional user ID to look up for.
UserID string
// Optional array of SKU IDs to check for.
SkuIDs []string
// Optional timestamp to retrieve Entitlements before this time.
Before *time.Time
// Optional timestamp to retrieve Entitlements after this time.
After *time.Time
// Optional maximum number of entitlements to return (1-100, default 100).
Limit int
// Optional guild ID to look up for.
GuildID string
// Optional whether or not ended entitlements should be omitted.
ExcludeEnded bool
}
// Constants for the different bit offsets of text channel permissions // Constants for the different bit offsets of text channel permissions
const ( const (
// Deprecated: PermissionReadMessages has been replaced with PermissionViewChannel for text and voice channels // Deprecated: PermissionReadMessages has been replaced with PermissionViewChannel for text and voice channels
PermissionReadMessages = 0x0000000000000400 PermissionReadMessages = 1 << 10
PermissionSendMessages = 0x0000000000000800
PermissionSendTTSMessages = 0x0000000000001000 // Allows for sending messages in a channel and creating threads in a forum (does not allow sending messages in threads).
PermissionManageMessages = 0x0000000000002000 PermissionSendMessages = 1 << 11
PermissionEmbedLinks = 0x0000000000004000
PermissionAttachFiles = 0x0000000000008000 // Allows for sending of /tts messages.
PermissionReadMessageHistory = 0x0000000000010000 PermissionSendTTSMessages = 1 << 12
PermissionMentionEveryone = 0x0000000000020000
PermissionUseExternalEmojis = 0x0000000000040000 // Allows for deletion of other users messages.
PermissionUseSlashCommands = 0x0000000080000000 PermissionManageMessages = 1 << 13
PermissionManageThreads = 0x0000000400000000
PermissionCreatePublicThreads = 0x0000000800000000 // Links sent by users with this permission will be auto-embedded.
PermissionCreatePrivateThreads = 0x0000001000000000 PermissionEmbedLinks = 1 << 14
PermissionUseExternalStickers = 0x0000002000000000
PermissionSendMessagesInThreads = 0x0000004000000000 // Allows for uploading images and files.
PermissionAttachFiles = 1 << 15
// Allows for reading of message history.
PermissionReadMessageHistory = 1 << 16
// Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel.
PermissionMentionEveryone = 1 << 17
// Allows the usage of custom emojis from other servers.
PermissionUseExternalEmojis = 1 << 18
// Deprecated: PermissionUseSlashCommands has been replaced by PermissionUseApplicationCommands
PermissionUseSlashCommands = 1 << 31
// Allows members to use application commands, including slash commands and context menu commands.
PermissionUseApplicationCommands = 1 << 31
// Allows for deleting and archiving threads, and viewing all private threads.
PermissionManageThreads = 1 << 34
// Allows for creating public and announcement threads.
PermissionCreatePublicThreads = 1 << 35
// Allows for creating private threads.
PermissionCreatePrivateThreads = 1 << 36
// Allows the usage of custom stickers from other servers.
PermissionUseExternalStickers = 1 << 37
// Allows for sending messages in threads.
PermissionSendMessagesInThreads = 1 << 38
// Allows sending voice messages.
PermissionSendVoiceMessages = 1 << 46
// Allows sending polls.
PermissionSendPolls = 1 << 49
// Allows user-installed apps to send public responses. When disabled, users will still be allowed to use their apps but the responses will be ephemeral. This only applies to apps not also installed to the server.
PermissionUseExternalApps = 1 << 50
) )
// Constants for the different bit offsets of voice permissions // Constants for the different bit offsets of voice permissions
const ( const (
PermissionVoicePrioritySpeaker = 0x0000000000000100 // Allows for using priority speaker in a voice channel.
PermissionVoiceStreamVideo = 0x0000000000000200 PermissionVoicePrioritySpeaker = 1 << 8
PermissionVoiceConnect = 0x0000000000100000
PermissionVoiceSpeak = 0x0000000000200000 // Allows the user to go live.
PermissionVoiceMuteMembers = 0x0000000000400000 PermissionVoiceStreamVideo = 1 << 9
PermissionVoiceDeafenMembers = 0x0000000000800000
PermissionVoiceMoveMembers = 0x0000000001000000 // Allows for joining of a voice channel.
PermissionVoiceUseVAD = 0x0000000002000000 PermissionVoiceConnect = 1 << 20
PermissionVoiceRequestToSpeak = 0x0000000100000000
PermissionUseActivities = 0x0000008000000000 // Allows for speaking in a voice channel.
PermissionVoiceSpeak = 1 << 21
// Allows for muting members in a voice channel.
PermissionVoiceMuteMembers = 1 << 22
// Allows for deafening of members in a voice channel.
PermissionVoiceDeafenMembers = 1 << 23
// Allows for moving of members between voice channels.
PermissionVoiceMoveMembers = 1 << 24
// Allows for using voice-activity-detection in a voice channel.
PermissionVoiceUseVAD = 1 << 25
// Allows for requesting to speak in stage channels.
PermissionVoiceRequestToSpeak = 1 << 32
// Deprecated: PermissionUseActivities has been replaced by PermissionUseEmbeddedActivities.
PermissionUseActivities = 1 << 39
// Allows for using Activities (applications with the EMBEDDED flag) in a voice channel.
PermissionUseEmbeddedActivities = 1 << 39
// Allows for using soundboard in a voice channel.
PermissionUseSoundboard = 1 << 42
// Allows the usage of custom soundboard sounds from other servers.
PermissionUseExternalSounds = 1 << 45
) )
// Constants for general management. // Constants for general management.
const ( const (
PermissionChangeNickname = 0x0000000004000000 // Allows for modification of own nickname.
PermissionManageNicknames = 0x0000000008000000 PermissionChangeNickname = 1 << 26
PermissionManageRoles = 0x0000000010000000
PermissionManageWebhooks = 0x0000000020000000 // Allows for modification of other users nicknames.
PermissionManageEmojis = 0x0000000040000000 PermissionManageNicknames = 1 << 27
PermissionManageEvents = 0x0000000200000000
// Allows management and editing of roles.
PermissionManageRoles = 1 << 28
// Allows management and editing of webhooks.
PermissionManageWebhooks = 1 << 29
// Deprecated: PermissionManageEmojis has been replaced by PermissionManageGuildExpressions.
PermissionManageEmojis = 1 << 30
// Allows for editing and deleting emojis, stickers, and soundboard sounds created by all users.
PermissionManageGuildExpressions = 1 << 30
// Allows for editing and deleting scheduled events created by all users.
PermissionManageEvents = 1 << 33
// Allows for viewing role subscription insights.
PermissionViewCreatorMonetizationAnalytics = 1 << 41
// Allows for creating emojis, stickers, and soundboard sounds, and editing and deleting those created by the current user.
PermissionCreateGuildExpressions = 1 << 43
// Allows for creating scheduled events, and editing and deleting those created by the current user.
PermissionCreateEvents = 1 << 44
) )
// Constants for the different bit offsets of general permissions // Constants for the different bit offsets of general permissions
const ( const (
PermissionCreateInstantInvite = 0x0000000000000001 // Allows creation of instant invites.
PermissionKickMembers = 0x0000000000000002 PermissionCreateInstantInvite = 1 << 0
PermissionBanMembers = 0x0000000000000004
PermissionAdministrator = 0x0000000000000008 // Allows kicking members.
PermissionManageChannels = 0x0000000000000010 PermissionKickMembers = 1 << 1
PermissionManageServer = 0x0000000000000020
PermissionAddReactions = 0x0000000000000040 // Allows banning members.
PermissionViewAuditLogs = 0x0000000000000080 PermissionBanMembers = 1 << 2
PermissionViewChannel = 0x0000000000000400
PermissionViewGuildInsights = 0x0000000000080000 // Allows all permissions and bypasses channel permission overwrites.
PermissionModerateMembers = 0x0000010000000000 PermissionAdministrator = 1 << 3
// Allows management and editing of channels.
PermissionManageChannels = 1 << 4
// Deprecated: PermissionManageServer has been replaced by PermissionManageGuild.
PermissionManageServer = 1 << 5
// Allows management and editing of the guild.
PermissionManageGuild = 1 << 5
// Allows for the addition of reactions to messages.
PermissionAddReactions = 1 << 6
// Allows for viewing of audit logs.
PermissionViewAuditLogs = 1 << 7
// Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels.
PermissionViewChannel = 1 << 10
// Allows for viewing guild insights.
PermissionViewGuildInsights = 1 << 19
// Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels.
PermissionModerateMembers = 1 << 40
PermissionAllText = PermissionViewChannel | PermissionAllText = PermissionViewChannel |
PermissionSendMessages | PermissionSendMessages |
@@ -2585,6 +3016,8 @@ const (
IntentGuildScheduledEvents Intent = 1 << 16 IntentGuildScheduledEvents Intent = 1 << 16
IntentAutoModerationConfiguration Intent = 1 << 20 IntentAutoModerationConfiguration Intent = 1 << 20
IntentAutoModerationExecution Intent = 1 << 21 IntentAutoModerationExecution Intent = 1 << 21
IntentGuildMessagePolls Intent = 1 << 24
IntentDirectMessagePolls Intent = 1 << 25
// TODO: remove when compatibility is not needed // TODO: remove when compatibility is not needed

View File

@@ -152,3 +152,11 @@ func (u *User) DefaultAvatarIndex() int {
id, _ := strconv.Atoi(u.Discriminator) id, _ := strconv.Atoi(u.Discriminator)
return id % 5 return id % 5
} }
// DisplayName returns the user's global name if they have one, otherwise it returns their username.
func (u *User) DisplayName() string {
if u.GlobalName != "" {
return u.GlobalName
}
return u.Username
}

View File

@@ -515,6 +515,21 @@ func (s *Session) RequestGuildMembersBatchList(guildIDs []string, userIDs []stri
return return
} }
// GatewayWriteStruct allows for sending raw gateway structs over the gateway.
func (s *Session) GatewayWriteStruct(data interface{}) (err error) {
s.RLock()
defer s.RUnlock()
if s.wsConn == nil {
return ErrWSNotFound
}
s.wsMutex.Lock()
err = s.wsConn.WriteJSON(data)
s.wsMutex.Unlock()
return err
}
func (s *Session) requestGuildMembers(data requestGuildMembersData) (err error) { func (s *Session) requestGuildMembers(data requestGuildMembersData) (err error) {
s.log(LogInformational, "called") s.log(LogInformational, "called")

2
vendor/modules.txt vendored
View File

@@ -52,7 +52,7 @@ github.com/av-elier/go-decimal-to-rational
# github.com/blang/semver/v4 v4.0.0 # github.com/blang/semver/v4 v4.0.0
## explicit; go 1.14 ## explicit; go 1.14
github.com/blang/semver/v4 github.com/blang/semver/v4
# github.com/bwmarrin/discordgo v0.28.1 # github.com/bwmarrin/discordgo v0.29.0
## explicit; go 1.13 ## explicit; go 1.13
github.com/bwmarrin/discordgo github.com/bwmarrin/discordgo
# github.com/d5/tengo/v2 v2.17.0 # github.com/d5/tengo/v2 v2.17.0