Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for user-installable applications #327

Merged
merged 32 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1695c1d
feat(api): Add integration type to applications
VelvetToroyashi Nov 30, 2023
deef93e
feat(api): Add contexts
VelvetToroyashi Nov 30, 2023
81544f7
feat(commands): Add new hint attributes
VelvetToroyashi Nov 30, 2023
bcad4cb
fix(api): Set property names in converter
VelvetToroyashi Nov 30, 2023
3a1f9c1
feat(api): Add AuthorizingIntegrationOwners
VelvetToroyashi Nov 30, 2023
43840e5
fix(api): Add property mappings to bulk data as well
VelvetToroyashi Nov 30, 2023
da1dade
fix(api): Add missing parameter to InteractionCreate
VelvetToroyashi Nov 30, 2023
aefd709
feat(api): Add interaction callback hints
VelvetToroyashi Nov 30, 2023
7a9df56
feat(commands): Add missing install context attribute
VelvetToroyashi Nov 30, 2023
4be9310
feat(commands): Add support for user commands
VelvetToroyashi Nov 30, 2023
6718427
refactor(api)!: Make allowed contexts be `params`
VelvetToroyashi Nov 30, 2023
d1fe3d8
fix(api): Add missing interaction property
VelvetToroyashi Nov 30, 2023
a5d9e3b
feat: Implement integration type configurations
VelvetToroyashi Mar 18, 2024
35745b7
refactor: Remove interaction callback hints
VelvetToroyashi Mar 18, 2024
21e27a0
refactor: Remove interaction callback hints
VelvetToroyashi Mar 18, 2024
dbb4862
feat: Implement bulk of changes for user apps
VelvetToroyashi Mar 19, 2024
baac359
feat: Implement relevant API changes
VelvetToroyashi Mar 19, 2024
7120e48
fix: De-duplicate context enum
VelvetToroyashi Mar 19, 2024
0c5bf51
fix: Rename integration types config property to match Discord
VelvetToroyashi Mar 19, 2024
dba0317
fix: Fix test sample data, mostly.
VelvetToroyashi Mar 19, 2024
a6ad66c
fix: Fix remaining sample data
VelvetToroyashi Mar 19, 2024
891d4e6
fix(rest): Add DOC for IApplicationIntegrationTypeConfig
VelvetToroyashi Mar 19, 2024
395ca86
fix: Make type configs nullable instead of optional
VelvetToroyashi Mar 19, 2024
aab305a
chore: Fix test sample data (again)
VelvetToroyashi Mar 19, 2024
61034d3
feat: Implement missing interface counterparts
VelvetToroyashi Mar 19, 2024
4a947fa
fix: Remove more unimplemented stuff
VelvetToroyashi Mar 19, 2024
1269d3e
fix: Finally fix data (properly)
VelvetToroyashi Mar 31, 2024
9736b65
chore: Update Remora.Rest to latest version
VelvetToroyashi Apr 2, 2024
944f881
fix: Finally fix tests
VelvetToroyashi Apr 2, 2024
85fd434
fix: Cleanup some residual code
VelvetToroyashi Apr 2, 2024
b76f8bf
chore: Fix warnings and notes
VelvetToroyashi Apr 3, 2024
5b4b055
Address PR comments
VelvetToroyashi Apr 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .idea/.idea.Remora.Discord/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// ApplicationIntegrationType.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;

namespace Remora.Discord.API.Abstractions.Objects;

/// <summary>
/// Represents valid locations for users to install application integrations.
/// </summary>
[PublicAPI]
public enum ApplicationIntegrationType
Nihlus marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Specifies that the integration can be installed on a guild.
/// </summary>
GuildInstallable = 0,

/// <summary>
/// Specifies that the integration can be installed on a user.
/// </summary>
UserInstallable = 1,
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ public interface IApplication : IPartialApplication
/// </summary>
new Optional<Uri> CustomInstallUrl { get; }

/// <summary>
/// Gets the application's integration type configurations.
/// </summary>
new IReadOnlyDictionary<ApplicationIntegrationType, IApplicationIntegrationTypeConfig?> IntegrationTypesConfig { get; }

/// <inheritdoc/>
Optional<Snowflake> IPartialApplication.ID => this.ID;

Expand Down Expand Up @@ -242,4 +247,7 @@ public interface IApplication : IPartialApplication

/// <inheritdoc/>
Optional<Uri> IPartialApplication.CustomInstallUrl => this.CustomInstallUrl;

/// <inheritdoc/>
Optional<IReadOnlyDictionary<ApplicationIntegrationType, IApplicationIntegrationTypeConfig?>> IPartialApplication.IntegrationTypesConfig => new(this.IntegrationTypesConfig);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// IApplicationIntegrationTypeConfig.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;

namespace Remora.Discord.API.Abstractions.Objects;

/// <summary>
/// The integration type configuration for an application.
/// </summary>
[PublicAPI]
public interface IApplicationIntegrationTypeConfig
{
/// <summary>
/// Gets the OAuth2 install parameters for the integration type.
/// </summary>
public IApplicationOAuth2InstallParams OAuth2InstallParams { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// IApplicationOAuth2InstallParams.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;

namespace Remora.Discord.API.Abstractions.Objects;

/// <summary>
/// Represents the OAuth2 install parameters for an application.
/// </summary>
[PublicAPI]
public interface IApplicationOAuth2InstallParams
{
/// <summary>
/// Gets the permissions required for the application.
/// </summary>
/// <remarks>
/// Only applicable if <see cref="IApplicationOAuth2InstallParams.Scopes"/> includes `bot`.
/// </remarks>
IDiscordPermissionSet Permissions { get; }

/// <summary>
/// Gets the list of OAuth2 scopes required for the application.
/// </summary>
IReadOnlyList<string> Scopes { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,7 @@ public interface IPartialApplication

/// <inheritdoc cref="IApplication.CustomInstallUrl" />
Optional<Uri> CustomInstallUrl { get; }

/// <inheritdoc cref="IApplication.IntegrationTypesConfig" />
Optional<IReadOnlyDictionary<ApplicationIntegrationType, IApplicationIntegrationTypeConfig?>> IntegrationTypesConfig { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,14 @@ public interface IApplicationCommand
/// Gets a value indicating whether this command is age-restricted.
/// </summary>
Optional<bool> IsNsfw { get; }

/// <summary>
/// Gets a value indicating the contexts in which this command can be installed.
/// </summary>
Optional<IReadOnlyList<ApplicationIntegrationType>> IntegrationTypes { get; }

/// <summary>
/// Gets a value indicating the contexts in which this command can be invoked.
/// </summary>
Optional<IReadOnlyList<InteractionContextType>> Contexts { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,10 @@ public interface IBulkApplicationCommandData

/// <inheritdoc cref="IApplicationCommand.IsNsfw"/>
Optional<bool> IsNsfw { get; }

/// <inheritdoc cref="IApplicationCommand.IntegrationTypes"/>
Optional<IReadOnlyList<ApplicationIntegrationType>> IntegrationTypes { get; }

/// <inheritdoc cref="IApplicationCommand.Contexts"/>
Optional<IReadOnlyList<InteractionContextType>> Contexts { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// IApplicationCommandInteractionMetadata.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;

namespace Remora.Discord.API.Abstractions.Objects;

/// <summary>
/// Represents metadata related to application commands.
/// </summary>
[PublicAPI]
public interface IApplicationCommandInteractionMetadata : IMessageInteractionMetadata
{
/// <summary>
/// Gets the name of the command.
/// </summary>
string Name { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public interface IInteraction
/// <summary>
/// Gets the computed permissions for the application in the context of the interaction's execution.
/// </summary>
Optional<IDiscordPermissionSet> AppPermissions { get; }
IDiscordPermissionSet AppPermissions { get; }

/// <summary>
/// Gets the locale of the invoking user.
Expand All @@ -122,4 +122,23 @@ public interface IInteraction
/// Gets, for monetized apps, any entitlements for the invoking user.
/// </summary>
IReadOnlyList<IEntitlement> Entitlements { get; }

/// <summary>
/// Gets the context of the interaction.
/// </summary>
Optional<InteractionContextType> Context { get; }

/// <summary>
/// Gets the integrations that authorized the interaction.
/// </summary>
/// <remarks>
/// This is a mapping of the integration type to the ID of its resource.
/// <para>
/// The dictionary contains the following, given the circumstances: <br/>
/// - If the integration is installed to a user, a key of <see cref="ApplicationIntegrationType.UserInstallable"/> and the value is the user ID. <br/>
/// - If the integration is installed to a guild, a key of <see cref="ApplicationIntegrationType.GuildInstallable"/> and the value is the guild ID.
/// If the interaction is sent outside the context of a guild, the value is always zero.<br/>
Nihlus marked this conversation as resolved.
Show resolved Hide resolved
/// </para>
/// </remarks>
Optional<IReadOnlyDictionary<ApplicationIntegrationType, Snowflake>> AuthorizingIntegrationOwners { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// IMessageComponentInteractionMetadata.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 metadata related to a message component interaction.
/// </summary>
[PublicAPI]
public interface IMessageComponentInteractionMetadata : IMessageInteractionMetadata
{
/// <summary>
/// Gets the ID of the message that was interacted with.
/// </summary>
Snowflake InteractedMessageID { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// IMessageInteractionMetadata.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 the metadata of an application command interaction.
/// </summary>
[PublicAPI]
public interface IMessageInteractionMetadata
{
/// <summary>
/// Gets the ID of the interaction.
/// </summary>
Snowflake ID { get; }

/// <summary>
/// Gets the ID of the user who triggered the interaction.
/// </summary>
Snowflake UserID { get; }

/// <summary>
/// Gets the type of the interaction.
/// </summary>
InteractionType Type { get; }

/// <summary>
/// Gets the ID of the original response message. Only applicable to followup messages.
/// </summary>
Optional<Snowflake> OriginalResponseMessageID { get; }

/// <summary>
/// Gets the integrations that authorized the interaction.
/// </summary>
/// <remarks>
/// This is a mapping of the integration type to the ID of its resource.
/// <para>
/// The dictionary contains the following, given the circumstances: <br/>
/// - If the integration is installed to a user, a key of <see cref="ApplicationIntegrationType.UserInstallable"/> and the value is the user ID. <br/>
/// - If the integration is installed to a guild, a key of <see cref="ApplicationIntegrationType.GuildInstallable"/> and the value is the guild ID.
/// If the interaction is sent outside the context of a guild, the value is always zero.<br/>
Nihlus marked this conversation as resolved.
Show resolved Hide resolved
/// </para>
/// </remarks>
IReadOnlyDictionary<ApplicationIntegrationType, Snowflake> AuthorizingIntegrationOwners { get; }
}
Loading
Loading