From 3b0882ee78041b9013731257d601ebd49208d54b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 26 Mar 2024 08:06:53 +0100 Subject: [PATCH 1/7] fix nil panic in message reaction add handler (#347) --- handlers/message_reaction_handler.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/handlers/message_reaction_handler.go b/handlers/message_reaction_handler.go index 1b1eb688..0e738681 100644 --- a/handlers/message_reaction_handler.go +++ b/handlers/message_reaction_handler.go @@ -2,6 +2,7 @@ package handlers import ( "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" "github.com/disgoorg/disgo/events" "github.com/disgoorg/disgo/gateway" ) @@ -37,6 +38,11 @@ func gatewayHandlerMessageReactionAdd(client bot.Client, sequenceNumber int, sha MessageAuthorID: event.MessageAuthorID, }) } else { + var member discord.Member + // sometimes the member is nil for some reason + if event.Member != nil { + member = *event.Member + } client.EventManager().DispatchEvent(&events.GuildMessageReactionAdd{ GenericGuildMessageReaction: &events.GenericGuildMessageReaction{ GenericEvent: genericEvent, @@ -48,7 +54,7 @@ func gatewayHandlerMessageReactionAdd(client bot.Client, sequenceNumber int, sha BurstColors: event.BurstColors, Burst: event.Burst, }, - Member: *event.Member, + Member: member, MessageAuthorID: event.MessageAuthorID, }) } From 223c084e15c01a65af816adf08bd8a35d9baa917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 27 Mar 2024 11:37:51 +0100 Subject: [PATCH 2/7] Update example.go --- _examples/handler/example.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_examples/handler/example.go b/_examples/handler/example.go index 0636b76b..630231b8 100644 --- a/_examples/handler/example.go +++ b/_examples/handler/example.go @@ -80,7 +80,7 @@ func main() { r.Use(middleware.Print("group2")) r.Command("/ping", handlePing) r.Command("/ping2", handleContent("pong2")) - r.Component("button1/{data}", handleComponent) + r.Component("/button1/{data}", handleComponent) }) r.NotFound(handleNotFound) @@ -126,7 +126,7 @@ func handlePing(event *handler.CommandEvent) error { Content: "pong", Components: []discord.ContainerComponent{ discord.ActionRowComponent{ - discord.NewPrimaryButton("button1", "button1/testData"), + discord.NewPrimaryButton("button1", "/button1/testData"), }, }, }) From 9b1dddf5954fd627e0f18dc92c43d5401e657ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 29 Mar 2024 13:06:31 +0100 Subject: [PATCH 3/7] allow multiple gateway closes without blocking forever (#339) --- gateway/gateway_impl.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/gateway/gateway_impl.go b/gateway/gateway_impl.go index f644bf88..79a31b65 100644 --- a/gateway/gateway_impl.go +++ b/gateway/gateway_impl.go @@ -42,10 +42,10 @@ type gatewayImpl struct { closeHandlerFunc CloseHandlerFunc token string - conn *websocket.Conn - connMu sync.Mutex - heartbeatChan chan struct{} - status Status + conn *websocket.Conn + connMu sync.Mutex + heartbeatCancel context.CancelFunc + status Status heartbeatInterval time.Duration lastHeartbeatSent time.Time @@ -132,9 +132,9 @@ func (g *gatewayImpl) Close(ctx context.Context) { } func (g *gatewayImpl) CloseWithCode(ctx context.Context, code int, message string) { - if g.heartbeatChan != nil { + if g.heartbeatCancel != nil { g.config.Logger.Debug("closing heartbeat goroutines...") - g.heartbeatChan <- struct{}{} + g.heartbeatCancel() } g.connMu.Lock() @@ -234,16 +234,16 @@ func (g *gatewayImpl) reconnect() { } func (g *gatewayImpl) heartbeat() { - if g.heartbeatChan == nil { - g.heartbeatChan = make(chan struct{}) - } + ctx, cancel := context.WithCancel(context.Background()) + g.heartbeatCancel = cancel + heartbeatTicker := time.NewTicker(g.heartbeatInterval) defer heartbeatTicker.Stop() defer g.config.Logger.Debug("exiting heartbeat goroutine") for { select { - case <-g.heartbeatChan: + case <-ctx.Done(): return case <-heartbeatTicker.C: From 77825013c1e51697918ddeba4513cd9b1ad163fe Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sat, 30 Mar 2024 19:21:44 +0100 Subject: [PATCH 4/7] Add bulk ban endpoint (#342) --- discord/ban.go | 14 ++++++++++++++ rest/guilds.go | 6 ++++++ rest/rest_endpoints.go | 1 + 3 files changed, 21 insertions(+) diff --git a/discord/ban.go b/discord/ban.go index c730ba5a..b8c9b92e 100644 --- a/discord/ban.go +++ b/discord/ban.go @@ -1,5 +1,7 @@ package discord +import "github.com/disgoorg/snowflake/v2" + // Ban represents a banned User from a Guild (https://discord.com/developers/docs/resources/guild#ban-object) type Ban struct { Reason *string `json:"reason,omitempty"` @@ -10,3 +12,15 @@ type Ban struct { type AddBan struct { DeleteMessageSeconds int `json:"delete_message_seconds,omitempty"` } + +// BulkBan is used to bulk ban Users +type BulkBan struct { + UserIDs []snowflake.ID `json:"user_ids"` + DeleteMessageSeconds int `json:"delete_message_seconds,omitempty"` +} + +// BulkBanResult is the result of a BulkBan request +type BulkBanResult struct { + BannedUsers []snowflake.ID `json:"banned_users"` + FailedUsers []snowflake.ID `json:"failed_users"` +} diff --git a/rest/guilds.go b/rest/guilds.go index 43d71b14..f1eceac4 100644 --- a/rest/guilds.go +++ b/rest/guilds.go @@ -40,6 +40,7 @@ type Guilds interface { GetBan(guildID snowflake.ID, userID snowflake.ID, opts ...RequestOpt) (*discord.Ban, error) AddBan(guildID snowflake.ID, userID snowflake.ID, deleteMessageDuration time.Duration, opts ...RequestOpt) error DeleteBan(guildID snowflake.ID, userID snowflake.ID, opts ...RequestOpt) error + BulkBan(guildID snowflake.ID, ban discord.BulkBan, opts ...RequestOpt) (*discord.BulkBanResult, error) GetIntegrations(guildID snowflake.ID, opts ...RequestOpt) ([]discord.Integration, error) DeleteIntegration(guildID snowflake.ID, integrationID snowflake.ID, opts ...RequestOpt) error @@ -210,6 +211,11 @@ func (s *guildImpl) DeleteBan(guildID snowflake.ID, userID snowflake.ID, opts .. return s.client.Do(DeleteBan.Compile(nil, guildID, userID), nil, nil, opts...) } +func (s *guildImpl) BulkBan(guildID snowflake.ID, ban discord.BulkBan, opts ...RequestOpt) (result *discord.BulkBanResult, err error) { + err = s.client.Do(BulkBan.Compile(nil, guildID), ban, &result, opts...) + return +} + func (s *guildImpl) GetIntegrations(guildID snowflake.ID, opts ...RequestOpt) (integrations []discord.Integration, err error) { err = s.client.Do(GetIntegrations.Compile(nil, guildID), nil, &integrations, opts...) return diff --git a/rest/rest_endpoints.go b/rest/rest_endpoints.go index fb1d689a..faa92815 100644 --- a/rest/rest_endpoints.go +++ b/rest/rest_endpoints.go @@ -65,6 +65,7 @@ var ( GetBan = NewEndpoint(http.MethodGet, "/guilds/{guild.id}/bans/{user.id}") AddBan = NewEndpoint(http.MethodPut, "/guilds/{guild.id}/bans/{user.id}") DeleteBan = NewEndpoint(http.MethodDelete, "/guilds/{guild.id}/bans/{user.id}") + BulkBan = NewEndpoint(http.MethodPost, "/guilds/{guild.id}/bulk-ban") GetMember = NewEndpoint(http.MethodGet, "/guilds/{guild.id}/members/{user.id}") GetMembers = NewEndpoint(http.MethodGet, "/guilds/{guild.id}/members") From 97864e4798df3edcec3fb1a954e2f8354cfb7177 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 2 Apr 2024 20:22:39 +0200 Subject: [PATCH 5/7] Add ConnectionTypeBungie (#340) --- discord/connection.go | 1 + 1 file changed, 1 insertion(+) diff --git a/discord/connection.go b/discord/connection.go index 771d52b7..37714d2a 100644 --- a/discord/connection.go +++ b/discord/connection.go @@ -16,6 +16,7 @@ type ConnectionType string const ( ConnectionTypeBattleNet ConnectionType = "battlenet" + ConnectionTypeBungie ConnectionType = "bungie" ConnectionTypeEbay ConnectionType = "ebay" ConnectionTypeEpicGames ConnectionType = "epicgames" ConnectionTypeFacebook ConnectionType = "facebook" From 2500da82585df0917a3a496f18f4016255737210 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sun, 7 Apr 2024 23:08:03 +0200 Subject: [PATCH 6/7] Update avatar decorations (#320) * Update avatar decorations * add AvatarDecorationData to Member * add AvatarDecorationURL to Member --- discord/cdn_endpoints.go | 2 +- discord/member.go | 32 +++++++++++++++++++++----------- discord/user.go | 31 ++++++++++++++++++------------- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/discord/cdn_endpoints.go b/discord/cdn_endpoints.go index 8186af5a..6cffdfeb 100644 --- a/discord/cdn_endpoints.go +++ b/discord/cdn_endpoints.go @@ -24,7 +24,7 @@ var ( MemberAvatar = NewCDN("/guilds/{guild.id}/users/{user.id}/avatars/{member.avatar.hash}", FileFormatPNG, FileFormatJPEG, FileFormatWebP, FileFormatGIF) - UserAvatarDecoration = NewCDN("/avatar-decorations/{user.id}/{user.avatar.decoration.hash}", FileFormatPNG) + AvatarDecoration = NewCDN("/avatar-decoration-presets/{user.avatar.decoration.hash}", FileFormatPNG) ApplicationIcon = NewCDN("/app-icons/{application.id}/{icon.hash}", FileFormatPNG, FileFormatJPEG, FileFormatWebP) ApplicationCover = NewCDN("/app-assets/{application.id}/{cover.image.hash}", FileFormatPNG, FileFormatJPEG, FileFormatWebP) diff --git a/discord/member.go b/discord/member.go index 12666104..2bf9278f 100644 --- a/discord/member.go +++ b/discord/member.go @@ -13,17 +13,18 @@ var _ Mentionable = (*Member)(nil) // Member is a discord GuildMember type Member struct { - User User `json:"user"` - Nick *string `json:"nick"` - Avatar *string `json:"avatar"` - RoleIDs []snowflake.ID `json:"roles,omitempty"` - JoinedAt time.Time `json:"joined_at"` - PremiumSince *time.Time `json:"premium_since,omitempty"` - Deaf bool `json:"deaf,omitempty"` - Mute bool `json:"mute,omitempty"` - Flags MemberFlags `json:"flags"` - Pending bool `json:"pending"` - CommunicationDisabledUntil *time.Time `json:"communication_disabled_until"` + User User `json:"user"` + Nick *string `json:"nick"` + Avatar *string `json:"avatar"` + RoleIDs []snowflake.ID `json:"roles,omitempty"` + JoinedAt time.Time `json:"joined_at"` + PremiumSince *time.Time `json:"premium_since,omitempty"` + Deaf bool `json:"deaf,omitempty"` + Mute bool `json:"mute,omitempty"` + Flags MemberFlags `json:"flags"` + Pending bool `json:"pending"` + CommunicationDisabledUntil *time.Time `json:"communication_disabled_until"` + AvatarDecorationData *AvatarDecorationData `json:"avatar_decoration_data"` // This field is not present everywhere in the API and often populated by disgo GuildID snowflake.ID `json:"guild_id"` @@ -67,6 +68,15 @@ func (m Member) AvatarURL(opts ...CDNOpt) *string { return &url } +// AvatarDecorationURL returns the avatar decoration URL if set or nil +func (m Member) AvatarDecorationURL(opts ...CDNOpt) *string { + if m.AvatarDecorationData == nil { + return nil + } + url := formatAssetURL(AvatarDecoration, opts, m.AvatarDecorationData.Asset) + return &url +} + func (m Member) CreatedAt() time.Time { return m.User.CreatedAt() } diff --git a/discord/user.go b/discord/user.go index c0fe7535..f9218cd4 100644 --- a/discord/user.go +++ b/discord/user.go @@ -65,17 +65,17 @@ var _ Mentionable = (*User)(nil) // User is a struct for interacting with discord's users type User struct { - ID snowflake.ID `json:"id"` - Username string `json:"username"` - Discriminator string `json:"discriminator"` - GlobalName *string `json:"global_name"` - Avatar *string `json:"avatar"` - Banner *string `json:"banner"` - AccentColor *int `json:"accent_color"` - Bot bool `json:"bot"` - System bool `json:"system"` - PublicFlags UserFlags `json:"public_flags"` - AvatarDecoration *string `json:"avatar_decoration"` + ID snowflake.ID `json:"id"` + Username string `json:"username"` + Discriminator string `json:"discriminator"` + GlobalName *string `json:"global_name"` + Avatar *string `json:"avatar"` + Banner *string `json:"banner"` + AccentColor *int `json:"accent_color"` + Bot bool `json:"bot"` + System bool `json:"system"` + PublicFlags UserFlags `json:"public_flags"` + AvatarDecorationData *AvatarDecorationData `json:"avatar_decoration_data"` } // String returns a mention of the user @@ -145,10 +145,10 @@ func (u User) BannerURL(opts ...CDNOpt) *string { // AvatarDecorationURL returns the avatar decoration URL if set or nil func (u User) AvatarDecorationURL(opts ...CDNOpt) *string { - if u.AvatarDecoration == nil { + if u.AvatarDecorationData == nil { return nil } - url := formatAssetURL(UserAvatarDecoration, opts, u.ID, *u.AvatarDecoration) + url := formatAssetURL(AvatarDecoration, opts, u.AvatarDecorationData.Asset) return &url } @@ -198,3 +198,8 @@ type ApplicationRoleConnectionUpdate struct { PlatformUsername *string `json:"platform_username,omitempty"` Metadata *map[string]string `json:"metadata,omitempty"` } + +type AvatarDecorationData struct { + Asset string `json:"asset"` + SkuID snowflake.ID `json:"sku_id"` +} From 7039b07428cd37e1aeeddca1547c4ce825aa4081 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 8 Apr 2024 00:12:56 +0200 Subject: [PATCH 7/7] Add support for user apps (#341) * Add support for user apps * add Name to InteractionMetadata * add integrationType to auth * fix examples * omit default integration_type v2 * fuck * don't explicitly use integration const * mention integrationType in docs * make OAuth2InstallParams a pointer * dont use pointer for InteractionContextType --- _examples/oauth2/example.go | 2 +- _examples/verified_roles/main.go | 2 +- discord/application.go | 86 +++++++++++++--------- discord/application_command.go | 44 +++++++++++ discord/application_command_create.go | 21 ++++-- discord/application_command_raw.go | 56 +++++++------- discord/application_command_update.go | 21 ++++-- discord/interaction.go | 28 +++++-- discord/interaction_application_command.go | 32 ++++---- discord/interaction_autocomplete.go | 32 ++++---- discord/interaction_base.go | 36 +++++---- discord/interaction_component.go | 32 ++++---- discord/interaction_modal_submit.go | 32 ++++---- discord/interaction_ping.go | 8 ++ discord/message.go | 12 +++ oauth2/client.go | 8 +- oauth2/client_impl.go | 9 ++- 17 files changed, 302 insertions(+), 159 deletions(-) diff --git a/_examples/oauth2/example.go b/_examples/oauth2/example.go index 6e1c323f..29687fa3 100644 --- a/_examples/oauth2/example.go +++ b/_examples/oauth2/example.go @@ -87,7 +87,7 @@ func handleRoot(w http.ResponseWriter, r *http.Request) { } func handleLogin(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, client.GenerateAuthorizationURL(baseURL+"/trylogin", discord.PermissionsNone, 0, false, discord.OAuth2ScopeIdentify, discord.OAuth2ScopeGuilds, discord.OAuth2ScopeEmail, discord.OAuth2ScopeConnections, discord.OAuth2ScopeWebhookIncoming), http.StatusSeeOther) + http.Redirect(w, r, client.GenerateAuthorizationURL(baseURL+"/trylogin", discord.PermissionsNone, 0, false, 0, discord.OAuth2ScopeIdentify, discord.OAuth2ScopeGuilds, discord.OAuth2ScopeEmail, discord.OAuth2ScopeConnections, discord.OAuth2ScopeWebhookIncoming), http.StatusSeeOther) } func handleTryLogin(w http.ResponseWriter, r *http.Request) { diff --git a/_examples/verified_roles/main.go b/_examples/verified_roles/main.go index 2fadbaa5..d3ef5e95 100644 --- a/_examples/verified_roles/main.go +++ b/_examples/verified_roles/main.go @@ -52,7 +52,7 @@ func main() { } func handleVerify(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, oAuth2Client.GenerateAuthorizationURL(baseURL+"/callback", discord.PermissionsNone, 0, false, discord.OAuth2ScopeIdentify, discord.OAuth2ScopeRoleConnectionsWrite), http.StatusTemporaryRedirect) + http.Redirect(w, r, oAuth2Client.GenerateAuthorizationURL(baseURL+"/callback", discord.PermissionsNone, 0, false, 0, discord.OAuth2ScopeIdentify, discord.OAuth2ScopeRoleConnectionsWrite), http.StatusTemporaryRedirect) } func handleCallback(w http.ResponseWriter, r *http.Request) { diff --git a/discord/application.go b/discord/application.go index 05e5aafc..c100abe9 100644 --- a/discord/application.go +++ b/discord/application.go @@ -12,32 +12,34 @@ import ( ) type Application struct { - ID snowflake.ID `json:"id"` - Name string `json:"name"` - Icon *string `json:"icon,omitempty"` - Description string `json:"description"` - RPCOrigins []string `json:"rpc_origins"` - BotPublic bool `json:"bot_public"` - BotRequireCodeGrant bool `json:"bot_require_code_grant"` - Bot *User `json:"bot,omitempty"` - TermsOfServiceURL *string `json:"terms_of_service_url,omitempty"` - PrivacyPolicyURL *string `json:"privacy_policy_url,omitempty"` - CustomInstallURL *string `json:"custom_install_url,omitempty"` - InteractionsEndpointURL *string `json:"interactions_endpoint_url,omitempty"` - RoleConnectionsVerificationURL *string `json:"role_connections_verification_url"` - InstallParams *InstallParams `json:"install_params"` - Tags []string `json:"tags"` - Owner *User `json:"owner,omitempty"` - Summary string `json:"summary"` - VerifyKey string `json:"verify_key"` - Team *Team `json:"team,omitempty"` - GuildID *snowflake.ID `json:"guild_id,omitempty"` - Guild *Guild `json:"guild,omitempty"` - PrimarySkuID *snowflake.ID `json:"primary_sku_id,omitempty"` - Slug *string `json:"slug,omitempty"` - CoverImage *string `json:"cover_image,omitempty"` - Flags ApplicationFlags `json:"flags,omitempty"` - ApproximateGuildCount *int `json:"approximate_guild_count,omitempty"` + ID snowflake.ID `json:"id"` + Name string `json:"name"` + Icon *string `json:"icon,omitempty"` + Description string `json:"description"` + RPCOrigins []string `json:"rpc_origins"` + BotPublic bool `json:"bot_public"` + BotRequireCodeGrant bool `json:"bot_require_code_grant"` + Bot *User `json:"bot,omitempty"` + TermsOfServiceURL *string `json:"terms_of_service_url,omitempty"` + PrivacyPolicyURL *string `json:"privacy_policy_url,omitempty"` + CustomInstallURL *string `json:"custom_install_url,omitempty"` + InteractionsEndpointURL *string `json:"interactions_endpoint_url,omitempty"` + RoleConnectionsVerificationURL *string `json:"role_connections_verification_url"` + InstallParams *InstallParams `json:"install_params"` + Tags []string `json:"tags"` + Owner *User `json:"owner,omitempty"` + Summary string `json:"summary"` + VerifyKey string `json:"verify_key"` + Team *Team `json:"team,omitempty"` + GuildID *snowflake.ID `json:"guild_id,omitempty"` + Guild *Guild `json:"guild,omitempty"` + PrimarySkuID *snowflake.ID `json:"primary_sku_id,omitempty"` + Slug *string `json:"slug,omitempty"` + CoverImage *string `json:"cover_image,omitempty"` + Flags ApplicationFlags `json:"flags,omitempty"` + ApproximateGuildCount *int `json:"approximate_guild_count,omitempty"` + IntegrationTypes []ApplicationIntegrationType `json:"integration_types"` + IntegrationTypesConfig ApplicationIntegrationTypesConfig `json:"integration_types_config"` } func (a Application) IconURL(opts ...CDNOpt) *string { @@ -61,15 +63,16 @@ func (a Application) CreatedAt() time.Time { } type ApplicationUpdate struct { - CustomInstallURL *string `json:"custom_install_url,omitempty"` - Description *string `json:"description,omitempty"` - RoleConnectionsVerificationURL *string `json:"role_connections_verification_url,omitempty"` - InstallParams *InstallParams `json:"install_params,omitempty"` - Flags *ApplicationFlags `json:"flags,omitempty"` - Icon *json.Nullable[Icon] `json:"icon,omitempty"` - CoverImage *json.Nullable[Icon] `json:"cover_image,omitempty"` - InteractionsEndpointURL *string `json:"interactions_endpoint_url,omitempty"` - Tags []string `json:"tags,omitempty"` + CustomInstallURL *string `json:"custom_install_url,omitempty"` + Description *string `json:"description,omitempty"` + RoleConnectionsVerificationURL *string `json:"role_connections_verification_url,omitempty"` + InstallParams *InstallParams `json:"install_params,omitempty"` + Flags *ApplicationFlags `json:"flags,omitempty"` + Icon *json.Nullable[Icon] `json:"icon,omitempty"` + CoverImage *json.Nullable[Icon] `json:"cover_image,omitempty"` + InteractionsEndpointURL *string `json:"interactions_endpoint_url,omitempty"` + Tags []string `json:"tags,omitempty"` + IntegrationTypesConfig *ApplicationIntegrationTypesConfig `json:"integration_types_config,omitempty"` } type PartialApplication struct { @@ -261,3 +264,16 @@ const ( TeamRoleDeveloper TeamRole = "developer" TeamRoleReadOnly TeamRole = "read_only" ) + +type ApplicationIntegrationType int + +const ( + ApplicationIntegrationTypeGuildInstall ApplicationIntegrationType = iota + ApplicationIntegrationTypeUserInstall +) + +type ApplicationIntegrationTypesConfig map[ApplicationIntegrationType]ApplicationIntegrationTypeConfiguration + +type ApplicationIntegrationTypeConfiguration struct { + OAuth2InstallParams *InstallParams `json:"oauth2_install_params"` +} diff --git a/discord/application_command.go b/discord/application_command.go index 1f149bec..72d96d90 100644 --- a/discord/application_command.go +++ b/discord/application_command.go @@ -30,6 +30,8 @@ type ApplicationCommand interface { Version() snowflake.ID CreatedAt() time.Time NSFW() bool + IntegrationTypes() []ApplicationIntegrationType + Contexts() []InteractionContextType applicationCommand() } @@ -95,6 +97,8 @@ type SlashCommand struct { defaultMemberPermissions Permissions dmPermission bool nsfw bool + integrationTypes []ApplicationIntegrationType + contexts []InteractionContextType version snowflake.ID } @@ -117,6 +121,8 @@ func (c *SlashCommand) UnmarshalJSON(data []byte) error { c.defaultMemberPermissions = v.DefaultMemberPermissions c.dmPermission = v.DMPermission c.nsfw = v.NSFW + c.integrationTypes = v.IntegrationTypes + c.contexts = v.Contexts c.version = v.Version return nil } @@ -137,6 +143,8 @@ func (c SlashCommand) MarshalJSON() ([]byte, error) { DefaultMemberPermissions: c.defaultMemberPermissions, DMPermission: c.dmPermission, NSFW: c.nsfw, + IntegrationTypes: c.integrationTypes, + Contexts: c.contexts, Version: c.version, }) } @@ -180,6 +188,14 @@ func (c SlashCommand) NSFW() bool { return c.nsfw } +func (c SlashCommand) IntegrationTypes() []ApplicationIntegrationType { + return c.integrationTypes +} + +func (c SlashCommand) Contexts() []InteractionContextType { + return c.contexts +} + func (c SlashCommand) Version() snowflake.ID { return c.version } @@ -206,6 +222,8 @@ type UserCommand struct { defaultMemberPermissions Permissions dmPermission bool nsfw bool + integrationTypes []ApplicationIntegrationType + contexts []InteractionContextType version snowflake.ID } @@ -224,6 +242,8 @@ func (c *UserCommand) UnmarshalJSON(data []byte) error { c.defaultMemberPermissions = v.DefaultMemberPermissions c.dmPermission = v.DMPermission c.nsfw = v.NSFW + c.integrationTypes = v.IntegrationTypes + c.contexts = v.Contexts c.version = v.Version return nil } @@ -240,6 +260,8 @@ func (c UserCommand) MarshalJSON() ([]byte, error) { DefaultMemberPermissions: c.defaultMemberPermissions, DMPermission: c.dmPermission, NSFW: c.nsfw, + IntegrationTypes: c.integrationTypes, + Contexts: c.contexts, Version: c.version, }) } @@ -283,6 +305,14 @@ func (c UserCommand) NSFW() bool { return c.nsfw } +func (c UserCommand) IntegrationTypes() []ApplicationIntegrationType { + return c.integrationTypes +} + +func (c UserCommand) Contexts() []InteractionContextType { + return c.contexts +} + func (c UserCommand) Version() snowflake.ID { return c.version } @@ -305,6 +335,8 @@ type MessageCommand struct { defaultMemberPermissions Permissions dmPermission bool nsfw bool + integrationTypes []ApplicationIntegrationType + contexts []InteractionContextType version snowflake.ID } @@ -323,6 +355,8 @@ func (c *MessageCommand) UnmarshalJSON(data []byte) error { c.defaultMemberPermissions = v.DefaultMemberPermissions c.dmPermission = v.DMPermission c.nsfw = v.NSFW + c.integrationTypes = v.IntegrationTypes + c.contexts = v.Contexts c.version = v.Version return nil } @@ -339,6 +373,8 @@ func (c MessageCommand) MarshalJSON() ([]byte, error) { DefaultMemberPermissions: c.defaultMemberPermissions, DMPermission: c.dmPermission, NSFW: c.nsfw, + IntegrationTypes: c.integrationTypes, + Contexts: c.contexts, Version: c.version, }) } @@ -382,6 +418,14 @@ func (c MessageCommand) NSFW() bool { return c.nsfw } +func (c MessageCommand) IntegrationTypes() []ApplicationIntegrationType { + return c.integrationTypes +} + +func (c MessageCommand) Contexts() []InteractionContextType { + return c.contexts +} + func (c MessageCommand) Version() snowflake.ID { return c.version } diff --git a/discord/application_command_create.go b/discord/application_command_create.go index bf80a0fb..61104ed7 100644 --- a/discord/application_command_create.go +++ b/discord/application_command_create.go @@ -16,8 +16,11 @@ type SlashCommandCreate struct { DescriptionLocalizations map[Locale]string `json:"description_localizations,omitempty"` Options []ApplicationCommandOption `json:"options,omitempty"` DefaultMemberPermissions *json.Nullable[Permissions] `json:"default_member_permissions,omitempty"` // different behavior for 0 and null, optional - DMPermission *bool `json:"dm_permission,omitempty"` - NSFW *bool `json:"nsfw,omitempty"` + // Deprecated: Use Contexts instead + DMPermission *bool `json:"dm_permission,omitempty"` + IntegrationTypes []ApplicationIntegrationType `json:"integration_types,omitempty"` + Contexts []InteractionContextType `json:"contexts,omitempty"` + NSFW *bool `json:"nsfw,omitempty"` } func (c SlashCommandCreate) MarshalJSON() ([]byte, error) { @@ -45,8 +48,11 @@ type UserCommandCreate struct { Name string `json:"name"` NameLocalizations map[Locale]string `json:"name_localizations,omitempty"` DefaultMemberPermissions *json.Nullable[Permissions] `json:"default_member_permissions,omitempty"` - DMPermission *bool `json:"dm_permission,omitempty"` - NSFW *bool `json:"nsfw,omitempty"` + // Deprecated: Use Contexts instead + DMPermission *bool `json:"dm_permission,omitempty"` + IntegrationTypes []ApplicationIntegrationType `json:"integration_types,omitempty"` + Contexts []InteractionContextType `json:"contexts,omitempty"` + NSFW *bool `json:"nsfw,omitempty"` } func (c UserCommandCreate) MarshalJSON() ([]byte, error) { @@ -74,8 +80,11 @@ type MessageCommandCreate struct { Name string `json:"name"` NameLocalizations map[Locale]string `json:"name_localizations,omitempty"` DefaultMemberPermissions *json.Nullable[Permissions] `json:"default_member_permissions,omitempty"` - DMPermission *bool `json:"dm_permission,omitempty"` - NSFW *bool `json:"nsfw,omitempty"` + // Deprecated: Use Contexts instead + DMPermission *bool `json:"dm_permission,omitempty"` + IntegrationTypes []ApplicationIntegrationType `json:"integration_types,omitempty"` + Contexts []InteractionContextType `json:"contexts,omitempty"` + NSFW *bool `json:"nsfw,omitempty"` } func (c MessageCommandCreate) MarshalJSON() ([]byte, error) { diff --git a/discord/application_command_raw.go b/discord/application_command_raw.go index a5fbe038..404bfef1 100644 --- a/discord/application_command_raw.go +++ b/discord/application_command_raw.go @@ -6,21 +6,23 @@ import ( ) type rawSlashCommand struct { - ID snowflake.ID `json:"id"` - Type ApplicationCommandType `json:"type"` - ApplicationID snowflake.ID `json:"application_id"` - GuildID *snowflake.ID `json:"guild_id,omitempty"` - Name string `json:"name"` - NameLocalizations map[Locale]string `json:"name_localizations,omitempty"` - NameLocalized string `json:"name_localized,omitempty"` - Description string `json:"description,omitempty"` - DescriptionLocalizations map[Locale]string `json:"description_localizations,omitempty"` - DescriptionLocalized string `json:"description_localized,omitempty"` - Options []ApplicationCommandOption `json:"options,omitempty"` - DefaultMemberPermissions Permissions `json:"default_member_permissions"` - DMPermission bool `json:"dm_permission"` - NSFW bool `json:"nsfw"` - Version snowflake.ID `json:"version"` + ID snowflake.ID `json:"id"` + Type ApplicationCommandType `json:"type"` + ApplicationID snowflake.ID `json:"application_id"` + GuildID *snowflake.ID `json:"guild_id,omitempty"` + Name string `json:"name"` + NameLocalizations map[Locale]string `json:"name_localizations,omitempty"` + NameLocalized string `json:"name_localized,omitempty"` + Description string `json:"description,omitempty"` + DescriptionLocalizations map[Locale]string `json:"description_localizations,omitempty"` + DescriptionLocalized string `json:"description_localized,omitempty"` + Options []ApplicationCommandOption `json:"options,omitempty"` + DefaultMemberPermissions Permissions `json:"default_member_permissions"` + DMPermission bool `json:"dm_permission"` + NSFW bool `json:"nsfw"` + IntegrationTypes []ApplicationIntegrationType `json:"integration_types"` + Contexts []InteractionContextType `json:"contexts"` + Version snowflake.ID `json:"version"` } func (c *rawSlashCommand) UnmarshalJSON(data []byte) error { @@ -46,15 +48,17 @@ func (c *rawSlashCommand) UnmarshalJSON(data []byte) error { } type rawContextCommand struct { - ID snowflake.ID `json:"id"` - Type ApplicationCommandType `json:"type"` - ApplicationID snowflake.ID `json:"application_id"` - GuildID *snowflake.ID `json:"guild_id,omitempty"` - Name string `json:"name"` - NameLocalizations map[Locale]string `json:"name_localizations,omitempty"` - NameLocalized string `json:"name_localized,omitempty"` - DefaultMemberPermissions Permissions `json:"default_member_permissions"` - DMPermission bool `json:"dm_permission"` - NSFW bool `json:"nsfw"` - Version snowflake.ID `json:"version"` + ID snowflake.ID `json:"id"` + Type ApplicationCommandType `json:"type"` + ApplicationID snowflake.ID `json:"application_id"` + GuildID *snowflake.ID `json:"guild_id,omitempty"` + Name string `json:"name"` + NameLocalizations map[Locale]string `json:"name_localizations,omitempty"` + NameLocalized string `json:"name_localized,omitempty"` + DefaultMemberPermissions Permissions `json:"default_member_permissions"` + DMPermission bool `json:"dm_permission"` + NSFW bool `json:"nsfw"` + IntegrationTypes []ApplicationIntegrationType `json:"integration_types"` + Contexts []InteractionContextType `json:"contexts"` + Version snowflake.ID `json:"version"` } diff --git a/discord/application_command_update.go b/discord/application_command_update.go index 33764546..a91c89c0 100644 --- a/discord/application_command_update.go +++ b/discord/application_command_update.go @@ -16,8 +16,11 @@ type SlashCommandUpdate struct { DescriptionLocalizations *map[Locale]string `json:"description_localizations,omitempty"` Options *[]ApplicationCommandOption `json:"options,omitempty"` DefaultMemberPermissions *json.Nullable[Permissions] `json:"default_member_permissions,omitempty"` - DMPermission *bool `json:"dm_permission,omitempty"` - NSFW *bool `json:"nsfw,omitempty"` + // Deprecated: Use Contexts instead + DMPermission *bool `json:"dm_permission,omitempty"` + IntegrationTypes *[]ApplicationIntegrationType `json:"integration_types,omitempty"` + Contexts *[]InteractionContextType `json:"contexts,omitempty"` + NSFW *bool `json:"nsfw,omitempty"` } func (c SlashCommandUpdate) MarshalJSON() ([]byte, error) { @@ -45,8 +48,11 @@ type UserCommandUpdate struct { Name *string `json:"name,omitempty"` NameLocalizations *map[Locale]string `json:"name_localizations,omitempty"` DefaultMemberPermissions *json.Nullable[Permissions] `json:"default_member_permissions,omitempty"` - DMPermission *bool `json:"dm_permission,omitempty"` - NSFW *bool `json:"nsfw,omitempty"` + // Deprecated: Use Contexts instead + DMPermission *bool `json:"dm_permission,omitempty"` + IntegrationTypes *[]ApplicationIntegrationType `json:"integration_types,omitempty"` + Contexts *[]InteractionContextType `json:"contexts,omitempty"` + NSFW *bool `json:"nsfw,omitempty"` } func (c UserCommandUpdate) MarshalJSON() ([]byte, error) { @@ -74,8 +80,11 @@ type MessageCommandUpdate struct { Name *string `json:"name,omitempty"` NameLocalizations *map[Locale]string `json:"name_localizations,omitempty"` DefaultMemberPermissions *json.Nullable[Permissions] `json:"default_member_permissions,omitempty"` - DMPermission *bool `json:"dm_permission,omitempty"` - NSFW *bool `json:"nsfw,omitempty"` + // Deprecated: Use Contexts instead + DMPermission *bool `json:"dm_permission,omitempty"` + IntegrationTypes *[]ApplicationIntegrationType `json:"integration_types,omitempty"` + Contexts *[]InteractionContextType `json:"contexts,omitempty"` + NSFW *bool `json:"nsfw,omitempty"` } func (c MessageCommandUpdate) MarshalJSON() ([]byte, error) { diff --git a/discord/interaction.go b/discord/interaction.go index 0833985c..139c3f5f 100644 --- a/discord/interaction.go +++ b/discord/interaction.go @@ -20,6 +20,14 @@ const ( InteractionTypeModalSubmit ) +type InteractionContextType int + +const ( + InteractionContextTypeGuild InteractionContextType = iota + InteractionContextTypeBotDM + InteractionContextTypePrivateChannel +) + type rawInteraction struct { ID snowflake.ID `json:"id"` Type InteractionType `json:"type"` @@ -28,14 +36,16 @@ type rawInteraction struct { Version int `json:"version"` GuildID *snowflake.ID `json:"guild_id,omitempty"` // Deprecated: Use Channel instead - ChannelID snowflake.ID `json:"channel_id,omitempty"` - Channel InteractionChannel `json:"channel,omitempty"` - Locale Locale `json:"locale,omitempty"` - GuildLocale *Locale `json:"guild_locale,omitempty"` - Member *ResolvedMember `json:"member,omitempty"` - User *User `json:"user,omitempty"` - AppPermissions *Permissions `json:"app_permissions,omitempty"` - Entitlements []Entitlement `json:"entitlements"` + ChannelID snowflake.ID `json:"channel_id,omitempty"` + Channel InteractionChannel `json:"channel,omitempty"` + Locale Locale `json:"locale,omitempty"` + GuildLocale *Locale `json:"guild_locale,omitempty"` + Member *ResolvedMember `json:"member,omitempty"` + User *User `json:"user,omitempty"` + AppPermissions *Permissions `json:"app_permissions,omitempty"` + Entitlements []Entitlement `json:"entitlements"` + AuthorizingIntegrationOwners map[ApplicationIntegrationType]snowflake.ID `json:"authorizing_integration_owners"` + Context InteractionContextType `json:"context"` } // Interaction is used for easier unmarshalling of different Interaction(s) @@ -55,6 +65,8 @@ type Interaction interface { User() User AppPermissions() *Permissions Entitlements() []Entitlement + AuthorizingIntegrationOwners() map[ApplicationIntegrationType]snowflake.ID + Context() InteractionContextType CreatedAt() time.Time interaction() diff --git a/discord/interaction_application_command.go b/discord/interaction_application_command.go index bda98493..0681097c 100644 --- a/discord/interaction_application_command.go +++ b/discord/interaction_application_command.go @@ -79,6 +79,8 @@ func (i *ApplicationCommandInteraction) UnmarshalJSON(data []byte) error { i.baseInteraction.user = interaction.User i.baseInteraction.appPermissions = interaction.AppPermissions i.baseInteraction.entitlements = interaction.Entitlements + i.baseInteraction.authorizingIntegrationOwners = interaction.AuthorizingIntegrationOwners + i.baseInteraction.context = interaction.Context i.Data = interactionData return nil @@ -90,20 +92,22 @@ func (i ApplicationCommandInteraction) MarshalJSON() ([]byte, error) { Data ApplicationCommandInteractionData `json:"data"` }{ rawInteraction: rawInteraction{ - ID: i.id, - Type: i.Type(), - ApplicationID: i.applicationID, - Token: i.token, - Version: i.version, - GuildID: i.guildID, - ChannelID: i.channelID, - Channel: i.channel, - Locale: i.locale, - GuildLocale: i.guildLocale, - Member: i.member, - User: i.user, - AppPermissions: i.appPermissions, - Entitlements: i.entitlements, + ID: i.id, + Type: i.Type(), + ApplicationID: i.applicationID, + Token: i.token, + Version: i.version, + GuildID: i.guildID, + ChannelID: i.channelID, + Channel: i.channel, + Locale: i.locale, + GuildLocale: i.guildLocale, + Member: i.member, + User: i.user, + AppPermissions: i.appPermissions, + Entitlements: i.entitlements, + AuthorizingIntegrationOwners: i.authorizingIntegrationOwners, + Context: i.context, }, Data: i.Data, }) diff --git a/discord/interaction_autocomplete.go b/discord/interaction_autocomplete.go index 03925072..7d78a9f3 100644 --- a/discord/interaction_autocomplete.go +++ b/discord/interaction_autocomplete.go @@ -36,6 +36,8 @@ func (i *AutocompleteInteraction) UnmarshalJSON(data []byte) error { i.baseInteraction.user = interaction.User i.baseInteraction.appPermissions = interaction.AppPermissions i.baseInteraction.entitlements = interaction.Entitlements + i.baseInteraction.authorizingIntegrationOwners = interaction.AuthorizingIntegrationOwners + i.baseInteraction.context = interaction.Context i.Data = interaction.Data return nil @@ -47,20 +49,22 @@ func (i AutocompleteInteraction) MarshalJSON() ([]byte, error) { Data AutocompleteInteractionData `json:"data"` }{ rawInteraction: rawInteraction{ - ID: i.id, - Type: i.Type(), - ApplicationID: i.applicationID, - Token: i.token, - Version: i.version, - GuildID: i.guildID, - ChannelID: i.channelID, - Channel: i.channel, - Locale: i.locale, - GuildLocale: i.guildLocale, - Member: i.member, - User: i.user, - AppPermissions: i.appPermissions, - Entitlements: i.entitlements, + ID: i.id, + Type: i.Type(), + ApplicationID: i.applicationID, + Token: i.token, + Version: i.version, + GuildID: i.guildID, + ChannelID: i.channelID, + Channel: i.channel, + Locale: i.locale, + GuildLocale: i.guildLocale, + Member: i.member, + User: i.user, + AppPermissions: i.appPermissions, + Entitlements: i.entitlements, + AuthorizingIntegrationOwners: i.authorizingIntegrationOwners, + Context: i.context, }, Data: i.Data, }) diff --git a/discord/interaction_base.go b/discord/interaction_base.go index f9d8046a..a4c98b18 100644 --- a/discord/interaction_base.go +++ b/discord/interaction_base.go @@ -7,19 +7,21 @@ import ( ) type baseInteraction struct { - id snowflake.ID - applicationID snowflake.ID - token string - version int - guildID *snowflake.ID - channelID snowflake.ID - channel InteractionChannel - locale Locale - guildLocale *Locale - member *ResolvedMember - user *User - appPermissions *Permissions - entitlements []Entitlement + id snowflake.ID + applicationID snowflake.ID + token string + version int + guildID *snowflake.ID + channelID snowflake.ID + channel InteractionChannel + locale Locale + guildLocale *Locale + member *ResolvedMember + user *User + appPermissions *Permissions + entitlements []Entitlement + authorizingIntegrationOwners map[ApplicationIntegrationType]snowflake.ID + context InteractionContextType } func (i baseInteraction) ID() snowflake.ID { @@ -69,6 +71,14 @@ func (i baseInteraction) Entitlements() []Entitlement { return i.entitlements } +func (i baseInteraction) AuthorizingIntegrationOwners() map[ApplicationIntegrationType]snowflake.ID { + return i.authorizingIntegrationOwners +} + +func (i baseInteraction) Context() InteractionContextType { + return i.context +} + func (i baseInteraction) CreatedAt() time.Time { return i.id.Time() } diff --git a/discord/interaction_component.go b/discord/interaction_component.go index 850530df..c33916be 100644 --- a/discord/interaction_component.go +++ b/discord/interaction_component.go @@ -89,6 +89,8 @@ func (i *ComponentInteraction) UnmarshalJSON(data []byte) error { i.baseInteraction.user = interaction.User i.baseInteraction.appPermissions = interaction.AppPermissions i.baseInteraction.entitlements = interaction.Entitlements + i.baseInteraction.authorizingIntegrationOwners = interaction.AuthorizingIntegrationOwners + i.baseInteraction.context = interaction.Context i.Data = interactionData i.Message = interaction.Message @@ -103,20 +105,22 @@ func (i ComponentInteraction) MarshalJSON() ([]byte, error) { Message Message `json:"message"` }{ rawInteraction: rawInteraction{ - ID: i.id, - Type: i.Type(), - ApplicationID: i.applicationID, - Token: i.token, - Version: i.version, - GuildID: i.guildID, - ChannelID: i.channelID, - Channel: i.channel, - Locale: i.locale, - GuildLocale: i.guildLocale, - Member: i.member, - User: i.user, - AppPermissions: i.appPermissions, - Entitlements: i.entitlements, + ID: i.id, + Type: i.Type(), + ApplicationID: i.applicationID, + Token: i.token, + Version: i.version, + GuildID: i.guildID, + ChannelID: i.channelID, + Channel: i.channel, + Locale: i.locale, + GuildLocale: i.guildLocale, + Member: i.member, + User: i.user, + AppPermissions: i.appPermissions, + Entitlements: i.entitlements, + AuthorizingIntegrationOwners: i.authorizingIntegrationOwners, + Context: i.context, }, Data: i.Data, Message: i.Message, diff --git a/discord/interaction_modal_submit.go b/discord/interaction_modal_submit.go index 03126820..98c4156e 100644 --- a/discord/interaction_modal_submit.go +++ b/discord/interaction_modal_submit.go @@ -33,6 +33,8 @@ func (i *ModalSubmitInteraction) UnmarshalJSON(data []byte) error { i.baseInteraction.user = interaction.User i.baseInteraction.appPermissions = interaction.AppPermissions i.baseInteraction.entitlements = interaction.Entitlements + i.baseInteraction.authorizingIntegrationOwners = interaction.AuthorizingIntegrationOwners + i.baseInteraction.context = interaction.Context i.Data = interaction.Data return nil @@ -44,20 +46,22 @@ func (i ModalSubmitInteraction) MarshalJSON() ([]byte, error) { Data ModalSubmitInteractionData `json:"data"` }{ rawInteraction: rawInteraction{ - ID: i.id, - Type: i.Type(), - ApplicationID: i.applicationID, - Token: i.token, - Version: i.version, - GuildID: i.guildID, - ChannelID: i.channelID, - Channel: i.channel, - Locale: i.locale, - GuildLocale: i.guildLocale, - Member: i.member, - User: i.user, - AppPermissions: i.appPermissions, - Entitlements: i.entitlements, + ID: i.id, + Type: i.Type(), + ApplicationID: i.applicationID, + Token: i.token, + Version: i.version, + GuildID: i.guildID, + ChannelID: i.channelID, + Channel: i.channel, + Locale: i.locale, + GuildLocale: i.guildLocale, + Member: i.member, + User: i.user, + AppPermissions: i.appPermissions, + Entitlements: i.entitlements, + AuthorizingIntegrationOwners: i.authorizingIntegrationOwners, + Context: i.context, }, Data: i.Data, }) diff --git a/discord/interaction_ping.go b/discord/interaction_ping.go index 08e1c890..268d369f 100644 --- a/discord/interaction_ping.go +++ b/discord/interaction_ping.go @@ -100,4 +100,12 @@ func (PingInteraction) Entitlements() []Entitlement { return nil } +func (PingInteraction) AuthorizingIntegrationOwners() map[ApplicationIntegrationType]snowflake.ID { + return nil +} + +func (PingInteraction) Context() InteractionContextType { + return 0 +} + func (PingInteraction) interaction() {} diff --git a/discord/message.go b/discord/message.go index e7a0ff7c..b107c45b 100644 --- a/discord/message.go +++ b/discord/message.go @@ -113,6 +113,7 @@ type Message struct { Thread *MessageThread `json:"thread,omitempty"` Position *int `json:"position,omitempty"` RoleSubscriptionData *RoleSubscriptionData `json:"role_subscription_data,omitempty"` + InteractionMetadata *InteractionMetadata `json:"interaction_metadata,omitempty"` Resolved *ResolvedData `json:"resolved,omitempty"` } @@ -463,3 +464,14 @@ type RoleSubscriptionData struct { TotalMonthsSubscribed int `json:"total_months_subscribed"` IsRenewal bool `json:"is_renewal"` } + +type InteractionMetadata struct { + ID snowflake.ID `json:"id"` + Type InteractionType `json:"type"` + UserID snowflake.ID `json:"user_id"` + AuthorizingIntegrationOwners map[ApplicationIntegrationType]snowflake.ID `json:"authorizing_integration_owners"` + OriginalResponseMessageID *snowflake.ID `json:"original_response_message_id"` + Name *string `json:"name"` + InteractedMessageID *snowflake.ID `json:"interacted_message_id"` + TriggeringInteractionMetadata *InteractionMetadata `json:"triggering_interaction_metadata"` +} diff --git a/oauth2/client.go b/oauth2/client.go index 91cbb27d..4c826baa 100644 --- a/oauth2/client.go +++ b/oauth2/client.go @@ -58,10 +58,10 @@ type Client interface { // StateController returns the configured StateController. StateController() StateController - // GenerateAuthorizationURL generates an authorization URL with the given redirect URI, permissions, guildID, disableGuildSelect & scopes. State is automatically generated. - GenerateAuthorizationURL(redirectURI string, permissions discord.Permissions, guildID snowflake.ID, disableGuildSelect bool, scopes ...discord.OAuth2Scope) string - // GenerateAuthorizationURLState generates an authorization URL with the given redirect URI, permissions, guildID, disableGuildSelect & scopes. State is automatically generated & returned. - GenerateAuthorizationURLState(redirectURI string, permissions discord.Permissions, guildID snowflake.ID, disableGuildSelect bool, scopes ...discord.OAuth2Scope) (string, string) + // GenerateAuthorizationURL generates an authorization URL with the given redirect URI, permissions, guildID, disableGuildSelect, integrationType & scopes. State is automatically generated. + GenerateAuthorizationURL(redirectURI string, permissions discord.Permissions, guildID snowflake.ID, disableGuildSelect bool, integrationType discord.ApplicationIntegrationType, scopes ...discord.OAuth2Scope) string + // GenerateAuthorizationURLState generates an authorization URL with the given redirect URI, permissions, guildID, disableGuildSelect, integrationType & scopes. State is automatically generated & returned. + GenerateAuthorizationURLState(redirectURI string, permissions discord.Permissions, guildID snowflake.ID, disableGuildSelect bool, integrationType discord.ApplicationIntegrationType, scopes ...discord.OAuth2Scope) (string, string) // StartSession starts a new Session with the given authorization code & state. StartSession(code string, state string, opts ...rest.RequestOpt) (Session, *discord.IncomingWebhook, error) diff --git a/oauth2/client_impl.go b/oauth2/client_impl.go index f5d2b586..232e3070 100644 --- a/oauth2/client_impl.go +++ b/oauth2/client_impl.go @@ -47,12 +47,12 @@ func (c *clientImpl) StateController() StateController { return c.stateController } -func (c *clientImpl) GenerateAuthorizationURL(redirectURI string, permissions discord.Permissions, guildID snowflake.ID, disableGuildSelect bool, scopes ...discord.OAuth2Scope) string { - authURL, _ := c.GenerateAuthorizationURLState(redirectURI, permissions, guildID, disableGuildSelect, scopes...) +func (c *clientImpl) GenerateAuthorizationURL(redirectURI string, permissions discord.Permissions, guildID snowflake.ID, disableGuildSelect bool, integrationType discord.ApplicationIntegrationType, scopes ...discord.OAuth2Scope) string { + authURL, _ := c.GenerateAuthorizationURLState(redirectURI, permissions, guildID, disableGuildSelect, integrationType, scopes...) return authURL } -func (c *clientImpl) GenerateAuthorizationURLState(redirectURI string, permissions discord.Permissions, guildID snowflake.ID, disableGuildSelect bool, scopes ...discord.OAuth2Scope) (string, string) { +func (c *clientImpl) GenerateAuthorizationURLState(redirectURI string, permissions discord.Permissions, guildID snowflake.ID, disableGuildSelect bool, integrationType discord.ApplicationIntegrationType, scopes ...discord.OAuth2Scope) (string, string) { state := c.StateController().NewState(redirectURI) values := discord.QueryValues{ "client_id": c.id, @@ -71,6 +71,9 @@ func (c *clientImpl) GenerateAuthorizationURLState(redirectURI string, permissio if disableGuildSelect { values["disable_guild_select"] = true } + if integrationType != 0 { + values["integration_type"] = integrationType + } return discord.AuthorizeURL(values), state }