From 2ab32b192242cc0af101ff5f37fe6be860f445ec Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Mon, 29 Apr 2024 14:24:33 -0400 Subject: [PATCH 01/22] fix(api): Register converters for metadata --- .../Extensions/ServiceCollectionExtensions.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs index 5decb3ea76..82129626e4 100644 --- a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs +++ b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs @@ -1184,6 +1184,10 @@ private static JsonSerializerOptions AddInteractionObjectConverters(this JsonSer options.AddDataObjectConverter(); + options.AddDataObjectConverter(); + options.AddDataObjectConverter(); + options.AddDataObjectConverter(); + return options; } From b924cd0355b7859f408bdf25889638b897596421 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Mon, 29 Apr 2024 14:28:33 -0400 Subject: [PATCH 02/22] fix(api): Change UserID to User in accordance to Discord's new update --- .../API/Objects/Interactions/IMessageInteractionMetadata.cs | 2 +- .../Interactions/ApplicationCommandInteractionMetadata.cs | 2 +- .../Objects/Interactions/MessageComponentInteractionMetadata.cs | 2 +- .../API/Objects/Interactions/ModalSubmitInteractionMetadata.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs index 8e2decdbc1..2ff24394b0 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs @@ -40,7 +40,7 @@ public interface IMessageInteractionMetadata /// /// Gets the ID of the user who triggered the interaction. /// - Snowflake UserID { get; } + IUser User { get; } /// /// Gets the type of the interaction. diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommandInteractionMetadata.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommandInteractionMetadata.cs index 83714785d2..f02ee5f259 100644 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommandInteractionMetadata.cs +++ b/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommandInteractionMetadata.cs @@ -32,7 +32,7 @@ namespace Remora.Discord.API.Objects; public record ApplicationCommandInteractionMetadata ( Snowflake ID, - Snowflake UserID, + IUser User, InteractionType Type, Optional OriginalResponseMessageID, IReadOnlyDictionary AuthorizingIntegrationOwners, diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/MessageComponentInteractionMetadata.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/MessageComponentInteractionMetadata.cs index 701a08d5e8..da26a3e9f8 100644 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/MessageComponentInteractionMetadata.cs +++ b/Backend/Remora.Discord.API/API/Objects/Interactions/MessageComponentInteractionMetadata.cs @@ -32,7 +32,7 @@ namespace Remora.Discord.API.Objects; public record MessageComponentInteractionMetadata ( Snowflake ID, - Snowflake UserID, + IUser User, InteractionType Type, Optional OriginalResponseMessageID, IReadOnlyDictionary AuthorizingIntegrationOwners, diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/ModalSubmitInteractionMetadata.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/ModalSubmitInteractionMetadata.cs index 0ddf24ab7f..60d0288e09 100644 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/ModalSubmitInteractionMetadata.cs +++ b/Backend/Remora.Discord.API/API/Objects/Interactions/ModalSubmitInteractionMetadata.cs @@ -33,7 +33,7 @@ namespace Remora.Discord.API.Objects; public record ModalSubmitInteractionMetadata ( Snowflake ID, - Snowflake UserID, + IUser User, InteractionType Type, Optional OriginalResponseMessageID, IReadOnlyDictionary AuthorizingIntegrationOwners, From 29a492265b6dc4636da255b67f77451b41906c86 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Mon, 29 Apr 2024 14:34:22 -0400 Subject: [PATCH 03/22] fix: Update nullability of integration types --- .../Interactions/ApplicationCommands/IApplicationCommand.cs | 2 +- .../Interactions/ApplicationCommands/ApplicationCommand.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/ApplicationCommands/IApplicationCommand.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/ApplicationCommands/IApplicationCommand.cs index f4f8607d5b..5628508ed3 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/ApplicationCommands/IApplicationCommand.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/ApplicationCommands/IApplicationCommand.cs @@ -123,5 +123,5 @@ public interface IApplicationCommand /// /// Gets a value indicating the contexts in which this command can be invoked. /// - Optional> Contexts { get; } + Optional?> Contexts { get; } } diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommands/ApplicationCommand.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommands/ApplicationCommand.cs index d909a12895..b47f8772bf 100644 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommands/ApplicationCommand.cs +++ b/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommands/ApplicationCommand.cs @@ -49,5 +49,5 @@ public record ApplicationCommand Optional DMPermission = default, Optional IsNsfw = default, Optional> IntegrationTypes = default, - Optional> Contexts = default + Optional?> Contexts = default ) : IApplicationCommand; From ef632cbf493607e1c6e4cd901f9d6ff419bcf711 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Mon, 29 Apr 2024 15:06:16 -0400 Subject: [PATCH 04/22] fix: Fix application edit endpoint --- .../API/Rest/IDiscordRestApplicationAPI.cs | 4 ++-- .../API/Applications/DiscordRestApplicationAPI.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs index cb703bd09a..bdaa2d8458 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs @@ -410,7 +410,7 @@ Task>> UpdateApplicatio /// The new cover image. /// The new interactions endpoint URL. /// The new tags. - /// The new integration types. + /// The new integration types. /// The cancellation token for this operation. /// The updated application. Task> EditCurrentApplicationAsync @@ -424,7 +424,7 @@ Task> EditCurrentApplicationAsync Optional coverImage = default, Optional interactionsEndpointUrl = default, Optional> tags = default, - Optional> integrationTypes = default, + Optional> integrationTypeConfig = default, CancellationToken ct = default ); } diff --git a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs index dc97d60fc6..d0e0616826 100644 --- a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs +++ b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs @@ -234,7 +234,7 @@ public virtual async Task> EditGlobalApplicationComm Optional defaultMemberPermissions = default, Optional dmPermission = default, Optional isNsfw = default, - Optional> allowedIntegrationTypes = default, + Optional> integrationTypesConfig = default, Optional> allowedContextTypes = default, CancellationToken ct = default ) @@ -274,7 +274,7 @@ public virtual async Task> EditGlobalApplicationComm json.Write("dm_permission", dmPermission, this.JsonOptions); json.Write("nsfw", isNsfw, this.JsonOptions); json.Write("contexts", allowedContextTypes, this.JsonOptions); - json.Write("integration_types", allowedIntegrationTypes, this.JsonOptions); + json.Write("integration_types_config", integrationTypesConfig, this.JsonOptions); } ) .WithRateLimitContext(this.RateLimitCache), @@ -683,7 +683,7 @@ public async Task> EditCurrentApplicationAsync Optional coverImage = default, Optional interactionsEndpointUrl = default, Optional> tags = default, - Optional> integrationTypes = default, + Optional> integrationTypes = default, CancellationToken ct = default ) { From 7bdac3c603ad9433365d8d6cb68a1ca2d3e458f4 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Mon, 29 Apr 2024 15:51:05 -0400 Subject: [PATCH 05/22] fix: Fix tests and json for sending --- .../API/Rest/IDiscordRestApplicationAPI.cs | 4 ++-- .../API/Applications/DiscordRestApplicationAPI.cs | 4 ++-- .../DiscordRestApplicationAPITests.cs | 15 +++++++-------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs index bdaa2d8458..e132994645 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs @@ -410,7 +410,7 @@ Task>> UpdateApplicatio /// The new cover image. /// The new interactions endpoint URL. /// The new tags. - /// The new integration types. + /// The new integration types. /// The cancellation token for this operation. /// The updated application. Task> EditCurrentApplicationAsync @@ -424,7 +424,7 @@ Task> EditCurrentApplicationAsync Optional coverImage = default, Optional interactionsEndpointUrl = default, Optional> tags = default, - Optional> integrationTypeConfig = default, + Optional> integrationTypesConfig = default, CancellationToken ct = default ); } diff --git a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs index d0e0616826..0baf8f6cb2 100644 --- a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs +++ b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs @@ -683,7 +683,7 @@ public async Task> EditCurrentApplicationAsync Optional coverImage = default, Optional interactionsEndpointUrl = default, Optional> tags = default, - Optional> integrationTypes = default, + Optional> integrationTypesConfig = default, CancellationToken ct = default ) { @@ -726,7 +726,7 @@ public async Task> EditCurrentApplicationAsync json.Write("cover_image", base64EncodedCover, this.JsonOptions); json.Write("interactions_endpoint_url", interactionsEndpointUrl, this.JsonOptions); json.Write("tags", tags, this.JsonOptions); - json.Write("integration_types", integrationTypes, this.JsonOptions); + json.Write("integration_types_config", integrationTypesConfig, this.JsonOptions); } ); diff --git a/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs b/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs index 90eca8f418..1b03011f9e 100644 --- a/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs +++ b/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs @@ -2495,10 +2495,10 @@ public async Task PerformsRequestCorrectly() var interactionsEndpointUrl = new Uri("https://example.org/interact"); var tags = new[] { "ooga", "booga" }; - var integrationTypes = new[] + var integrationTypes = new Dictionary { - ApplicationIntegrationType.UserInstallable, - ApplicationIntegrationType.GuildInstallable + { ApplicationIntegrationType.UserInstallable, new ApplicationIntegrationTypeConfig(new ApplicationOAuth2InstallParams(DiscordPermissionSet.Empty, Array.Empty())) }, + { ApplicationIntegrationType.GuildInstallable, new ApplicationIntegrationTypeConfig(new ApplicationOAuth2InstallParams(DiscordPermissionSet.Empty, Array.Empty())) }, }; var api = CreateAPI @@ -2542,12 +2542,11 @@ public async Task PerformsRequestCorrectly() ) .WithProperty ( - "integration_types", - p => p.IsArray + "integration_types_config", + p => p.IsObject ( - a => a.WithCount(2) - .WithElement(0, e => e.Is("1")) - .WithElement(1, e => e.Is("0")) + a => a.WithProperty("0", p => p.IsObject()) + .WithProperty("1", p => p.IsObject()) ) ) ) From 70f13d14f51de684fa20b281774ffa8886309bbe Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 3 May 2024 15:49:23 -0400 Subject: [PATCH 06/22] refactor(api): Merge metadata into single class --- .../IApplicationCommandInteractionMetadata.cs | 37 ----------------- .../IMessageComponentInteractionMetadata.cs | 38 ----------------- .../IMessageInteractionMetadata.cs | 15 +++++++ .../IModalSubmitInteractionMetadata.cs | 38 ----------------- .../API/Objects/Messages/IMessage.cs | 4 +- .../API/Objects/Messages/IPartialMessage.cs | 2 +- .../Remora.Discord.API.Abstractions.csproj | 9 ---- .../Gateway/Events/Messages/MessageCreate.cs | 2 +- .../Gateway/Events/Messages/MessageUpdate.cs | 2 +- .../ApplicationCommandInteractionMetadata.cs | 40 ------------------ ...adata.cs => MessageInteractionMetadata.cs} | 14 ++++--- .../ModalSubmitInteractionMetadata.cs | 41 ------------------- .../API/Objects/Messages/Message.cs | 2 +- .../API/Objects/Messages/PartialMessage.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 4 +- .../Objects/INTERACTION/INTERACTION.json | 7 +++- .../Samples/Objects/MESSAGE/MESSAGE.json | 14 +++++++ 17 files changed, 51 insertions(+), 220 deletions(-) delete mode 100644 Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IApplicationCommandInteractionMetadata.cs delete mode 100644 Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageComponentInteractionMetadata.cs delete mode 100644 Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IModalSubmitInteractionMetadata.cs delete mode 100644 Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommandInteractionMetadata.cs rename Backend/Remora.Discord.API/API/Objects/Interactions/{MessageComponentInteractionMetadata.cs => MessageInteractionMetadata.cs} (79%) delete mode 100644 Backend/Remora.Discord.API/API/Objects/Interactions/ModalSubmitInteractionMetadata.cs diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IApplicationCommandInteractionMetadata.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IApplicationCommandInteractionMetadata.cs deleted file mode 100644 index 2b7349b175..0000000000 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IApplicationCommandInteractionMetadata.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// IApplicationCommandInteractionMetadata.cs -// -// Author: -// Jarl Gullberg -// -// Copyright (c) Jarl Gullberg -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see . -// - -using JetBrains.Annotations; - -namespace Remora.Discord.API.Abstractions.Objects; - -/// -/// Represents metadata related to application commands. -/// -[PublicAPI] -public interface IApplicationCommandInteractionMetadata : IMessageInteractionMetadata -{ - /// - /// Gets the name of the command. - /// - string Name { get; } -} diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageComponentInteractionMetadata.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageComponentInteractionMetadata.cs deleted file mode 100644 index 36725b1112..0000000000 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageComponentInteractionMetadata.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// IMessageComponentInteractionMetadata.cs -// -// Author: -// Jarl Gullberg -// -// Copyright (c) Jarl Gullberg -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see . -// - -using JetBrains.Annotations; -using Remora.Rest.Core; - -namespace Remora.Discord.API.Abstractions.Objects; - -/// -/// Represents metadata related to a message component interaction. -/// -[PublicAPI] -public interface IMessageComponentInteractionMetadata : IMessageInteractionMetadata -{ - /// - /// Gets the ID of the message that was interacted with. - /// - Snowflake InteractedMessageID { get; } -} diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs index 2ff24394b0..701c6d3ca6 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs @@ -42,6 +42,11 @@ public interface IMessageInteractionMetadata /// IUser User { get; } + /// + /// Gets the name of the command. + /// + Optional Name { get; } + /// /// Gets the type of the interaction. /// @@ -52,6 +57,11 @@ public interface IMessageInteractionMetadata /// Optional OriginalResponseMessageID { get; } + /// + /// Gets the ID of the message containing the interactive component; only applicable to component interactions. + /// + Optional InteractedMessageID { get; } + /// /// Gets the integrations that authorized the interaction. /// @@ -65,4 +75,9 @@ public interface IMessageInteractionMetadata /// /// IReadOnlyDictionary AuthorizingIntegrationOwners { get; } + + /// + /// Gets the interaction metadata responsible, if this is a response to a modal. + /// + Optional TriggeringInteractionMetadata { get; } } diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IModalSubmitInteractionMetadata.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IModalSubmitInteractionMetadata.cs deleted file mode 100644 index 2c2dfd30e1..0000000000 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IModalSubmitInteractionMetadata.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// IModalSubmitInteractionMetadata.cs -// -// Author: -// Jarl Gullberg -// -// Copyright (c) Jarl Gullberg -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see . -// - -using JetBrains.Annotations; -using OneOf; - -namespace Remora.Discord.API.Abstractions.Objects; - -/// -/// Represents metadata related to a modal submit interaction. -/// -[PublicAPI] -public interface IModalSubmitInteractionMetadata : IMessageInteractionMetadata -{ - /// - /// Gets the metadata for the interaction that triggered the modal. - /// - OneOf TriggeringInteractionMetadata { get; } -} diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Messages/IMessage.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Messages/IMessage.cs index 6e8a968238..d293ce5dba 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Messages/IMessage.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Messages/IMessage.cs @@ -197,7 +197,7 @@ public interface IMessage : IPartialMessage /// /// Gets the metadata of the interaction, if any. /// - new Optional> InteractionMetadata { get; } + new Optional InteractionMetadata { get; } /// Optional IPartialMessage.ID => this.ID; @@ -290,5 +290,5 @@ public interface IMessage : IPartialMessage Optional IPartialMessage.Resolved => this.Resolved; /// - Optional> IPartialMessage.InteractionMetadata => this.InteractionMetadata; + Optional IPartialMessage.InteractionMetadata => this.InteractionMetadata; } diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Messages/IPartialMessage.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Messages/IPartialMessage.cs index e8cd370eb8..986c922b27 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Messages/IPartialMessage.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Messages/IPartialMessage.cs @@ -125,5 +125,5 @@ public interface IPartialMessage Optional Resolved { get; } /// - Optional> InteractionMetadata { get; } + Optional InteractionMetadata { get; } } diff --git a/Backend/Remora.Discord.API.Abstractions/Remora.Discord.API.Abstractions.csproj b/Backend/Remora.Discord.API.Abstractions/Remora.Discord.API.Abstractions.csproj index 7ca89deb06..6d51932ace 100644 --- a/Backend/Remora.Discord.API.Abstractions/Remora.Discord.API.Abstractions.csproj +++ b/Backend/Remora.Discord.API.Abstractions/Remora.Discord.API.Abstractions.csproj @@ -117,15 +117,6 @@ IDiscordRestGuildAPI.cs - - IMessageInteractionMetadata.cs - - - IMessageInteractionMetadata.cs - - - IMessageInteractionMetadata.cs - diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Messages/MessageCreate.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Messages/MessageCreate.cs index 4ff3e7c950..169e8196f0 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Messages/MessageCreate.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Messages/MessageCreate.cs @@ -66,5 +66,5 @@ public record MessageCreate Optional> StickerItems = default, Optional Position = default, Optional Resolved = default, - Optional> InteractionMetadata = default + Optional InteractionMetadata = default ) : IMessageCreate; diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Messages/MessageUpdate.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Messages/MessageUpdate.cs index d3d5591ccf..27a6fdce0f 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Messages/MessageUpdate.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Messages/MessageUpdate.cs @@ -66,5 +66,5 @@ public record MessageUpdate Optional> StickerItems = default, Optional Position = default, Optional Resolved = default, - Optional> InteractionMetadata = default + Optional InteractionMetadata = default ) : IMessageUpdate; diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommandInteractionMetadata.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommandInteractionMetadata.cs deleted file mode 100644 index f02ee5f259..0000000000 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationCommandInteractionMetadata.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// ApplicationCommandInteractionMetadata.cs -// -// Author: -// Jarl Gullberg -// -// Copyright (c) Jarl Gullberg -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see . -// - -using System.Collections.Generic; -using JetBrains.Annotations; -using Remora.Discord.API.Abstractions.Objects; -using Remora.Rest.Core; - -namespace Remora.Discord.API.Objects; - -/// -[PublicAPI] -public record ApplicationCommandInteractionMetadata -( - Snowflake ID, - IUser User, - InteractionType Type, - Optional OriginalResponseMessageID, - IReadOnlyDictionary AuthorizingIntegrationOwners, - string Name -) : IApplicationCommandInteractionMetadata; diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/MessageComponentInteractionMetadata.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/MessageInteractionMetadata.cs similarity index 79% rename from Backend/Remora.Discord.API/API/Objects/Interactions/MessageComponentInteractionMetadata.cs rename to Backend/Remora.Discord.API/API/Objects/Interactions/MessageInteractionMetadata.cs index da26a3e9f8..11f7a221ae 100644 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/MessageComponentInteractionMetadata.cs +++ b/Backend/Remora.Discord.API/API/Objects/Interactions/MessageInteractionMetadata.cs @@ -1,5 +1,5 @@ // -// MessageComponentInteractionMetadata.cs +// MessageInteractionMetadata.cs // // Author: // Jarl Gullberg @@ -27,14 +27,16 @@ namespace Remora.Discord.API.Objects; -/// +/// [PublicAPI] -public record MessageComponentInteractionMetadata +public record MessageInteractionMetadata ( Snowflake ID, IUser User, - InteractionType Type, + Optional Name, Optional OriginalResponseMessageID, + Optional InteractedMessageID, + InteractionType Type, IReadOnlyDictionary AuthorizingIntegrationOwners, - Snowflake InteractedMessageID -) : IMessageComponentInteractionMetadata; + Optional TriggeringInteractionMetadata +) : IMessageInteractionMetadata; diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/ModalSubmitInteractionMetadata.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/ModalSubmitInteractionMetadata.cs deleted file mode 100644 index 60d0288e09..0000000000 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/ModalSubmitInteractionMetadata.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// ModalSubmitInteractionMetadata.cs -// -// Author: -// Jarl Gullberg -// -// Copyright (c) Jarl Gullberg -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see . -// - -using System.Collections.Generic; -using JetBrains.Annotations; -using OneOf; -using Remora.Discord.API.Abstractions.Objects; -using Remora.Rest.Core; - -namespace Remora.Discord.API.Objects; - -/// -[PublicAPI] -public record ModalSubmitInteractionMetadata -( - Snowflake ID, - IUser User, - InteractionType Type, - Optional OriginalResponseMessageID, - IReadOnlyDictionary AuthorizingIntegrationOwners, - OneOf TriggeringInteractionMetadata -) : IModalSubmitInteractionMetadata; diff --git a/Backend/Remora.Discord.API/API/Objects/Messages/Message.cs b/Backend/Remora.Discord.API/API/Objects/Messages/Message.cs index 480d9ef1da..78ec868e7e 100644 --- a/Backend/Remora.Discord.API/API/Objects/Messages/Message.cs +++ b/Backend/Remora.Discord.API/API/Objects/Messages/Message.cs @@ -65,5 +65,5 @@ public record Message Optional> StickerItems = default, Optional Position = default, Optional Resolved = default, - Optional> InteractionMetadata = default + Optional InteractionMetadata = default ) : IMessage; diff --git a/Backend/Remora.Discord.API/API/Objects/Messages/PartialMessage.cs b/Backend/Remora.Discord.API/API/Objects/Messages/PartialMessage.cs index d1bd60826b..f37ad8a54b 100644 --- a/Backend/Remora.Discord.API/API/Objects/Messages/PartialMessage.cs +++ b/Backend/Remora.Discord.API/API/Objects/Messages/PartialMessage.cs @@ -65,5 +65,5 @@ public record PartialMessage Optional> StickerItems = default, Optional Position = default, Optional Resolved = default, - Optional> InteractionMetadata = default + Optional InteractionMetadata = default ) : IPartialMessage; diff --git a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs index 82129626e4..638cb9d6be 100644 --- a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs +++ b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs @@ -1184,9 +1184,7 @@ private static JsonSerializerOptions AddInteractionObjectConverters(this JsonSer options.AddDataObjectConverter(); - options.AddDataObjectConverter(); - options.AddDataObjectConverter(); - options.AddDataObjectConverter(); + options.AddDataObjectConverter(); return options; } diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/INTERACTION/INTERACTION.json b/Tests/Remora.Discord.Tests/Samples/Objects/INTERACTION/INTERACTION.json index 15d8ef5e71..0085768c3d 100644 --- a/Tests/Remora.Discord.Tests/Samples/Objects/INTERACTION/INTERACTION.json +++ b/Tests/Remora.Discord.Tests/Samples/Objects/INTERACTION/INTERACTION.json @@ -58,5 +58,10 @@ "type": 8, "deleted": false } - ] + ], + "authorizing_integration_owners": { + "0": "999999999999999999", + "1": "999999999999999999" + }, + "context": 0 } diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE/MESSAGE.json b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE/MESSAGE.json index cd4644aabc..87aa15dc9f 100644 --- a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE/MESSAGE.json +++ b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE/MESSAGE.json @@ -102,6 +102,20 @@ "avatar": "68b329da9893e34099c7d8ad5cb9c940" } }, + "interaction_metadata": { + "id": "999999999999999999", + "type": 2, + "user": { + "username": "none", + "discriminator": "9999", + "id": "999999999999999999", + "avatar": "68b329da9893e34099c7d8ad5cb9c940" + }, + "authorizing_integration_owners": { + "0": "999999999999999999", + "1": "999999999999999999" + } + }, "thread": { "id": "999999999999999999", "type": 1 From 9e027f56f5b668a89415c3c6f62ddf8d0bff0099 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Sat, 4 May 2024 14:03:14 -0400 Subject: [PATCH 07/22] test: Add json payloads --- ...ESSAGE_INTERACTION_METADATA.component.json | 16 ++++++++++ ...MESSAGE_INTERACTION_METADATA.followup.json | 16 ++++++++++ .../MESSAGE_INTERACTION_METADATA.modal.json | 29 +++++++++++++++++++ ...ESSAGE_INTERACTION_METADATA.optionals.json | 14 +++++++++ 4 files changed, 75 insertions(+) create mode 100644 Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.component.json create mode 100644 Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.followup.json create mode 100644 Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.modal.json create mode 100644 Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.optionals.json diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.component.json b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.component.json new file mode 100644 index 0000000000..a0b6403887 --- /dev/null +++ b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.component.json @@ -0,0 +1,16 @@ +{ + "id": "999999999999999999", + "type": 3, + "user": { + "username": "none", + "discriminator": "9999", + "id": "999999999999999999", + "avatar": "68b329da9893e34099c7d8ad5cb9c940" + }, + "authorizing_integration_owners": { + "0": "999999999999999999", + "1": "999999999999999999" + }, + "original_response_message_id": "999999999999999999", + "interacted_message_id": "999999999999999999" +} \ No newline at end of file diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.followup.json b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.followup.json new file mode 100644 index 0000000000..2992d62bed --- /dev/null +++ b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.followup.json @@ -0,0 +1,16 @@ +{ + "id": "999999999999999999", + "type": 2, + "user": { + "username": "none", + "discriminator": "9999", + "id": "999999999999999999", + "avatar": "68b329da9893e34099c7d8ad5cb9c940" + }, + "authorizing_integration_owners": { + "0": "999999999999999999", + "1": "999999999999999999" + }, + "name": "ooga", + "original_response_message_id": "999999999999999999" +} \ No newline at end of file diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.modal.json b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.modal.json new file mode 100644 index 0000000000..d6c9570e5b --- /dev/null +++ b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.modal.json @@ -0,0 +1,29 @@ +{ + "id": "999999999999999999", + "type": 5, + "user": { + "username": "none", + "discriminator": "9999", + "id": "999999999999999999", + "avatar": "68b329da9893e34099c7d8ad5cb9c940" + }, + "authorizing_integration_owners": { + "0": "999999999999999999", + "1": "999999999999999999" + }, + "triggering_interaction_metadata": { + "id": "999999999999999999", + "type": 2, + "user": { + "username": "none", + "discriminator": "9999", + "id": "999999999999999999", + "avatar": "68b329da9893e34099c7d8ad5cb9c940" + }, + "authorizing_integration_owners": { + "0": "999999999999999999", + "1": "999999999999999999" + }, + "name": "ooga" + } +} \ No newline at end of file diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.optionals.json b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.optionals.json new file mode 100644 index 0000000000..59b54b9364 --- /dev/null +++ b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.optionals.json @@ -0,0 +1,14 @@ +{ + "id": "999999999999999999", + "type": 2, + "user": { + "username": "none", + "discriminator": "9999", + "id": "999999999999999999", + "avatar": "68b329da9893e34099c7d8ad5cb9c940" + }, + "authorizing_integration_owners": { + "0": "999999999999999999", + "1": "999999999999999999" + } +} \ No newline at end of file From 7288f91123a3533ec772ab1c55d3bdab8249bb5c Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Mon, 6 May 2024 20:45:25 -0400 Subject: [PATCH 08/22] test: Add test for IMessageInteractionMetadata --- .../MessageInteractionMetadataTests.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Tests/Remora.Discord.API.Tests/API/Objects/Interactions/MessageInteractionMetadataTests.cs diff --git a/Tests/Remora.Discord.API.Tests/API/Objects/Interactions/MessageInteractionMetadataTests.cs b/Tests/Remora.Discord.API.Tests/API/Objects/Interactions/MessageInteractionMetadataTests.cs new file mode 100644 index 0000000000..a24e379b89 --- /dev/null +++ b/Tests/Remora.Discord.API.Tests/API/Objects/Interactions/MessageInteractionMetadataTests.cs @@ -0,0 +1,39 @@ +// +// MessageInteractionMetadataTests.cs +// +// Author: +// Jarl Gullberg +// +// Copyright (c) Jarl Gullberg +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +using Remora.Discord.API.Abstractions.Objects; +using Remora.Discord.API.Tests.TestBases; + +namespace Remora.Discord.API.Tests.Objects; + +/// +public class MessageInteractionMetadataTests : ObjectTestBase +{ + /// + /// Initializes a new instance of the class. + /// + /// The test fixture. + public MessageInteractionMetadataTests(JsonBackedTypeTestFixture fixture) + : base(fixture) + { + } +} From 061cfd4e60ccb7c4af093f81d063a2b1b6a53a32 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Thu, 9 May 2024 08:07:35 -0400 Subject: [PATCH 09/22] fix: Remove erroneous converter & add missing json This removes the string enum converter for ApplicationIntegrationType, which caused deserialization to fail due to the fact that Discord accepted a stringified value, but would return a numeric value in the response payload, which the enum converter cannot handle. Missing JSON fields (`contexts`, `integration_types` have also been added, as they were previously missing, and likely would've caught this issue. A new converter type was also added to fix this confounding issue, but it breaks on `Optional>` which confuses me. This is being posted purely for debugging purposes, and is known to be broken at this point for reasons entirely beyond me and perhaps even God. --- .../Extensions/ServiceCollectionExtensions.cs | 6 +- .../IntegrationTypeConfigConverter.cs | 94 +++++++++++++++++++ .../APPLICATION_COMMAND.json | 4 +- 3 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 Backend/Remora.Discord.API/Json/Converters/Internal/IntegrationTypeConfigConverter.cs diff --git a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs index c6aa322552..59760d7ef2 100644 --- a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs +++ b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs @@ -21,6 +21,7 @@ // using System.Text.Json; +using System.Text.Json.Serialization; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -1204,7 +1205,8 @@ private static JsonSerializerOptions AddOAuth2ObjectConverters(this JsonSerializ options.AddDataObjectConverter() .WithPropertyName(a => a.IsBotPublic, "bot_public") .WithPropertyName(a => a.DoesBotRequireCodeGrant, "bot_require_code_grant") - .WithPropertyName(a => a.PrimarySKUID, "primary_sku_id"); + .WithPropertyName(a => a.PrimarySKUID, "primary_sku_id") + .WithPropertyConverter(a => a.IntegrationTypesConfig, new IntegrationTypeConfigConverter()); options.AddDataObjectConverter() .WithPropertyName(a => a.IsBotPublic, "bot_public") @@ -1220,7 +1222,7 @@ private static JsonSerializerOptions AddOAuth2ObjectConverters(this JsonSerializ options.AddDataObjectConverter(); - options.Converters.Insert(0, new StringEnumConverter(options.PropertyNamingPolicy, true)); + //options.Converters.Insert(0, new JsonNumberEnumConverter()); return options; } diff --git a/Backend/Remora.Discord.API/Json/Converters/Internal/IntegrationTypeConfigConverter.cs b/Backend/Remora.Discord.API/Json/Converters/Internal/IntegrationTypeConfigConverter.cs new file mode 100644 index 0000000000..94792788e9 --- /dev/null +++ b/Backend/Remora.Discord.API/Json/Converters/Internal/IntegrationTypeConfigConverter.cs @@ -0,0 +1,94 @@ +// +// IntegrationTypeConfigConverter.cs +// +// Author: +// Jarl Gullberg +// +// Copyright (c) Jarl Gullberg +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; +using Remora.Discord.API.Abstractions.Objects; +using Remora.Rest.Json; + +namespace Remora.Discord.API.Json; + +/// +/// Converts integration type configurations. +/// +public class IntegrationTypeConfigConverter : JsonConverter> +{ + /// + public override IReadOnlyDictionary Read + ( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException(); + } + + var result = new Dictionary(); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + return result; + } + + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException(); + } + + if (!Enum.TryParse(reader.GetString(), out ApplicationIntegrationType key)) + { + throw new JsonException(); + } + + if (!reader.Read()) + { + throw new JsonException(); + } + + var value = JsonSerializer.Deserialize(ref reader, options); + + result.Add(key, value); + } + + return result; + } + + /// + public override void Write(Utf8JsonWriter writer, IReadOnlyDictionary value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + foreach (var (key, val) in value) + { + writer.WritePropertyName(((int)key).ToString()); + JsonSerializer.Serialize(writer, val, options); + } + + writer.WriteEndObject(); + } +} diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_COMMAND/APPLICATION_COMMAND.json b/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_COMMAND/APPLICATION_COMMAND.json index 116515a576..c5926ff246 100644 --- a/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_COMMAND/APPLICATION_COMMAND.json +++ b/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_COMMAND/APPLICATION_COMMAND.json @@ -21,5 +21,7 @@ "default_member_permissions": "0", "dm_permission": true, "nsfw": true, - "version": "999999999999999999" + "version": "999999999999999999", + "integration_types": [0, 1], + "contexts": [0, 1, 2] } From 2086a4219b5a316142cbe3726fba2e22e5e9b105 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Thu, 9 May 2024 17:10:15 -0400 Subject: [PATCH 10/22] fix(tests): Fix broken JSON tests --- .../Extensions/ServiceCollectionExtensions.cs | 9 ++++----- .../API/Applications/DiscordRestApplicationAPITests.cs | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs index 59760d7ef2..5ed3d434cb 100644 --- a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs +++ b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs @@ -1203,10 +1203,9 @@ private static JsonSerializerOptions AddInteractionObjectConverters(this JsonSer private static JsonSerializerOptions AddOAuth2ObjectConverters(this JsonSerializerOptions options) { options.AddDataObjectConverter() - .WithPropertyName(a => a.IsBotPublic, "bot_public") - .WithPropertyName(a => a.DoesBotRequireCodeGrant, "bot_require_code_grant") - .WithPropertyName(a => a.PrimarySKUID, "primary_sku_id") - .WithPropertyConverter(a => a.IntegrationTypesConfig, new IntegrationTypeConfigConverter()); + .WithPropertyName(a => a.IsBotPublic, "bot_public") + .WithPropertyName(a => a.DoesBotRequireCodeGrant, "bot_require_code_grant") + .WithPropertyName(a => a.PrimarySKUID, "primary_sku_id"); options.AddDataObjectConverter() .WithPropertyName(a => a.IsBotPublic, "bot_public") @@ -1222,7 +1221,7 @@ private static JsonSerializerOptions AddOAuth2ObjectConverters(this JsonSerializ options.AddDataObjectConverter(); - //options.Converters.Insert(0, new JsonNumberEnumConverter()); + options.Converters.Insert(0, new IntegrationTypeConfigConverter()); return options; } diff --git a/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs b/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs index 96fd608637..9e3194ad26 100644 --- a/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs +++ b/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs @@ -2498,8 +2498,8 @@ public async Task PerformsRequestCorrectly() var integrationTypes = new Dictionary { - { ApplicationIntegrationType.UserInstallable, new ApplicationIntegrationTypeConfig(new ApplicationOAuth2InstallParams(DiscordPermissionSet.Empty, Array.Empty())) }, { ApplicationIntegrationType.GuildInstallable, new ApplicationIntegrationTypeConfig(new ApplicationOAuth2InstallParams(DiscordPermissionSet.Empty, Array.Empty())) }, + { ApplicationIntegrationType.UserInstallable, new ApplicationIntegrationTypeConfig(new ApplicationOAuth2InstallParams(DiscordPermissionSet.Empty, Array.Empty())) }, }; var api = CreateAPI From 6539aafc6b6ddd10ba99cf4000e948b52998fbf6 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 10 May 2024 18:56:27 -0400 Subject: [PATCH 11/22] fix: Make ApplicationIntegrationType#OAuth2InstallParams `Optional` --- .../Objects/Applications/IApplicationIntegrationTypeConfig.cs | 3 ++- .../Objects/Interactions/ApplicationIntegrationTypeConfig.cs | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Applications/IApplicationIntegrationTypeConfig.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Applications/IApplicationIntegrationTypeConfig.cs index 66cca05a81..c912f179a2 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Applications/IApplicationIntegrationTypeConfig.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Applications/IApplicationIntegrationTypeConfig.cs @@ -21,6 +21,7 @@ // using JetBrains.Annotations; +using Remora.Rest.Core; namespace Remora.Discord.API.Abstractions.Objects; @@ -33,5 +34,5 @@ public interface IApplicationIntegrationTypeConfig /// /// Gets the OAuth2 install parameters for the integration type. /// - public IApplicationOAuth2InstallParams OAuth2InstallParams { get; } + public Optional OAuth2InstallParams { get; } } diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationIntegrationTypeConfig.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationIntegrationTypeConfig.cs index 4be5c8f345..0bebe70f3b 100644 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationIntegrationTypeConfig.cs +++ b/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationIntegrationTypeConfig.cs @@ -22,9 +22,11 @@ using JetBrains.Annotations; using Remora.Discord.API.Abstractions.Objects; +using Remora.Rest.Core; namespace Remora.Discord.API.Objects; /// [PublicAPI] -public record ApplicationIntegrationTypeConfig(IApplicationOAuth2InstallParams OAuth2InstallParams) : IApplicationIntegrationTypeConfig; +public record ApplicationIntegrationTypeConfig(Optional OAuth2InstallParams) + : IApplicationIntegrationTypeConfig; From cac68b42706b179ddecda03fc27e2a93f091048f Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 10 May 2024 20:39:57 -0400 Subject: [PATCH 12/22] fix: Fix tests, add enum dictionary converter --- .../Extensions/ServiceCollectionExtensions.cs | 14 ++- .../EnumKeyDictionaryConverterFactory.cs | 119 ++++++++++++++++++ .../IntegrationTypeConfigConverter.cs | 94 -------------- 3 files changed, 129 insertions(+), 98 deletions(-) create mode 100644 Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs delete mode 100644 Backend/Remora.Discord.API/Json/Converters/Internal/IntegrationTypeConfigConverter.cs diff --git a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs index 5ed3d434cb..9e1e16b5af 100644 --- a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs +++ b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs @@ -1045,7 +1045,12 @@ private static JsonSerializerOptions AddInteractionObjectConverters(this JsonSer >() .WithPropertyName(o => o.IsFocused, "focused"); - options.AddDataObjectConverter(); + options.AddDataObjectConverter() + .WithPropertyConverter + ( + i => i.AuthorizingIntegrationOwners, + new EnumKeyDictionaryConverterFactory() + ); options.AddDataObjectConverter < IInteractionMessageCallbackData, @@ -1190,7 +1195,8 @@ private static JsonSerializerOptions AddInteractionObjectConverters(this JsonSer options.AddDataObjectConverter(); - options.AddDataObjectConverter(); + options.AddDataObjectConverter() + .WithPropertyConverter(m => m.AuthorizingIntegrationOwners, new EnumKeyDictionaryConverterFactory()); return options; } @@ -1205,7 +1211,8 @@ private static JsonSerializerOptions AddOAuth2ObjectConverters(this JsonSerializ options.AddDataObjectConverter() .WithPropertyName(a => a.IsBotPublic, "bot_public") .WithPropertyName(a => a.DoesBotRequireCodeGrant, "bot_require_code_grant") - .WithPropertyName(a => a.PrimarySKUID, "primary_sku_id"); + .WithPropertyName(a => a.PrimarySKUID, "primary_sku_id") + .WithPropertyConverter(a => a.IntegrationTypesConfig, new EnumKeyDictionaryConverterFactory()); options.AddDataObjectConverter() .WithPropertyName(a => a.IsBotPublic, "bot_public") @@ -1221,7 +1228,6 @@ private static JsonSerializerOptions AddOAuth2ObjectConverters(this JsonSerializ options.AddDataObjectConverter(); - options.Converters.Insert(0, new IntegrationTypeConfigConverter()); return options; } diff --git a/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs b/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs new file mode 100644 index 0000000000..5a902f4a46 --- /dev/null +++ b/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs @@ -0,0 +1,119 @@ +// +// EnumKeyDictionaryConverterFactory.cs +// +// Author: +// Jarl Gullberg +// +// Copyright (c) Jarl Gullberg +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; +using Remora.Rest.Json; + +namespace Remora.Discord.API.Json; + +/// +/// Creates a JSON converter for dictionaries with enum keys. +/// +public class EnumKeyDictionaryConverterFactory : JsonConverterFactory +{ + /// + public override bool CanConvert(Type typeToConvert) + => typeToConvert.IsGenericType && typeof(IReadOnlyDictionary<,>).IsAssignableFrom(typeToConvert.GetGenericTypeDefinition()) + && typeToConvert.GetGenericArguments()[0].IsEnum; + + /// + public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) + => (JsonConverter?)Activator.CreateInstance + ( + typeof(EnumKeyDictionaryConverterInner<,>).MakeGenericType + ( + typeToConvert.GetGenericArguments()[0], + typeToConvert.GetGenericArguments()[1] + ), + options + ); + + private class EnumKeyDictionaryConverterInner : JsonConverter> + where TEnumKey : struct, Enum + { + private readonly JsonConverter _valueConverter; + private readonly JsonConverter _keyConverter; + + public EnumKeyDictionaryConverterInner(JsonSerializerOptions options) + { + _valueConverter = (JsonConverter)options.GetConverter(typeof(TValue)); + _keyConverter = new StringEnumConverter(asInteger: true); + } + + public override IReadOnlyDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException(); + } + + var result = new Dictionary(); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + return result; + } + + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException(); + } + + var keyString = reader.GetString() ?? throw new JsonException("Dictionaries cannot contain null keys."); + var parsedKey = Enum.TryParse(keyString, out var keyValue); + + if (!parsedKey) + { + throw new JsonException($"Could not parse key '{keyString}' as enum of type {typeof(TEnumKey).Name}."); + } + + if (!reader.Read()) + { + throw new JsonException(); + } + + var value = _valueConverter.Read(ref reader, typeof(TValue), options); + + result.Add(keyValue, value!); + } + + return result; + } + + public override void Write(Utf8JsonWriter writer, IReadOnlyDictionary value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + foreach (var (key, val) in value) + { + _keyConverter.WriteAsPropertyName(writer, key, options); + _valueConverter.Write(writer, val, options); + } + + writer.WriteEndObject(); + } + } +} diff --git a/Backend/Remora.Discord.API/Json/Converters/Internal/IntegrationTypeConfigConverter.cs b/Backend/Remora.Discord.API/Json/Converters/Internal/IntegrationTypeConfigConverter.cs deleted file mode 100644 index 94792788e9..0000000000 --- a/Backend/Remora.Discord.API/Json/Converters/Internal/IntegrationTypeConfigConverter.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -// IntegrationTypeConfigConverter.cs -// -// Author: -// Jarl Gullberg -// -// Copyright (c) Jarl Gullberg -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see . -// - -using System; -using System.Collections.Generic; -using System.Text.Json; -using System.Text.Json.Serialization; -using Remora.Discord.API.Abstractions.Objects; -using Remora.Rest.Json; - -namespace Remora.Discord.API.Json; - -/// -/// Converts integration type configurations. -/// -public class IntegrationTypeConfigConverter : JsonConverter> -{ - /// - public override IReadOnlyDictionary Read - ( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options - ) - { - if (reader.TokenType != JsonTokenType.StartObject) - { - throw new JsonException(); - } - - var result = new Dictionary(); - - while (reader.Read()) - { - if (reader.TokenType == JsonTokenType.EndObject) - { - return result; - } - - if (reader.TokenType != JsonTokenType.PropertyName) - { - throw new JsonException(); - } - - if (!Enum.TryParse(reader.GetString(), out ApplicationIntegrationType key)) - { - throw new JsonException(); - } - - if (!reader.Read()) - { - throw new JsonException(); - } - - var value = JsonSerializer.Deserialize(ref reader, options); - - result.Add(key, value); - } - - return result; - } - - /// - public override void Write(Utf8JsonWriter writer, IReadOnlyDictionary value, JsonSerializerOptions options) - { - writer.WriteStartObject(); - foreach (var (key, val) in value) - { - writer.WritePropertyName(((int)key).ToString()); - JsonSerializer.Serialize(writer, val, options); - } - - writer.WriteEndObject(); - } -} From 4e6114ff308da9f44e72aed757cee8c8981128a4 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 10 May 2024 20:55:59 -0400 Subject: [PATCH 13/22] feat(samples): Add user-app slash command sample --- .../SlashCommands/Commands/HttpCatCommands.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Samples/SlashCommands/Commands/HttpCatCommands.cs b/Samples/SlashCommands/Commands/HttpCatCommands.cs index bccf5109b3..a0d812fb46 100644 --- a/Samples/SlashCommands/Commands/HttpCatCommands.cs +++ b/Samples/SlashCommands/Commands/HttpCatCommands.cs @@ -11,8 +11,10 @@ using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API.Abstractions.Objects; +using Remora.Discord.API.Abstractions.Rest; using Remora.Discord.API.Objects; using Remora.Discord.Commands.Attributes; +using Remora.Discord.Commands.Contexts; using Remora.Discord.Commands.Feedback.Services; using Remora.Results; @@ -29,7 +31,9 @@ public class HttpCatCommands : CommandGroup /// Initializes a new instance of the class. /// /// The feedback service. - public HttpCatCommands(FeedbackService feedbackService) + /// The interactions API. + /// The context. + public HttpCatCommands(FeedbackService feedbackService, IDiscordRestInteractionAPI interactions, IInteractionContext context) { _feedbackService = feedbackService; } @@ -121,6 +125,17 @@ public Task PostChannelHttpCatAsync return PostHttpCatAsync((int)code); } + /// + /// + /// This method differs in the fact that it is installable to a user's account, rather than a guild. + /// + [Command("user-cat-dm")] + [AllowedContexts(InteractionContextType.PrivateChannel)] + [DiscordInstallContext(ApplicationIntegrationType.UserInstallable)] + [Description("Posts a cat image that matches the user, usable exclusively in DMs.")] + public Task PostUserHttpCatDMAsync([Description("The user to cattify")] IPartialUser catUser) + => PostUserHttpCatAsync(catUser); + private static ulong Map(ulong value, ulong fromSource, ulong toSource, ulong fromTarget, ulong toTarget) { return ((value - fromSource) / (toSource - fromSource) * (toTarget - fromTarget)) + fromTarget; From 4b880e81ca25463565ca76fc41c4ba6bde4a4386 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 10 May 2024 21:54:24 -0400 Subject: [PATCH 14/22] fix: Add converter for integration types config when writing manually --- .../Extensions/ServiceCollectionExtensions.cs | 3 +++ .../Internal/EnumKeyDictionaryConverterFactory.cs | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs index 9e1e16b5af..081f315a7f 100644 --- a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs +++ b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs @@ -41,6 +41,7 @@ using Remora.Discord.API.Rest; using Remora.Discord.API.VoiceGateway.Commands; using Remora.Discord.API.VoiceGateway.Events; +using Remora.Rest.Core; using Remora.Rest.Extensions; using Remora.Rest.Json; using Remora.Rest.Json.Policies; @@ -1228,6 +1229,8 @@ private static JsonSerializerOptions AddOAuth2ObjectConverters(this JsonSerializ options.AddDataObjectConverter(); + options.Converters.Insert(0, new EnumKeyDictionaryConverterFactory.EnumKeyDictionaryConverterInner(options)); + return options; } diff --git a/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs b/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs index 5a902f4a46..8410ad981b 100644 --- a/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs +++ b/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs @@ -50,18 +50,24 @@ public override bool CanConvert(Type typeToConvert) options ); - private class EnumKeyDictionaryConverterInner : JsonConverter> + /// + internal class EnumKeyDictionaryConverterInner : JsonConverter> where TEnumKey : struct, Enum { private readonly JsonConverter _valueConverter; private readonly JsonConverter _keyConverter; + /// + /// Initializes a new instance of the class. + /// + /// The serializer options. public EnumKeyDictionaryConverterInner(JsonSerializerOptions options) { _valueConverter = (JsonConverter)options.GetConverter(typeof(TValue)); _keyConverter = new StringEnumConverter(asInteger: true); } + /// public override IReadOnlyDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartObject) @@ -104,6 +110,7 @@ public override IReadOnlyDictionary Read(ref Utf8JsonReader re return result; } + /// public override void Write(Utf8JsonWriter writer, IReadOnlyDictionary value, JsonSerializerOptions options) { writer.WriteStartObject(); From 5b0a64112082b74d1cf3ac91c3f884dd0544c1df Mon Sep 17 00:00:00 2001 From: Velvet <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 10 May 2024 22:03:09 -0400 Subject: [PATCH 15/22] Update Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationIntegrationTypeConfig.cs Co-authored-by: MazeXP <26042705+MazeXP@users.noreply.github.com> --- .../Interactions/ApplicationIntegrationTypeConfig.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationIntegrationTypeConfig.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationIntegrationTypeConfig.cs index 0bebe70f3b..02e42a59ce 100644 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationIntegrationTypeConfig.cs +++ b/Backend/Remora.Discord.API/API/Objects/Interactions/ApplicationIntegrationTypeConfig.cs @@ -28,5 +28,7 @@ namespace Remora.Discord.API.Objects; /// [PublicAPI] -public record ApplicationIntegrationTypeConfig(Optional OAuth2InstallParams) - : IApplicationIntegrationTypeConfig; +public record ApplicationIntegrationTypeConfig +( + Optional OAuth2InstallParams +) : IApplicationIntegrationTypeConfig; From 4e06346ff71f53eed34007cef13707e0da86b800 Mon Sep 17 00:00:00 2001 From: Velvet <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 10 May 2024 22:05:28 -0400 Subject: [PATCH 16/22] Update Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs Co-authored-by: MazeXP <26042705+MazeXP@users.noreply.github.com> --- .../Converters/Internal/EnumKeyDictionaryConverterFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs b/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs index 8410ad981b..678c3c6ef2 100644 --- a/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs +++ b/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs @@ -31,7 +31,7 @@ namespace Remora.Discord.API.Json; /// /// Creates a JSON converter for dictionaries with enum keys. /// -public class EnumKeyDictionaryConverterFactory : JsonConverterFactory +internal class EnumKeyDictionaryConverterFactory : JsonConverterFactory { /// public override bool CanConvert(Type typeToConvert) From 42b7edf8312558d62880417bbd21ce9677e6f2ad Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 10 May 2024 22:12:03 -0400 Subject: [PATCH 17/22] refactor: Apply PR feedback --- .../API/Applications/DiscordRestApplicationAPI.cs | 2 +- .../API/Applications/DiscordRestApplicationAPITests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs index 0baf8f6cb2..78cadd9200 100644 --- a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs +++ b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs @@ -726,7 +726,7 @@ public async Task> EditCurrentApplicationAsync json.Write("cover_image", base64EncodedCover, this.JsonOptions); json.Write("interactions_endpoint_url", interactionsEndpointUrl, this.JsonOptions); json.Write("tags", tags, this.JsonOptions); - json.Write("integration_types_config", integrationTypesConfig, this.JsonOptions); + json.Write("integration_types", integrationTypesConfig, this.JsonOptions); } ); diff --git a/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs b/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs index 9e3194ad26..ffcc5b0857 100644 --- a/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs +++ b/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs @@ -2543,7 +2543,7 @@ public async Task PerformsRequestCorrectly() ) .WithProperty ( - "integration_types_config", + "integration_types", p => p.IsObject ( a => a.WithProperty("0", p => p.IsObject()) From 49f09d529d975ccd69d99f9998bc6d4e82f187bf Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 10 May 2024 22:41:43 -0400 Subject: [PATCH 18/22] Revert "refactor: Apply PR feedback" This reverts commit 42b7edf8312558d62880417bbd21ce9677e6f2ad. --- .../API/Applications/DiscordRestApplicationAPI.cs | 2 +- .../API/Applications/DiscordRestApplicationAPITests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs index 78cadd9200..0baf8f6cb2 100644 --- a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs +++ b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs @@ -726,7 +726,7 @@ public async Task> EditCurrentApplicationAsync json.Write("cover_image", base64EncodedCover, this.JsonOptions); json.Write("interactions_endpoint_url", interactionsEndpointUrl, this.JsonOptions); json.Write("tags", tags, this.JsonOptions); - json.Write("integration_types", integrationTypesConfig, this.JsonOptions); + json.Write("integration_types_config", integrationTypesConfig, this.JsonOptions); } ); diff --git a/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs b/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs index ffcc5b0857..9e3194ad26 100644 --- a/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs +++ b/Tests/Remora.Discord.Rest.Tests/API/Applications/DiscordRestApplicationAPITests.cs @@ -2543,7 +2543,7 @@ public async Task PerformsRequestCorrectly() ) .WithProperty ( - "integration_types", + "integration_types_config", p => p.IsObject ( a => a.WithProperty("0", p => p.IsObject()) From bf34c185b6770b35085ab5ede91004730f5163a0 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Sat, 11 May 2024 07:26:51 -0400 Subject: [PATCH 19/22] refactor!: Remove name from interaction metadata BREAKING-CHANGE: Removes the name field from interaction metadata; Discord says this field is currently unstable. --- .../API/Objects/Interactions/IMessageInteractionMetadata.cs | 5 ----- .../API/Objects/Interactions/MessageInteractionMetadata.cs | 1 - .../MESSAGE_INTERACTION_METADATA.followup.json | 1 - .../MESSAGE_INTERACTION_METADATA.modal.json | 3 +-- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs index 701c6d3ca6..d81ee787c7 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Interactions/IMessageInteractionMetadata.cs @@ -42,11 +42,6 @@ public interface IMessageInteractionMetadata /// IUser User { get; } - /// - /// Gets the name of the command. - /// - Optional Name { get; } - /// /// Gets the type of the interaction. /// diff --git a/Backend/Remora.Discord.API/API/Objects/Interactions/MessageInteractionMetadata.cs b/Backend/Remora.Discord.API/API/Objects/Interactions/MessageInteractionMetadata.cs index 11f7a221ae..cd8d4f1d9a 100644 --- a/Backend/Remora.Discord.API/API/Objects/Interactions/MessageInteractionMetadata.cs +++ b/Backend/Remora.Discord.API/API/Objects/Interactions/MessageInteractionMetadata.cs @@ -33,7 +33,6 @@ public record MessageInteractionMetadata ( Snowflake ID, IUser User, - Optional Name, Optional OriginalResponseMessageID, Optional InteractedMessageID, InteractionType Type, diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.followup.json b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.followup.json index 2992d62bed..c5152c5db5 100644 --- a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.followup.json +++ b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.followup.json @@ -11,6 +11,5 @@ "0": "999999999999999999", "1": "999999999999999999" }, - "name": "ooga", "original_response_message_id": "999999999999999999" } \ No newline at end of file diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.modal.json b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.modal.json index d6c9570e5b..7b4c3dc46d 100644 --- a/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.modal.json +++ b/Tests/Remora.Discord.Tests/Samples/Objects/MESSAGE_INTERACTION_METADATA/MESSAGE_INTERACTION_METADATA.modal.json @@ -23,7 +23,6 @@ "authorizing_integration_owners": { "0": "999999999999999999", "1": "999999999999999999" - }, - "name": "ooga" + } } } \ No newline at end of file From 6f1bb43b2eb7b37eb551c12b12b483e1379f5734 Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Sat, 11 May 2024 07:34:48 -0400 Subject: [PATCH 20/22] chore: Address PR comments again --- .../Extensions/ServiceCollectionExtensions.cs | 8 ++++---- ...Factory.cs => EnumIntKeyDictionaryConverterFactory.cs} | 4 ++-- Samples/SlashCommands/Commands/HttpCatCommands.cs | 6 +----- 3 files changed, 7 insertions(+), 11 deletions(-) rename Backend/Remora.Discord.API/Json/Converters/Internal/{EnumKeyDictionaryConverterFactory.cs => EnumIntKeyDictionaryConverterFactory.cs} (97%) diff --git a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs index 081f315a7f..111183bb8f 100644 --- a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs +++ b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs @@ -1050,7 +1050,7 @@ private static JsonSerializerOptions AddInteractionObjectConverters(this JsonSer .WithPropertyConverter ( i => i.AuthorizingIntegrationOwners, - new EnumKeyDictionaryConverterFactory() + new EnumIntKeyDictionaryConverterFactory() ); options.AddDataObjectConverter < @@ -1197,7 +1197,7 @@ private static JsonSerializerOptions AddInteractionObjectConverters(this JsonSer options.AddDataObjectConverter(); options.AddDataObjectConverter() - .WithPropertyConverter(m => m.AuthorizingIntegrationOwners, new EnumKeyDictionaryConverterFactory()); + .WithPropertyConverter(m => m.AuthorizingIntegrationOwners, new EnumIntKeyDictionaryConverterFactory()); return options; } @@ -1213,7 +1213,7 @@ private static JsonSerializerOptions AddOAuth2ObjectConverters(this JsonSerializ .WithPropertyName(a => a.IsBotPublic, "bot_public") .WithPropertyName(a => a.DoesBotRequireCodeGrant, "bot_require_code_grant") .WithPropertyName(a => a.PrimarySKUID, "primary_sku_id") - .WithPropertyConverter(a => a.IntegrationTypesConfig, new EnumKeyDictionaryConverterFactory()); + .WithPropertyConverter(a => a.IntegrationTypesConfig, new EnumIntKeyDictionaryConverterFactory()); options.AddDataObjectConverter() .WithPropertyName(a => a.IsBotPublic, "bot_public") @@ -1229,7 +1229,7 @@ private static JsonSerializerOptions AddOAuth2ObjectConverters(this JsonSerializ options.AddDataObjectConverter(); - options.Converters.Insert(0, new EnumKeyDictionaryConverterFactory.EnumKeyDictionaryConverterInner(options)); + options.Converters.Insert(0, new EnumIntKeyDictionaryConverterFactory.EnumKeyDictionaryConverterInner(options)); return options; } diff --git a/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs b/Backend/Remora.Discord.API/Json/Converters/Internal/EnumIntKeyDictionaryConverterFactory.cs similarity index 97% rename from Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs rename to Backend/Remora.Discord.API/Json/Converters/Internal/EnumIntKeyDictionaryConverterFactory.cs index 678c3c6ef2..e4fa18c155 100644 --- a/Backend/Remora.Discord.API/Json/Converters/Internal/EnumKeyDictionaryConverterFactory.cs +++ b/Backend/Remora.Discord.API/Json/Converters/Internal/EnumIntKeyDictionaryConverterFactory.cs @@ -1,5 +1,5 @@ // -// EnumKeyDictionaryConverterFactory.cs +// EnumIntKeyDictionaryConverterFactory.cs // // Author: // Jarl Gullberg @@ -31,7 +31,7 @@ namespace Remora.Discord.API.Json; /// /// Creates a JSON converter for dictionaries with enum keys. /// -internal class EnumKeyDictionaryConverterFactory : JsonConverterFactory +internal class EnumIntKeyDictionaryConverterFactory : JsonConverterFactory { /// public override bool CanConvert(Type typeToConvert) diff --git a/Samples/SlashCommands/Commands/HttpCatCommands.cs b/Samples/SlashCommands/Commands/HttpCatCommands.cs index a0d812fb46..3bc61a5097 100644 --- a/Samples/SlashCommands/Commands/HttpCatCommands.cs +++ b/Samples/SlashCommands/Commands/HttpCatCommands.cs @@ -11,10 +11,8 @@ using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API.Abstractions.Objects; -using Remora.Discord.API.Abstractions.Rest; using Remora.Discord.API.Objects; using Remora.Discord.Commands.Attributes; -using Remora.Discord.Commands.Contexts; using Remora.Discord.Commands.Feedback.Services; using Remora.Results; @@ -31,9 +29,7 @@ public class HttpCatCommands : CommandGroup /// Initializes a new instance of the class. /// /// The feedback service. - /// The interactions API. - /// The context. - public HttpCatCommands(FeedbackService feedbackService, IDiscordRestInteractionAPI interactions, IInteractionContext context) + public HttpCatCommands(FeedbackService feedbackService) { _feedbackService = feedbackService; } From e1ae7617c587fcce41d350c43c00b194797743df Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Sat, 11 May 2024 07:39:36 -0400 Subject: [PATCH 21/22] fix: Apply correct naming to integration_types --- .../API/Rest/IDiscordRestApplicationAPI.cs | 16 ++++++++-------- .../Applications/DiscordRestApplicationAPI.cs | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs index e132994645..627a0b5043 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestApplicationAPI.cs @@ -72,7 +72,7 @@ Task>> GetGlobalApplicationCommandsAsy /// The permissions required to execute the command. /// Whether this command is executable in DMs. /// Whether the command is age-restricted. - /// The installation contexts the command can be installed to. + /// The installation contexts the command can be installed to. /// The contexts in which the command is allowed to be run in. /// The cancellation token for this operation. /// A creation result which may or may not have succeeded. @@ -88,7 +88,7 @@ Task> CreateGlobalApplicationCommandAsync Optional defaultMemberPermissions = default, Optional dmPermission = default, Optional isNsfw = default, - Optional> allowedIntegrationTypes = default, + Optional> integrationTypes = default, Optional> allowedContextTypes = default, CancellationToken ct = default ); @@ -134,7 +134,7 @@ Task> GetGlobalApplicationCommandAsync /// The permissions required to execute the command. /// Whether this command is executable in DMs. /// Whether this command is age-restricted. - /// The installation contexts the command can be installed to. + /// The installation contexts the command can be installed to. /// The contexts in which the command is allowed to be run in. /// The cancellation token for this operation. /// A creation result which may or may not have succeeded. @@ -150,7 +150,7 @@ Task> EditGlobalApplicationCommandAsync Optional defaultMemberPermissions = default, Optional dmPermission = default, Optional isNsfw = default, - Optional> allowedIntegrationTypes = default, + Optional> integrationTypes = default, Optional> allowedContextTypes = default, CancellationToken ct = default ); @@ -205,7 +205,7 @@ Task>> GetGuildApplicationCommandsAsyn /// The localized descriptions of the command. /// The permissions required to execute the command. /// Whether the command is age-restricted. - /// The installation contexts the command can be installed to. + /// The installation contexts the command can be installed to. /// The contexts in which the command is allowed to be run in. /// The cancellation token for this operation. /// A creation result which may or may not have succeeded. @@ -221,7 +221,7 @@ Task> CreateGuildApplicationCommandAsync Optional?> descriptionLocalizations = default, Optional defaultMemberPermissions = default, Optional isNsfw = default, - Optional> allowedIntegrationTypes = default, + Optional> integrationTypes = default, Optional> allowedContextTypes = default, CancellationToken ct = default ); @@ -271,7 +271,7 @@ Task> GetGuildApplicationCommandAsync /// The localized descriptions of the command. /// The permissions required to execute the command. /// Whether this command is age-restricted. - /// The installation contexts the command can be installed to. + /// The installation contexts the command can be installed to. /// The contexts in which the command is allowed to be run in. /// The cancellation token for this operation. /// A creation result which may or may not have succeeded. @@ -290,7 +290,7 @@ Task> EditGuildApplicationCommandAsync Optional?> descriptionLocalizations = default, Optional defaultMemberPermissions = default, Optional isNsfw = default, - Optional> allowedIntegrationTypes = default, + Optional> integrationTypes = default, Optional> allowedContextTypes = default, CancellationToken ct = default ); diff --git a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs index 0baf8f6cb2..1fb7bf7550 100644 --- a/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs +++ b/Backend/Remora.Discord.Rest/API/Applications/DiscordRestApplicationAPI.cs @@ -103,7 +103,7 @@ public virtual async Task> CreateGlobalApplicationCo Optional defaultMemberPermissions = default, Optional dmPermission = default, Optional isNsfw = default, - Optional> allowedIntegrationTypes = default, + Optional> integrationTypes = default, Optional> allowedContextTypes = default, CancellationToken ct = default ) @@ -154,7 +154,7 @@ public virtual async Task> CreateGlobalApplicationCo json.Write("dm_permission", dmPermission, this.JsonOptions); json.Write("nsfw", isNsfw, this.JsonOptions); json.Write("contexts", allowedContextTypes, this.JsonOptions); - json.Write("integration_types", allowedIntegrationTypes, this.JsonOptions); + json.Write("integration_types", integrationTypes, this.JsonOptions); } ) .WithRateLimitContext(this.RateLimitCache), @@ -234,7 +234,7 @@ public virtual async Task> EditGlobalApplicationComm Optional defaultMemberPermissions = default, Optional dmPermission = default, Optional isNsfw = default, - Optional> integrationTypesConfig = default, + Optional> integrationTypes = default, Optional> allowedContextTypes = default, CancellationToken ct = default ) @@ -274,7 +274,7 @@ public virtual async Task> EditGlobalApplicationComm json.Write("dm_permission", dmPermission, this.JsonOptions); json.Write("nsfw", isNsfw, this.JsonOptions); json.Write("contexts", allowedContextTypes, this.JsonOptions); - json.Write("integration_types_config", integrationTypesConfig, this.JsonOptions); + json.Write("integration_types", integrationTypes, this.JsonOptions); } ) .WithRateLimitContext(this.RateLimitCache), @@ -387,7 +387,7 @@ public virtual async Task> CreateGuildApplicationCom Optional?> descriptionLocalizations = default, Optional defaultMemberPermissions = default, Optional isNsfw = default, - Optional> allowedIntegrationTypes = default, + Optional> integrationTypes = default, Optional> allowedContextTypes = default, CancellationToken ct = default ) @@ -437,7 +437,7 @@ public virtual async Task> CreateGuildApplicationCom json.Write("default_member_permissions", defaultMemberPermissions, this.JsonOptions); json.Write("nsfw", isNsfw, this.JsonOptions); json.Write("contexts", allowedContextTypes, this.JsonOptions); - json.Write("integration_types", allowedIntegrationTypes, this.JsonOptions); + json.Write("integration_types", integrationTypes, this.JsonOptions); } ) .WithRateLimitContext(this.RateLimitCache), @@ -475,7 +475,7 @@ public virtual async Task> EditGuildApplicationComma Optional?> descriptionLocalizations = default, Optional defaultMemberPermissions = default, Optional isNsfw = default, - Optional> allowedIntegrationTypes = default, + Optional> integrationTypes = default, Optional> allowedContextTypes = default, CancellationToken ct = default ) @@ -513,7 +513,7 @@ public virtual async Task> EditGuildApplicationComma json.Write("default_member_permissions", defaultMemberPermissions, this.JsonOptions); json.Write("nsfw", isNsfw, this.JsonOptions); json.Write("contexts", allowedContextTypes, this.JsonOptions); - json.Write("integration_types", allowedIntegrationTypes, this.JsonOptions); + json.Write("integration_types", integrationTypes, this.JsonOptions); } ) .WithRateLimitContext(this.RateLimitCache), From 4a47b2856a0de0e7eaea0004488ca19053ed46cc Mon Sep 17 00:00:00 2001 From: Velvet Toroyashi <42438262+VelvetToroyashi@users.noreply.github.com> Date: Fri, 17 May 2024 14:44:58 -0400 Subject: [PATCH 22/22] chore: Remove unused imports --- .../Extensions/ServiceCollectionExtensions.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs index 3100a771b5..6f8bf51876 100644 --- a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs +++ b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs @@ -21,7 +21,6 @@ // using System.Text.Json; -using System.Text.Json.Serialization; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -41,7 +40,6 @@ using Remora.Discord.API.Rest; using Remora.Discord.API.VoiceGateway.Commands; using Remora.Discord.API.VoiceGateway.Events; -using Remora.Rest.Core; using Remora.Rest.Extensions; using Remora.Rest.Json; using Remora.Rest.Json.Policies;