Skip to content

Commit

Permalink
Merge pull request #345 from VelvetToroyashi/velvet/feat/webhook-events
Browse files Browse the repository at this point in the history
Add support for incoming webhook commands
  • Loading branch information
Nihlus authored Nov 3, 2024
2 parents eda67ed + 80637f7 commit 5e7bfc5
Show file tree
Hide file tree
Showing 18 changed files with 514 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// IApplicationAuthorizedWebhookEvent.cs
//
// Author:
// Jarl Gullberg <[email protected]>
//
// 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 <http://www.gnu.org/licenses/>.
//

using System.Collections.Generic;
using JetBrains.Annotations;
using Remora.Rest.Core;

namespace Remora.Discord.API.Abstractions.Objects;

/// <summary>
/// Represents a webhook event for when an application is authorized.
/// </summary>
[PublicAPI]
public interface IApplicationAuthorizedWebhookEvent
{
/// <summary>
/// Gets the user that authorized the application.
/// </summary>
IUser User { get; }

/// <summary>
/// Gets the scopes that the application was authorized for.
/// </summary>
IReadOnlyList<string> Scopes { get; }

/// <summary>
/// Gets the guild that the application was authorized for, if <see cref="IntegrationType"/> is <see cref="ApplicationIntegrationType.GuildInstallable"/>.
/// </summary>
Optional<IPartialGuild> Guild { get; }

/// <summary>
/// Gets the integration type of the application.
/// </summary>
Optional<ApplicationIntegrationType> IntegrationType { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// IWebhookEvent.cs
//
// Author:
// Jarl Gullberg <[email protected]>
//
// 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 <http://www.gnu.org/licenses/>.
//

using System;
using JetBrains.Annotations;
using OneOf;

namespace Remora.Discord.API.Abstractions.Objects;

/// <summary>
/// Represents a webhook event.
/// </summary>
[PublicAPI]
public interface IWebhookEvent
{
/// <summary>
/// Gets the type of the event.
/// </summary>
WebhookEventType Type { get; }

/// <summary>
/// Gets the timestamp of the event.
/// </summary>
DateTimeOffset Timestamp { get; }

/// <summary>
/// Gets the data of the event.
/// </summary>
OneOf<IApplicationAuthorizedWebhookEvent, IEntitlement> Data { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// IWebhookEventPayload.cs
//
// Author:
// Jarl Gullberg <[email protected]>
//
// 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 <http://www.gnu.org/licenses/>.
//

using JetBrains.Annotations;
using Remora.Rest.Core;

namespace Remora.Discord.API.Abstractions.Objects;

/// <summary>
/// Represents a payload for a webhook event.
/// </summary>
[PublicAPI]
public interface IWebhookEventPayload
{
/// <summary>
/// Gets the version of this payload. Currently, always 1.
/// </summary>
int Version { get; }

/// <summary>
/// Gets the ID of the application.
/// </summary>
Snowflake ApplicationID { get; }

/// <summary>
/// Gets the type of the payload.
/// </summary>
WebhookEventPayloadType Type { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// WebhookEventPayloadType.cs
//
// Author:
// Jarl Gullberg <[email protected]>
//
// 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 <http://www.gnu.org/licenses/>.
//

namespace Remora.Discord.API.Abstractions.Objects;

/// <summary>
/// Represents the type of webhook event payload.
/// </summary>
public enum WebhookEventPayloadType
{
/// <summary>
/// The payload is a ping.
/// </summary>
Ping,

/// <summary>
/// The payload is an event with data.
/// </summary>
Event
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// WebhookEventType.cs
//
// Author:
// Jarl Gullberg <[email protected]>
//
// 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 <http://www.gnu.org/licenses/>.
//

namespace Remora.Discord.API.Abstractions.Objects;

/// <summary>
/// Represents the type of webhook event.
/// </summary>
public enum WebhookEventType
{
/// <summary>
/// The application was authorized to a user or guild.
/// </summary>
ApplicationAuthorized,

/// <summary>
/// An entitlement was created.
/// </summary>
EntitlementCreate,

/// <summary>
/// User was added to a Quest (currently unavailable).
/// </summary>
QuestUserEnrollment,
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Ctemplates/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Cusers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Cvoice/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Cwebhookevents/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Cwebhooks/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Crest/@EntryIndexedValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Crest_005Cobjects/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// ApplicationAuthorizedWebhookEvent.cs
//
// Author:
// Jarl Gullberg <[email protected]>
//
// 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 <http://www.gnu.org/licenses/>.
//

using System.Collections.Generic;
using JetBrains.Annotations;
using Remora.Discord.API.Abstractions.Objects;
using Remora.Rest.Core;

namespace Remora.Discord.API.Objects;

/// <inheritdoc cref="IApplicationAuthorizedWebhookEvent"/>
[PublicAPI]
public record ApplicationAuthorizedWebhookEvent
(
IUser User,
IReadOnlyList<string> Scopes,
Optional<IPartialGuild> Guild = default,
Optional<ApplicationIntegrationType> IntegrationType = default
) : IApplicationAuthorizedWebhookEvent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// WebhookEvent.cs
//
// Author:
// Jarl Gullberg <[email protected]>
//
// 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 <http://www.gnu.org/licenses/>.
//

using System;
using OneOf;
using Remora.Discord.API.Abstractions.Objects;

namespace Remora.Discord.API.Objects;

/// <inheritdoc cref="IWebhookEvent"/>
public record WebhookEvent
(
WebhookEventType Type,
DateTimeOffset Timestamp,
OneOf<IApplicationAuthorizedWebhookEvent, IEntitlement> Data
) : IWebhookEvent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// WebhookEventPayload.cs
//
// Author:
// Jarl Gullberg <[email protected]>
//
// 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 <http://www.gnu.org/licenses/>.
//

using JetBrains.Annotations;
using Remora.Discord.API.Abstractions.Objects;
using Remora.Rest.Core;

namespace Remora.Discord.API.Objects;

/// <inheritdoc cref="IWebhookEventPayload"/>
[PublicAPI]
public record WebhookEventPayload
(
int Version,
Snowflake ApplicationID,
WebhookEventPayloadType Type
) : IWebhookEventPayload;
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ public static IServiceCollection ConfigureDiscordJsonConverters
.AddStickerObjectConverters()
.AddApplicationRoleConnectionObjectConverters()
.AddMonetizationConverters()
.AddPollObjectConverters();
.AddPollObjectConverters()
.AddWebhookEventObjectConverters();
options.AddDataObjectConverter<IUnknownEvent, UnknownEvent>();
options.AddConverter<PropertyErrorDetailsConverter>();
Expand Down Expand Up @@ -1352,4 +1353,15 @@ this JsonSerializerOptions options

return options;
}

private static JsonSerializerOptions AddWebhookEventObjectConverters(this JsonSerializerOptions options)
{
options.AddDataObjectConverter<IWebhookEvent, WebhookEvent>()
.WithPropertyConverter(we => we.Type, new StringEnumConverter<WebhookEventType>(new SnakeCaseNamingPolicy()));

options.AddDataObjectConverter<IApplicationAuthorizedWebhookEvent, ApplicationAuthorizedWebhookEvent>();
options.AddDataObjectConverter<IWebhookEventPayload, WebhookEventPayload>();

return options;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Ctemplates/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Cusers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Cvoice/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Cwebhookevents/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cobjects_005Cwebhooks/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=api_005Cwebhookevents/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=json_005Cconverters/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=json_005Cconverters_005Cinternal/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=json_005Cpolicies/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Loading

0 comments on commit 5e7bfc5

Please sign in to comment.