diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/IApplicationAuthorizedWebhookEvent.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/IApplicationAuthorizedWebhookEvent.cs new file mode 100644 index 0000000000..93ed7c0375 --- /dev/null +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/IApplicationAuthorizedWebhookEvent.cs @@ -0,0 +1,54 @@ +// +// IApplicationAuthorizedWebhookEvent.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.Rest.Core; + +namespace Remora.Discord.API.Abstractions.Objects; + +/// +/// Represents a webhook event for when an application is authorized. +/// +[PublicAPI] +public interface IApplicationAuthorizedWebhookEvent +{ + /// + /// Gets the user that authorized the application. + /// + IUser User { get; } + + /// + /// Gets the scopes that the application was authorized for. + /// + IReadOnlyList Scopes { get; } + + /// + /// Gets the guild that the application was authorized for, if is . + /// + Optional Guild { get; } + + /// + /// Gets the integration type of the application. + /// + Optional IntegrationType { get; } +} diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/IWebhookEvent.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/IWebhookEvent.cs new file mode 100644 index 0000000000..f4ba1fed9c --- /dev/null +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/IWebhookEvent.cs @@ -0,0 +1,49 @@ +// +// IWebhookEvent.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 JetBrains.Annotations; +using OneOf; + +namespace Remora.Discord.API.Abstractions.Objects; + +/// +/// Represents a webhook event. +/// +[PublicAPI] +public interface IWebhookEvent +{ + /// + /// Gets the type of the event. + /// + WebhookEventType Type { get; } + + /// + /// Gets the timestamp of the event. + /// + DateTimeOffset Timestamp { get; } + + /// + /// Gets the data of the event. + /// + OneOf Data { get; } +} diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/IWebhookEventPayload.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/IWebhookEventPayload.cs new file mode 100644 index 0000000000..d090e6a065 --- /dev/null +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/IWebhookEventPayload.cs @@ -0,0 +1,48 @@ +// +// IWebhookEventPayload.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 a payload for a webhook event. +/// +[PublicAPI] +public interface IWebhookEventPayload +{ + /// + /// Gets the version of this payload. Currently, always 1. + /// + int Version { get; } + + /// + /// Gets the ID of the application. + /// + Snowflake ApplicationID { get; } + + /// + /// Gets the type of the payload. + /// + WebhookEventPayloadType Type { get; } +} diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/WebhookEventPayloadType.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/WebhookEventPayloadType.cs new file mode 100644 index 0000000000..2f42a2ba01 --- /dev/null +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/WebhookEventPayloadType.cs @@ -0,0 +1,39 @@ +// +// WebhookEventPayloadType.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 . +// + +namespace Remora.Discord.API.Abstractions.Objects; + +/// +/// Represents the type of webhook event payload. +/// +public enum WebhookEventPayloadType +{ + /// + /// The payload is a ping. + /// + Ping, + + /// + /// The payload is an event with data. + /// + Event +} diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/WebhookEventType.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/WebhookEventType.cs new file mode 100644 index 0000000000..095d7a97aa --- /dev/null +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/WebhookEvents/WebhookEventType.cs @@ -0,0 +1,44 @@ +// +// WebhookEventType.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 . +// + +namespace Remora.Discord.API.Abstractions.Objects; + +/// +/// Represents the type of webhook event. +/// +public enum WebhookEventType +{ + /// + /// The application was authorized to a user or guild. + /// + ApplicationAuthorized, + + /// + /// An entitlement was created. + /// + EntitlementCreate, + + /// + /// User was added to a Quest (currently unavailable). + /// + QuestUserEnrollment, +} diff --git a/Backend/Remora.Discord.API.Abstractions/Remora.Discord.API.Abstractions.csproj.DotSettings b/Backend/Remora.Discord.API.Abstractions/Remora.Discord.API.Abstractions.csproj.DotSettings index 5a6720068b..49b6e72465 100644 --- a/Backend/Remora.Discord.API.Abstractions/Remora.Discord.API.Abstractions.csproj.DotSettings +++ b/Backend/Remora.Discord.API.Abstractions/Remora.Discord.API.Abstractions.csproj.DotSettings @@ -56,6 +56,7 @@ True True True + True True False True \ No newline at end of file diff --git a/Backend/Remora.Discord.API/API/Objects/WebhookEvents/ApplicationAuthorizedWebhookEvent.cs b/Backend/Remora.Discord.API/API/Objects/WebhookEvents/ApplicationAuthorizedWebhookEvent.cs new file mode 100644 index 0000000000..2296bf5b0c --- /dev/null +++ b/Backend/Remora.Discord.API/API/Objects/WebhookEvents/ApplicationAuthorizedWebhookEvent.cs @@ -0,0 +1,38 @@ +// +// ApplicationAuthorizedWebhookEvent.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 ApplicationAuthorizedWebhookEvent +( + IUser User, + IReadOnlyList Scopes, + Optional Guild = default, + Optional IntegrationType = default +) : IApplicationAuthorizedWebhookEvent; diff --git a/Backend/Remora.Discord.API/API/Objects/WebhookEvents/WebhookEvent.cs b/Backend/Remora.Discord.API/API/Objects/WebhookEvents/WebhookEvent.cs new file mode 100644 index 0000000000..f6cbc7c3f6 --- /dev/null +++ b/Backend/Remora.Discord.API/API/Objects/WebhookEvents/WebhookEvent.cs @@ -0,0 +1,35 @@ +// +// WebhookEvent.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 OneOf; +using Remora.Discord.API.Abstractions.Objects; + +namespace Remora.Discord.API.Objects; + +/// +public record WebhookEvent +( + WebhookEventType Type, + DateTimeOffset Timestamp, + OneOf Data +) : IWebhookEvent; diff --git a/Backend/Remora.Discord.API/API/Objects/WebhookEvents/WebhookEventPayload.cs b/Backend/Remora.Discord.API/API/Objects/WebhookEvents/WebhookEventPayload.cs new file mode 100644 index 0000000000..bcc774203f --- /dev/null +++ b/Backend/Remora.Discord.API/API/Objects/WebhookEvents/WebhookEventPayload.cs @@ -0,0 +1,36 @@ +// +// WebhookEventPayload.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.Discord.API.Abstractions.Objects; +using Remora.Rest.Core; + +namespace Remora.Discord.API.Objects; + +/// +[PublicAPI] +public record WebhookEventPayload +( + int Version, + Snowflake ApplicationID, + WebhookEventPayloadType Type +) : IWebhookEventPayload; diff --git a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs index 1ebaa370fc..0ee7df59ad 100644 --- a/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs +++ b/Backend/Remora.Discord.API/Extensions/ServiceCollectionExtensions.cs @@ -116,7 +116,8 @@ public static IServiceCollection ConfigureDiscordJsonConverters .AddStickerObjectConverters() .AddApplicationRoleConnectionObjectConverters() .AddMonetizationConverters() - .AddPollObjectConverters(); + .AddPollObjectConverters() + .AddWebhookEventObjectConverters(); options.AddDataObjectConverter(); options.AddConverter(); @@ -1352,4 +1353,15 @@ this JsonSerializerOptions options return options; } + + private static JsonSerializerOptions AddWebhookEventObjectConverters(this JsonSerializerOptions options) + { + options.AddDataObjectConverter() + .WithPropertyConverter(we => we.Type, new StringEnumConverter(new SnakeCaseNamingPolicy())); + + options.AddDataObjectConverter(); + options.AddDataObjectConverter(); + + return options; + } } diff --git a/Backend/Remora.Discord.API/Remora.Discord.API.csproj.DotSettings b/Backend/Remora.Discord.API/Remora.Discord.API.csproj.DotSettings index 6002fcea0f..1f146341bb 100644 --- a/Backend/Remora.Discord.API/Remora.Discord.API.csproj.DotSettings +++ b/Backend/Remora.Discord.API/Remora.Discord.API.csproj.DotSettings @@ -50,7 +50,9 @@ True True True + True True + True True True True \ No newline at end of file diff --git a/Tests/Remora.Discord.API.Tests/API/Objects/WebhookEventTests/ApplicationAuthorizedWebhookEventTests.cs b/Tests/Remora.Discord.API.Tests/API/Objects/WebhookEventTests/ApplicationAuthorizedWebhookEventTests.cs new file mode 100644 index 0000000000..6f2a320640 --- /dev/null +++ b/Tests/Remora.Discord.API.Tests/API/Objects/WebhookEventTests/ApplicationAuthorizedWebhookEventTests.cs @@ -0,0 +1,39 @@ +// +// ApplicationAuthorizedWebhookEventTests.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.WebhookEventTests; + +/// +public class ApplicationAuthorizedWebhookEventTests : ObjectTestBase +{ + /// + /// Initializes a new instance of the class. + /// + /// The test fixture. + public ApplicationAuthorizedWebhookEventTests(JsonBackedTypeTestFixture fixture) + : base(fixture) + { + } +} diff --git a/Tests/Remora.Discord.API.Tests/API/Objects/WebhookEventTests/WebhookEventPayloadTests.cs b/Tests/Remora.Discord.API.Tests/API/Objects/WebhookEventTests/WebhookEventPayloadTests.cs new file mode 100644 index 0000000000..17684258e5 --- /dev/null +++ b/Tests/Remora.Discord.API.Tests/API/Objects/WebhookEventTests/WebhookEventPayloadTests.cs @@ -0,0 +1,39 @@ +// +// WebhookEventPayloadTests.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.WebhookEventTests; + +/// +public class WebhookEventPayloadTests : ObjectTestBase +{ + /// + /// Initializes a new instance of the class. + /// + /// The test fixture. + public WebhookEventPayloadTests(JsonBackedTypeTestFixture fixture) + : base(fixture) + { + } +} diff --git a/Tests/Remora.Discord.API.Tests/API/Objects/WebhookEventTests/WebhookEventTests.cs b/Tests/Remora.Discord.API.Tests/API/Objects/WebhookEventTests/WebhookEventTests.cs new file mode 100644 index 0000000000..6060bff4ba --- /dev/null +++ b/Tests/Remora.Discord.API.Tests/API/Objects/WebhookEventTests/WebhookEventTests.cs @@ -0,0 +1,39 @@ +// +// WebhookEventTests.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.WebhookEventTests; + +/// +public class WebhookEventTests : ObjectTestBase +{ + /// + /// Initializes a new instance of the class. + /// + /// The test fixture. + public WebhookEventTests(JsonBackedTypeTestFixture fixture) + : base(fixture) + { + } +} diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_AUTHORIZED_WEBHOOK_EVENT/APPLICATION_AUTHORIZED_WEBHOOK_EVENT.json b/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_AUTHORIZED_WEBHOOK_EVENT/APPLICATION_AUTHORIZED_WEBHOOK_EVENT.json new file mode 100644 index 0000000000..f93f458eee --- /dev/null +++ b/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_AUTHORIZED_WEBHOOK_EVENT/APPLICATION_AUTHORIZED_WEBHOOK_EVENT.json @@ -0,0 +1,10 @@ +{ + "user": { + "username": "none", + "discriminator": "9999", + "id": "999999999999999999", + "avatar": "68b329da9893e34099c7d8ad5cb9c940" + }, + "scopes": ["application.commands"], + "integration_type": 1 +} diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_AUTHORIZED_WEBHOOK_EVENT/APPLICATION_AUTHORIZED_WEBHOOK_EVENT.optionals.json b/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_AUTHORIZED_WEBHOOK_EVENT/APPLICATION_AUTHORIZED_WEBHOOK_EVENT.optionals.json new file mode 100644 index 0000000000..65b494ecb1 --- /dev/null +++ b/Tests/Remora.Discord.Tests/Samples/Objects/APPLICATION_AUTHORIZED_WEBHOOK_EVENT/APPLICATION_AUTHORIZED_WEBHOOK_EVENT.optionals.json @@ -0,0 +1,9 @@ +{ + "user": { + "username": "none", + "discriminator": "9999", + "id": "999999999999999999", + "avatar": "68b329da9893e34099c7d8ad5cb9c940" + }, + "scopes": ["application.commands"] +} diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/WEBHOOK_EVENT/WEBHOOK_EVENT.json b/Tests/Remora.Discord.Tests/Samples/Objects/WEBHOOK_EVENT/WEBHOOK_EVENT.json new file mode 100644 index 0000000000..f08d2394ca --- /dev/null +++ b/Tests/Remora.Discord.Tests/Samples/Objects/WEBHOOK_EVENT/WEBHOOK_EVENT.json @@ -0,0 +1,14 @@ +{ + "type": "APPLICATION_AUTHORIZED", + "timestamp": "1970-01-01T00:00:00.000000+00:00", + "data": { + "user": { + "username": "none", + "discriminator": "9999", + "id": "999999999999999999", + "avatar": "68b329da9893e34099c7d8ad5cb9c940" + }, + "scopes": ["application.commands"], + "integration_type": 1 + } +} diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/WEBHOOK_EVENT_PAYLOAD/WEBHOOK_EVENT_PAYLOAD.json b/Tests/Remora.Discord.Tests/Samples/Objects/WEBHOOK_EVENT_PAYLOAD/WEBHOOK_EVENT_PAYLOAD.json new file mode 100644 index 0000000000..b468fc5ca6 --- /dev/null +++ b/Tests/Remora.Discord.Tests/Samples/Objects/WEBHOOK_EVENT_PAYLOAD/WEBHOOK_EVENT_PAYLOAD.json @@ -0,0 +1,5 @@ +{ + "version": 1, + "type": 1, + "application_id": "999999999999999999" +}