From afb04c4e3ec235382f2fc6735e7cfc6b548140b6 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Mon, 18 Mar 2024 19:53:22 +0100 Subject: [PATCH 01/10] Add support for user apps --- 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 | 11 +++ 13 files changed, 289 insertions(+), 150 deletions(-) diff --git a/discord/application.go b/discord/application.go index d3045bae8..35e36a88a 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 { @@ -259,3 +262,16 @@ type TeamPermissions string const ( TeamPermissionAdmin = "*" ) + +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 a0e06b78f..b861e55de 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 bf80a0fbd..61104ed74 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 a5fbe038c..404bfef1b 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 33764546f..a91c89c05 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 0833985c5..197f3fb88 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 bda984936..0681097cb 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 039250721..7d78a9f32 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 f9d8046a6..9942754c0 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 850530dfd..c33916bea 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 031268205..98c4156ea 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 08e1c890a..34eb7dd58 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 nil +} + func (PingInteraction) interaction() {} diff --git a/discord/message.go b/discord/message.go index e7a0ff7c8..939a16fea 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,13 @@ 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"` + InteractedMessageID *snowflake.ID `json:"interacted_message_id"` + TriggeringInteractionMetadata *InteractionMetadata `json:"triggering_interaction_metadata"` +} From 8b196751a03f8cc4038e0d88f41c911cd0d9d907 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Tue, 19 Mar 2024 12:59:56 +0100 Subject: [PATCH 02/10] add Name to InteractionMetadata --- discord/message.go | 1 + 1 file changed, 1 insertion(+) diff --git a/discord/message.go b/discord/message.go index 939a16fea..b107c45b1 100644 --- a/discord/message.go +++ b/discord/message.go @@ -471,6 +471,7 @@ type InteractionMetadata struct { 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"` } From 4aabae4ab29280ef9279ef98a57f0d61a8f38901 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Wed, 20 Mar 2024 15:35:51 +0100 Subject: [PATCH 03/10] add integrationType to auth --- oauth2/client.go | 4 ++-- oauth2/client_impl.go | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/oauth2/client.go b/oauth2/client.go index 91cbb27d7..c7a83ee5f 100644 --- a/oauth2/client.go +++ b/oauth2/client.go @@ -59,9 +59,9 @@ type Client interface { 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 + 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 & scopes. State is automatically generated & returned. - GenerateAuthorizationURLState(redirectURI string, permissions discord.Permissions, guildID snowflake.ID, disableGuildSelect bool, scopes ...discord.OAuth2Scope) (string, string) + 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 f5d2b586a..13c157710 100644 --- a/oauth2/client_impl.go +++ b/oauth2/client_impl.go @@ -47,19 +47,20 @@ 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, - "redirect_uri": redirectURI, - "response_type": "code", - "scope": discord.JoinScopes(scopes), - "state": state, + "client_id": c.id, + "redirect_uri": redirectURI, + "response_type": "code", + "scope": discord.JoinScopes(scopes), + "state": state, + "integration_type": integrationType, } if permissions != discord.PermissionsNone { From f55cb04a1cd759c8ef293acd7a815eddbfb618af Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Wed, 20 Mar 2024 15:56:28 +0100 Subject: [PATCH 04/10] fix examples --- _examples/oauth2/example.go | 2 +- _examples/verified_roles/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_examples/oauth2/example.go b/_examples/oauth2/example.go index 6e1c323fd..0154c7276 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, discord.ApplicationIntegrationTypeGuildInstall, 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 2fadbaa57..f4d26f8fb 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, discord.ApplicationIntegrationTypeGuildInstall, discord.OAuth2ScopeIdentify, discord.OAuth2ScopeRoleConnectionsWrite), http.StatusTemporaryRedirect) } func handleCallback(w http.ResponseWriter, r *http.Request) { From db2bd889c385b768b04115a5649f1d0105f7998d Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Wed, 20 Mar 2024 16:18:15 +0100 Subject: [PATCH 05/10] omit default integration_type v2 --- oauth2/client_impl.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/oauth2/client_impl.go b/oauth2/client_impl.go index 13c157710..96d17cefe 100644 --- a/oauth2/client_impl.go +++ b/oauth2/client_impl.go @@ -72,6 +72,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 } From 6f9b2e69b95c29f3b03bd7be8a481beb5bea7239 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Wed, 20 Mar 2024 16:18:24 +0100 Subject: [PATCH 06/10] fuck --- oauth2/client_impl.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/oauth2/client_impl.go b/oauth2/client_impl.go index 96d17cefe..232e30709 100644 --- a/oauth2/client_impl.go +++ b/oauth2/client_impl.go @@ -55,12 +55,11 @@ func (c *clientImpl) GenerateAuthorizationURL(redirectURI string, permissions di 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, - "redirect_uri": redirectURI, - "response_type": "code", - "scope": discord.JoinScopes(scopes), - "state": state, - "integration_type": integrationType, + "client_id": c.id, + "redirect_uri": redirectURI, + "response_type": "code", + "scope": discord.JoinScopes(scopes), + "state": state, } if permissions != discord.PermissionsNone { From 75d65aa23344b07b634d63a86fcf702c8878e479 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Wed, 20 Mar 2024 16:20:56 +0100 Subject: [PATCH 07/10] don't explicitly use integration const --- _examples/oauth2/example.go | 2 +- _examples/verified_roles/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_examples/oauth2/example.go b/_examples/oauth2/example.go index 0154c7276..29687fa35 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.ApplicationIntegrationTypeGuildInstall, 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 f4d26f8fb..d3ef5e959 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.ApplicationIntegrationTypeGuildInstall, 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) { From 428cbb0293284c6a60ee453ed718c1ca195f530d Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Wed, 20 Mar 2024 20:22:38 +0100 Subject: [PATCH 08/10] mention integrationType in docs --- oauth2/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oauth2/client.go b/oauth2/client.go index c7a83ee5f..4c826baa6 100644 --- a/oauth2/client.go +++ b/oauth2/client.go @@ -58,9 +58,9 @@ 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 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 & scopes. State is automatically generated & returned. + // 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. From 5bea14e44dcdd69f37cfc63f1af9efd51be67015 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Tue, 2 Apr 2024 20:28:39 +0200 Subject: [PATCH 09/10] make OAuth2InstallParams a pointer --- discord/application.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/application.go b/discord/application.go index ee164df76..c100abe9a 100644 --- a/discord/application.go +++ b/discord/application.go @@ -275,5 +275,5 @@ const ( type ApplicationIntegrationTypesConfig map[ApplicationIntegrationType]ApplicationIntegrationTypeConfiguration type ApplicationIntegrationTypeConfiguration struct { - OAuth2InstallParams InstallParams `json:"oauth2_install_params"` + OAuth2InstallParams *InstallParams `json:"oauth2_install_params"` } From 4a3a8e52b06832c7c622f90519a357f6d19f2b33 Mon Sep 17 00:00:00 2001 From: mlnrDev Date: Mon, 8 Apr 2024 00:11:30 +0200 Subject: [PATCH 10/10] dont use pointer for InteractionContextType --- discord/interaction.go | 4 ++-- discord/interaction_base.go | 4 ++-- discord/interaction_ping.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/discord/interaction.go b/discord/interaction.go index 197f3fb88..139c3f5f0 100644 --- a/discord/interaction.go +++ b/discord/interaction.go @@ -45,7 +45,7 @@ type rawInteraction struct { AppPermissions *Permissions `json:"app_permissions,omitempty"` Entitlements []Entitlement `json:"entitlements"` AuthorizingIntegrationOwners map[ApplicationIntegrationType]snowflake.ID `json:"authorizing_integration_owners"` - Context *InteractionContextType `json:"context"` + Context InteractionContextType `json:"context"` } // Interaction is used for easier unmarshalling of different Interaction(s) @@ -66,7 +66,7 @@ type Interaction interface { AppPermissions() *Permissions Entitlements() []Entitlement AuthorizingIntegrationOwners() map[ApplicationIntegrationType]snowflake.ID - Context() *InteractionContextType + Context() InteractionContextType CreatedAt() time.Time interaction() diff --git a/discord/interaction_base.go b/discord/interaction_base.go index 9942754c0..a4c98b182 100644 --- a/discord/interaction_base.go +++ b/discord/interaction_base.go @@ -21,7 +21,7 @@ type baseInteraction struct { appPermissions *Permissions entitlements []Entitlement authorizingIntegrationOwners map[ApplicationIntegrationType]snowflake.ID - context *InteractionContextType + context InteractionContextType } func (i baseInteraction) ID() snowflake.ID { @@ -75,7 +75,7 @@ func (i baseInteraction) AuthorizingIntegrationOwners() map[ApplicationIntegrati return i.authorizingIntegrationOwners } -func (i baseInteraction) Context() *InteractionContextType { +func (i baseInteraction) Context() InteractionContextType { return i.context } diff --git a/discord/interaction_ping.go b/discord/interaction_ping.go index 34eb7dd58..268d369fb 100644 --- a/discord/interaction_ping.go +++ b/discord/interaction_ping.go @@ -104,8 +104,8 @@ func (PingInteraction) AuthorizingIntegrationOwners() map[ApplicationIntegration return nil } -func (PingInteraction) Context() *InteractionContextType { - return nil +func (PingInteraction) Context() InteractionContextType { + return 0 } func (PingInteraction) interaction() {}