[Feature] Initial user apps support (#2883)
* omg it kinda works somehow * more things added * a bit of xmldocs * added interaction framework support * working? IF * more builder stuff * space * rename attribute to prevent conflict with `ContextType` enum * context type * moar features * remove integration types * trigger workflow * modelzzzz * `InteractionContextType` * allow setting custom status with `SetGameAsync` * bugzzz * app permissions * message interaction context * hm * push for cd * structs lets goooo * whoops forgot to change types * whoops x2 * tweak some things * xmldocs + missing prop + fix enabled in dm * moar validations * deprecate a bunch of stuffz * disable moar obsolete warnings * add IF sample * Apply suggestions from code review Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> * Update src/Discord.Net.Rest/Entities/RestApplication.cs Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> --------- Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Discord.API;
|
||||
|
||||
@@ -94,4 +95,10 @@ internal class Application
|
||||
|
||||
[JsonProperty("verification_state")]
|
||||
public Optional<ApplicationVerificationState> VerificationState { get; set; }
|
||||
|
||||
[JsonProperty("integration_types")]
|
||||
public Optional<ApplicationIntegrationType[]> IntegrationTypes { get; set; }
|
||||
|
||||
[JsonProperty("integration_types_config")]
|
||||
public Optional<Dictionary<ApplicationIntegrationType, InstallParams>> IntegrationTypesConfig { get; set; }
|
||||
}
|
||||
|
||||
@@ -50,5 +50,11 @@ namespace Discord.API
|
||||
|
||||
[JsonProperty("nsfw")]
|
||||
public Optional<bool?> Nsfw { get; set; }
|
||||
|
||||
[JsonProperty("contexts")]
|
||||
public Optional<InteractionContextType[]> ContextTypes { get; set; }
|
||||
|
||||
[JsonProperty("integration_types")]
|
||||
public Optional<ApplicationIntegrationType[]> IntegrationTypes { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@ internal class InstallParams
|
||||
public string[] Scopes { get; set; }
|
||||
|
||||
[JsonProperty("permissions")]
|
||||
public ulong Permission { get; set; }
|
||||
public GuildPermission Permission { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,53 +1,63 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Discord.API;
|
||||
|
||||
[JsonConverter(typeof(Net.Converters.InteractionConverter))]
|
||||
internal class Interaction
|
||||
{
|
||||
[JsonConverter(typeof(Net.Converters.InteractionConverter))]
|
||||
internal class Interaction
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public ulong Id { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public ulong Id { get; set; }
|
||||
|
||||
[JsonProperty("application_id")]
|
||||
public ulong ApplicationId { get; set; }
|
||||
[JsonProperty("application_id")]
|
||||
public ulong ApplicationId { get; set; }
|
||||
|
||||
[JsonProperty("type")]
|
||||
public InteractionType Type { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public InteractionType Type { get; set; }
|
||||
|
||||
[JsonProperty("data")]
|
||||
public Optional<IDiscordInteractionData> Data { get; set; }
|
||||
[JsonProperty("data")]
|
||||
public Optional<IDiscordInteractionData> Data { get; set; }
|
||||
|
||||
[JsonProperty("guild_id")]
|
||||
public Optional<ulong> GuildId { get; set; }
|
||||
[JsonProperty("guild_id")]
|
||||
public Optional<ulong> GuildId { get; set; }
|
||||
|
||||
[JsonProperty("channel_id")]
|
||||
public Optional<ulong> ChannelId { get; set; }
|
||||
[JsonProperty("channel")]
|
||||
public Optional<Channel> Channel { get; set; }
|
||||
|
||||
[JsonProperty("channel")]
|
||||
public Optional<Channel> Channel { get; set; }
|
||||
[JsonProperty("channel_id")]
|
||||
public Optional<ulong> ChannelId { get; set; }
|
||||
|
||||
[JsonProperty("member")]
|
||||
public Optional<GuildMember> Member { get; set; }
|
||||
[JsonProperty("member")]
|
||||
public Optional<GuildMember> Member { get; set; }
|
||||
|
||||
[JsonProperty("user")]
|
||||
public Optional<User> User { get; set; }
|
||||
[JsonProperty("user")]
|
||||
public Optional<User> User { get; set; }
|
||||
|
||||
[JsonProperty("token")]
|
||||
public string Token { get; set; }
|
||||
[JsonProperty("token")]
|
||||
public string Token { get; set; }
|
||||
|
||||
[JsonProperty("version")]
|
||||
public int Version { get; set; }
|
||||
[JsonProperty("version")]
|
||||
public int Version { get; set; }
|
||||
|
||||
[JsonProperty("message")]
|
||||
public Optional<Message> Message { get; set; }
|
||||
[JsonProperty("message")]
|
||||
public Optional<Message> Message { get; set; }
|
||||
|
||||
[JsonProperty("locale")]
|
||||
public Optional<string> UserLocale { get; set; }
|
||||
[JsonProperty("locale")]
|
||||
public Optional<string> UserLocale { get; set; }
|
||||
|
||||
[JsonProperty("guild_locale")]
|
||||
public Optional<string> GuildLocale { get; set; }
|
||||
[JsonProperty("guild_locale")]
|
||||
public Optional<string> GuildLocale { get; set; }
|
||||
|
||||
[JsonProperty("entitlements")]
|
||||
public Entitlement[] Entitlements { get; set; }
|
||||
}
|
||||
[JsonProperty("entitlements")]
|
||||
public Entitlement[] Entitlements { get; set; }
|
||||
|
||||
[JsonProperty("authorizing_integration_owners")]
|
||||
public Dictionary<ApplicationIntegrationType, ulong> IntegrationOwners { get; set; }
|
||||
|
||||
[JsonProperty("context")]
|
||||
public Optional<InteractionContextType> ContextType { get; set; }
|
||||
|
||||
[JsonProperty("app_permissions")]
|
||||
public GuildPermission ApplicationPermissions { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,74 +1,104 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Discord.API
|
||||
namespace Discord.API;
|
||||
|
||||
internal class Message
|
||||
{
|
||||
internal class Message
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public ulong Id { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public MessageType Type { get; set; }
|
||||
[JsonProperty("channel_id")]
|
||||
public ulong ChannelId { get; set; }
|
||||
// ALWAYS sent on WebSocket messages
|
||||
[JsonProperty("guild_id")]
|
||||
public Optional<ulong> GuildId { get; set; }
|
||||
[JsonProperty("webhook_id")]
|
||||
public Optional<ulong> WebhookId { get; set; }
|
||||
[JsonProperty("author")]
|
||||
public Optional<User> Author { get; set; }
|
||||
// ALWAYS sent on WebSocket messages
|
||||
[JsonProperty("member")]
|
||||
public Optional<GuildMember> Member { get; set; }
|
||||
[JsonProperty("content")]
|
||||
public Optional<string> Content { get; set; }
|
||||
[JsonProperty("timestamp")]
|
||||
public Optional<DateTimeOffset> Timestamp { get; set; }
|
||||
[JsonProperty("edited_timestamp")]
|
||||
public Optional<DateTimeOffset?> EditedTimestamp { get; set; }
|
||||
[JsonProperty("tts")]
|
||||
public Optional<bool> IsTextToSpeech { get; set; }
|
||||
[JsonProperty("mention_everyone")]
|
||||
public Optional<bool> MentionEveryone { get; set; }
|
||||
[JsonProperty("mentions")]
|
||||
public Optional<User[]> UserMentions { get; set; }
|
||||
[JsonProperty("mention_roles")]
|
||||
public Optional<ulong[]> RoleMentions { get; set; }
|
||||
[JsonProperty("attachments")]
|
||||
public Optional<Attachment[]> Attachments { get; set; }
|
||||
[JsonProperty("embeds")]
|
||||
public Optional<Embed[]> Embeds { get; set; }
|
||||
[JsonProperty("pinned")]
|
||||
public Optional<bool> Pinned { get; set; }
|
||||
[JsonProperty("reactions")]
|
||||
public Optional<Reaction[]> Reactions { get; set; }
|
||||
// sent with Rich Presence-related chat embeds
|
||||
[JsonProperty("activity")]
|
||||
public Optional<MessageActivity> Activity { get; set; }
|
||||
// sent with Rich Presence-related chat embeds
|
||||
[JsonProperty("application")]
|
||||
public Optional<MessageApplication> Application { get; set; }
|
||||
[JsonProperty("message_reference")]
|
||||
public Optional<MessageReference> Reference { get; set; }
|
||||
[JsonProperty("flags")]
|
||||
public Optional<MessageFlags> Flags { get; set; }
|
||||
[JsonProperty("allowed_mentions")]
|
||||
public Optional<AllowedMentions> AllowedMentions { get; set; }
|
||||
[JsonProperty("referenced_message")]
|
||||
public Optional<Message> ReferencedMessage { get; set; }
|
||||
[JsonProperty("components")]
|
||||
public Optional<API.ActionRowComponent[]> Components { get; set; }
|
||||
public Optional<MessageInteraction> Interaction { get; set; }
|
||||
[JsonProperty("sticker_items")]
|
||||
public Optional<StickerItem[]> StickerItems { get; set; }
|
||||
[JsonProperty("role_subscription_data")]
|
||||
public Optional<MessageRoleSubscriptionData> RoleSubscriptionData { get; set; }
|
||||
[JsonProperty("id")]
|
||||
public ulong Id { get; set; }
|
||||
|
||||
[JsonProperty("thread")]
|
||||
public Optional<Channel> Thread { get; set; }
|
||||
[JsonProperty("type")]
|
||||
public MessageType Type { get; set; }
|
||||
|
||||
[JsonProperty("resolved")]
|
||||
public Optional<MessageComponentInteractionDataResolved> Resolved { get; set; }
|
||||
}
|
||||
[JsonProperty("channel_id")]
|
||||
public ulong ChannelId { get; set; }
|
||||
|
||||
// ALWAYS sent on WebSocket messages
|
||||
[JsonProperty("guild_id")]
|
||||
public Optional<ulong> GuildId { get; set; }
|
||||
|
||||
[JsonProperty("webhook_id")]
|
||||
public Optional<ulong> WebhookId { get; set; }
|
||||
|
||||
[JsonProperty("author")]
|
||||
public Optional<User> Author { get; set; }
|
||||
|
||||
// ALWAYS sent on WebSocket messages
|
||||
[JsonProperty("member")]
|
||||
public Optional<GuildMember> Member { get; set; }
|
||||
|
||||
[JsonProperty("content")]
|
||||
public Optional<string> Content { get; set; }
|
||||
|
||||
[JsonProperty("timestamp")]
|
||||
public Optional<DateTimeOffset> Timestamp { get; set; }
|
||||
|
||||
[JsonProperty("edited_timestamp")]
|
||||
public Optional<DateTimeOffset?> EditedTimestamp { get; set; }
|
||||
|
||||
[JsonProperty("tts")]
|
||||
public Optional<bool> IsTextToSpeech { get; set; }
|
||||
|
||||
[JsonProperty("mention_everyone")]
|
||||
public Optional<bool> MentionEveryone { get; set; }
|
||||
|
||||
[JsonProperty("mentions")]
|
||||
public Optional<User[]> UserMentions { get; set; }
|
||||
|
||||
[JsonProperty("mention_roles")]
|
||||
public Optional<ulong[]> RoleMentions { get; set; }
|
||||
|
||||
[JsonProperty("attachments")]
|
||||
public Optional<Attachment[]> Attachments { get; set; }
|
||||
|
||||
[JsonProperty("embeds")]
|
||||
public Optional<Embed[]> Embeds { get; set; }
|
||||
|
||||
[JsonProperty("pinned")]
|
||||
public Optional<bool> Pinned { get; set; }
|
||||
|
||||
[JsonProperty("reactions")]
|
||||
public Optional<Reaction[]> Reactions { get; set; }
|
||||
|
||||
// sent with Rich Presence-related chat embeds
|
||||
[JsonProperty("activity")]
|
||||
public Optional<MessageActivity> Activity { get; set; }
|
||||
|
||||
// sent with Rich Presence-related chat embeds
|
||||
[JsonProperty("application")]
|
||||
public Optional<MessageApplication> Application { get; set; }
|
||||
|
||||
[JsonProperty("message_reference")]
|
||||
public Optional<MessageReference> Reference { get; set; }
|
||||
|
||||
[JsonProperty("flags")]
|
||||
public Optional<MessageFlags> Flags { get; set; }
|
||||
|
||||
[JsonProperty("allowed_mentions")]
|
||||
public Optional<AllowedMentions> AllowedMentions { get; set; }
|
||||
|
||||
[JsonProperty("referenced_message")]
|
||||
public Optional<Message> ReferencedMessage { get; set; }
|
||||
|
||||
[JsonProperty("components")]
|
||||
public Optional<ActionRowComponent[]> Components { get; set; }
|
||||
|
||||
[JsonProperty("interaction")]
|
||||
public Optional<MessageInteraction> Interaction { get; set; }
|
||||
|
||||
[JsonProperty("sticker_items")]
|
||||
public Optional<StickerItem[]> StickerItems { get; set; }
|
||||
|
||||
[JsonProperty("role_subscription_data")]
|
||||
public Optional<MessageRoleSubscriptionData> RoleSubscriptionData { get; set; }
|
||||
|
||||
[JsonProperty("thread")]
|
||||
public Optional<Channel> Thread { get; set; }
|
||||
|
||||
[JsonProperty("resolved")]
|
||||
public Optional<MessageComponentInteractionDataResolved> Resolved { get; set; }
|
||||
|
||||
[JsonProperty("interaction_metadata")]
|
||||
public Optional<MessageInteractionMetadata> InteractionMetadata { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Discord.API;
|
||||
|
||||
internal class MessageInteractionMetadata
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public ulong Id { get; set; }
|
||||
|
||||
[JsonProperty("type")]
|
||||
public InteractionType Type { get; set; }
|
||||
|
||||
[JsonProperty("user_id")]
|
||||
public ulong UserId { get; set; }
|
||||
|
||||
[JsonProperty("authorizing_integration_owners")]
|
||||
public Dictionary<ApplicationIntegrationType, ulong> IntegrationOwners { get; set; }
|
||||
|
||||
[JsonProperty("original_response_message_id")]
|
||||
public Optional<ulong> OriginalResponseMessageId { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
public Optional<string> Name { get; set; }
|
||||
|
||||
[JsonProperty("interacted_message_id")]
|
||||
public Optional<ulong> InteractedMessageId { get; set; }
|
||||
|
||||
[JsonProperty("triggering_interaction_metadata")]
|
||||
public Optional<MessageInteractionMetadata> TriggeringInteractionMetadata { get; set; }
|
||||
}
|
||||
@@ -38,9 +38,17 @@ namespace Discord.API.Rest
|
||||
[JsonProperty("nsfw")]
|
||||
public Optional<bool> Nsfw { get; set; }
|
||||
|
||||
[JsonProperty("contexts")]
|
||||
public Optional<HashSet<InteractionContextType>> ContextTypes { get; set; }
|
||||
|
||||
[JsonProperty("integration_types")]
|
||||
public Optional<HashSet<ApplicationIntegrationType>> IntegrationTypes { get; set; }
|
||||
|
||||
public CreateApplicationCommandParams() { }
|
||||
|
||||
public CreateApplicationCommandParams(string name, string description, ApplicationCommandType type, ApplicationCommandOption[] options = null,
|
||||
IDictionary<string, string> nameLocalizations = null, IDictionary<string, string> descriptionLocalizations = null, bool nsfw = false)
|
||||
IDictionary<string, string> nameLocalizations = null, IDictionary<string, string> descriptionLocalizations = null, bool nsfw = false,
|
||||
HashSet<InteractionContextType> contextTypes = null, HashSet<ApplicationIntegrationType> integrationTypes = null)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
@@ -49,6 +57,8 @@ namespace Discord.API.Rest
|
||||
NameLocalizations = nameLocalizations?.ToDictionary(x => x.Key, x => x.Value) ?? Optional<Dictionary<string, string>>.Unspecified;
|
||||
DescriptionLocalizations = descriptionLocalizations?.ToDictionary(x => x.Key, x => x.Value) ?? Optional<Dictionary<string, string>>.Unspecified;
|
||||
Nsfw = nsfw;
|
||||
ContextTypes = contextTypes ?? Optional.Create<HashSet<InteractionContextType>>();
|
||||
IntegrationTypes = integrationTypes ?? Optional.Create<HashSet<ApplicationIntegrationType>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,5 +28,11 @@ namespace Discord.API.Rest
|
||||
|
||||
[JsonProperty("description_localizations")]
|
||||
public Optional<Dictionary<string, string>> DescriptionLocalizations { get; set; }
|
||||
|
||||
[JsonProperty("contexts")]
|
||||
public Optional<HashSet<InteractionContextType>> ContextTypes { get; set; }
|
||||
|
||||
[JsonProperty("integration_types")]
|
||||
public Optional<HashSet<ApplicationIntegrationType>> IntegrationTypes { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Discord.API.Rest;
|
||||
|
||||
@@ -30,4 +31,7 @@ internal class ModifyCurrentApplicationBotParams
|
||||
|
||||
[JsonProperty("tags")]
|
||||
public Optional<string[]> Tags { get; set; }
|
||||
}
|
||||
|
||||
[JsonProperty("integration_types_config")]
|
||||
public Optional<Dictionary<ApplicationIntegrationType, InstallParams>> IntegrationTypesConfig { get; set; }
|
||||
}
|
||||
|
||||
@@ -55,10 +55,17 @@ namespace Discord.Rest
|
||||
? null
|
||||
: new InstallParams
|
||||
{
|
||||
Permission = (ulong)args.InstallParams.Value.Permission,
|
||||
Permission = args.InstallParams.Value.Permission,
|
||||
Scopes = args.InstallParams.Value.Scopes.ToArray()
|
||||
}
|
||||
: Optional<InstallParams>.Unspecified,
|
||||
IntegrationTypesConfig = args.IntegrationTypesConfig.IsSpecified
|
||||
? args.IntegrationTypesConfig.Value?.ToDictionary(x => x.Key, x => new InstallParams
|
||||
{
|
||||
Permission = x.Value.Permission,
|
||||
Scopes = x.Value.Scopes.ToArray()
|
||||
})
|
||||
: Optional<Dictionary<ApplicationIntegrationType, InstallParams>>.Unspecified
|
||||
}, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,8 @@ namespace Discord.Rest
|
||||
DefaultMemberPermission = arg.DefaultMemberPermissions.ToNullable(),
|
||||
DmPermission = arg.IsDMEnabled.ToNullable(),
|
||||
Nsfw = arg.IsNsfw.GetValueOrDefault(false),
|
||||
IntegrationTypes = arg.IntegrationTypes,
|
||||
ContextTypes = arg.ContextTypes
|
||||
};
|
||||
|
||||
if (arg is SlashCommandProperties slashProps)
|
||||
@@ -146,7 +148,9 @@ namespace Discord.Rest
|
||||
// TODO: better conversion to nullable optionals
|
||||
DefaultMemberPermission = arg.DefaultMemberPermissions.ToNullable(),
|
||||
DmPermission = arg.IsDMEnabled.ToNullable(),
|
||||
Nsfw = arg.IsNsfw.GetValueOrDefault(false)
|
||||
Nsfw = arg.IsNsfw.GetValueOrDefault(false),
|
||||
IntegrationTypes = arg.IntegrationTypes,
|
||||
ContextTypes = arg.ContextTypes
|
||||
};
|
||||
|
||||
if (arg is SlashCommandProperties slashProps)
|
||||
@@ -190,7 +194,9 @@ namespace Discord.Rest
|
||||
// TODO: better conversion to nullable optionals
|
||||
DefaultMemberPermission = arg.DefaultMemberPermissions.ToNullable(),
|
||||
DmPermission = arg.IsDMEnabled.ToNullable(),
|
||||
Nsfw = arg.IsNsfw.GetValueOrDefault(false)
|
||||
Nsfw = arg.IsNsfw.GetValueOrDefault(false),
|
||||
IntegrationTypes = arg.IntegrationTypes,
|
||||
ContextTypes = arg.ContextTypes
|
||||
};
|
||||
|
||||
if (arg is SlashCommandProperties slashProps)
|
||||
@@ -254,7 +260,9 @@ namespace Discord.Rest
|
||||
NameLocalizations = args.NameLocalizations?.ToDictionary(),
|
||||
DescriptionLocalizations = args.DescriptionLocalizations?.ToDictionary(),
|
||||
Nsfw = args.IsNsfw.GetValueOrDefault(false),
|
||||
DefaultMemberPermission = args.DefaultMemberPermissions.ToNullable()
|
||||
DefaultMemberPermission = args.DefaultMemberPermissions.ToNullable(),
|
||||
IntegrationTypes = args.IntegrationTypes,
|
||||
ContextTypes = args.ContextTypes
|
||||
};
|
||||
|
||||
if (args is SlashCommandProperties slashProps)
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Discord.Rest
|
||||
public bool IsDefaultPermission { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
[Obsolete("This property will be deprecated soon. Use ContextTypes instead.")]
|
||||
public bool IsEnabledInDm { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -67,6 +68,12 @@ namespace Discord.Rest
|
||||
/// </remarks>
|
||||
public string DescriptionLocalized { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<ApplicationIntegrationType> IntegrationTypes { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<InteractionContextType> ContextTypes { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTimeOffset CreatedAt
|
||||
=> SnowflakeUtils.FromSnowflake(Id);
|
||||
@@ -102,9 +109,14 @@ namespace Discord.Rest
|
||||
NameLocalized = model.NameLocalized.GetValueOrDefault();
|
||||
DescriptionLocalized = model.DescriptionLocalized.GetValueOrDefault();
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
IsEnabledInDm = model.DmPermission.GetValueOrDefault(true).GetValueOrDefault(true);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
DefaultMemberPermissions = new GuildPermissions((ulong)model.DefaultMemberPermission.GetValueOrDefault(0).GetValueOrDefault(0));
|
||||
IsNsfw = model.Nsfw.GetValueOrDefault(false).GetValueOrDefault(false);
|
||||
|
||||
IntegrationTypes = model.IntegrationTypes.GetValueOrDefault(null)?.ToImmutableArray();
|
||||
ContextTypes = model.ContextTypes.GetValueOrDefault(null)?.ToImmutableArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -90,9 +90,18 @@ namespace Discord.Rest
|
||||
/// <inheritdoc/>
|
||||
public ulong ApplicationId { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public InteractionContextType? ContextType { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public GuildPermissions Permissions { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IDiscordInteraction.Entitlements" />
|
||||
public IReadOnlyCollection<RestEntitlement> Entitlements { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyDictionary<ApplicationIntegrationType, ulong> IntegrationOwners { get; private set; }
|
||||
|
||||
internal RestInteraction(BaseDiscordClient discord, ulong id)
|
||||
: base(discord, id)
|
||||
{
|
||||
@@ -232,6 +241,13 @@ namespace Discord.Rest
|
||||
: null;
|
||||
|
||||
Entitlements = model.Entitlements.Select(x => RestEntitlement.Create(discord, x)).ToImmutableArray();
|
||||
|
||||
IntegrationOwners = model.IntegrationOwners;
|
||||
ContextType = model.ContextType.IsSpecified
|
||||
? model.ContextType.Value
|
||||
: null;
|
||||
|
||||
Permissions = new GuildPermissions((ulong)model.ApplicationPermissions);
|
||||
}
|
||||
|
||||
internal string SerializePayload(object payload)
|
||||
|
||||
@@ -308,6 +308,7 @@ namespace Discord.Rest
|
||||
IReadOnlyCollection<IMessageComponent> IMessage.Components => Components;
|
||||
|
||||
/// <inheritdoc/>
|
||||
[Obsolete("This property will be deprecated soon. Use IUserMessage.InteractionMetadata instead.")]
|
||||
IMessageInteraction IMessage.Interaction => Interaction;
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -48,6 +48,9 @@ namespace Discord.Rest
|
||||
/// <inheritdoc />
|
||||
public IUserMessage ReferencedMessage => _referencedMessage;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IMessageInteractionMetadata InteractionMetadata { get; internal set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public MessageResolvedData ResolvedData { get; internal set; }
|
||||
|
||||
@@ -162,6 +165,8 @@ namespace Discord.Rest
|
||||
|
||||
ResolvedData = new MessageResolvedData(users, members, roles, channels);
|
||||
}
|
||||
if (model.InteractionMetadata.IsSpecified)
|
||||
InteractionMetadata = model.InteractionMetadata.Value.ToInteractionMetadata();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -6,183 +6,195 @@ using System.Threading.Tasks;
|
||||
|
||||
using Model = Discord.API.Application;
|
||||
|
||||
namespace Discord.Rest
|
||||
namespace Discord.Rest;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a REST-based entity that contains information about a Discord application created via the developer portal.
|
||||
/// </summary>
|
||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||
public class RestApplication : RestEntity<ulong>, IApplication
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a REST-based entity that contains information about a Discord application created via the developer portal.
|
||||
/// </summary>
|
||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||
public class RestApplication : RestEntity<ulong>, IApplication
|
||||
protected string _iconId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string Description { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<string> RPCOrigins { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public ApplicationFlags Flags { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public bool? IsBotPublic { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public bool? BotRequiresCodeGrant { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public ITeam Team { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public IUser Owner { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string TermsOfService { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string PrivacyPolicy { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string VerifyKey { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string CustomInstallUrl { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string RoleConnectionsVerificationUrl { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
|
||||
/// <inheritdoc />
|
||||
public string IconUrl => CDN.GetApplicationIconUrl(Id, _iconId);
|
||||
|
||||
/// <inheritdoc />
|
||||
public PartialGuild Guild { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public int? ApproximateGuildCount { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<string> RedirectUris { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string InteractionsEndpointUrl { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationInstallParams InstallParams { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationDiscoverabilityState DiscoverabilityState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public DiscoveryEligibilityFlags DiscoveryEligibilityFlags { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationExplicitContentFilterLevel ExplicitContentFilterLevel { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsHook { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<string> InteractionEventTypes { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationInteractionsVersion InteractionsVersion { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsMonetized { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationMonetizationEligibilityFlags MonetizationEligibilityFlags { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationMonetizationState MonetizationState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationRpcState RpcState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationStoreState StoreState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationVerificationState VerificationState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<string> Tags { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyDictionary<ApplicationIntegrationType, ApplicationInstallParams> IntegrationTypesConfig { get; private set; }
|
||||
|
||||
internal RestApplication(BaseDiscordClient discord, ulong id)
|
||||
: base(discord, id)
|
||||
{
|
||||
protected string _iconId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string Description { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<string> RPCOrigins { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public ApplicationFlags Flags { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public bool? IsBotPublic { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public bool? BotRequiresCodeGrant { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public ITeam Team { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public IUser Owner { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string TermsOfService { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string PrivacyPolicy { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string VerifyKey { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string CustomInstallUrl { get; private set; }
|
||||
/// <inheritdoc />
|
||||
public string RoleConnectionsVerificationUrl { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
|
||||
/// <inheritdoc />
|
||||
public string IconUrl => CDN.GetApplicationIconUrl(Id, _iconId);
|
||||
|
||||
/// <inheritdoc />
|
||||
public PartialGuild Guild { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public int? ApproximateGuildCount { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<string> RedirectUris { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string InteractionsEndpointUrl { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationInstallParams InstallParams { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationDiscoverabilityState DiscoverabilityState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public DiscoveryEligibilityFlags DiscoveryEligibilityFlags { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationExplicitContentFilterLevel ExplicitContentFilterLevel { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsHook { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<string> InteractionEventTypes { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationInteractionsVersion InteractionsVersion { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsMonetized { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationMonetizationEligibilityFlags MonetizationEligibilityFlags { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationMonetizationState MonetizationState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationRpcState RpcState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationStoreState StoreState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationVerificationState VerificationState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<string> Tags { get; private set; }
|
||||
|
||||
internal RestApplication(BaseDiscordClient discord, ulong id)
|
||||
: base(discord, id)
|
||||
{
|
||||
}
|
||||
internal static RestApplication Create(BaseDiscordClient discord, Model model)
|
||||
{
|
||||
var entity = new RestApplication(discord, model.Id);
|
||||
entity.Update(model);
|
||||
return entity;
|
||||
}
|
||||
internal void Update(Model model)
|
||||
{
|
||||
Description = model.Description;
|
||||
RPCOrigins = model.RPCOrigins.IsSpecified ? model.RPCOrigins.Value.ToImmutableArray() : ImmutableArray<string>.Empty;
|
||||
Name = model.Name;
|
||||
_iconId = model.Icon;
|
||||
IsBotPublic = model.IsBotPublic.IsSpecified ? model.IsBotPublic.Value : null;
|
||||
BotRequiresCodeGrant = model.BotRequiresCodeGrant.IsSpecified ? model.BotRequiresCodeGrant.Value : null;
|
||||
Tags = model.Tags.GetValueOrDefault(null)?.ToImmutableArray() ?? ImmutableArray<string>.Empty;
|
||||
PrivacyPolicy = model.PrivacyPolicy;
|
||||
TermsOfService = model.TermsOfService;
|
||||
|
||||
InstallParams = model.InstallParams.IsSpecified
|
||||
? new ApplicationInstallParams(model.InstallParams.Value.Scopes, (GuildPermission)model.InstallParams.Value.Permission)
|
||||
: null;
|
||||
|
||||
if (model.Flags.IsSpecified)
|
||||
Flags = model.Flags.Value;
|
||||
if (model.Owner.IsSpecified)
|
||||
Owner = RestUser.Create(Discord, model.Owner.Value);
|
||||
if (model.Team != null)
|
||||
Team = RestTeam.Create(Discord, model.Team);
|
||||
|
||||
CustomInstallUrl = model.CustomInstallUrl.IsSpecified ? model.CustomInstallUrl.Value : null;
|
||||
RoleConnectionsVerificationUrl = model.RoleConnectionsUrl.IsSpecified ? model.RoleConnectionsUrl.Value : null;
|
||||
VerifyKey = model.VerifyKey;
|
||||
|
||||
if (model.PartialGuild.IsSpecified)
|
||||
Guild = PartialGuildExtensions.Create(model.PartialGuild.Value);
|
||||
|
||||
InteractionsEndpointUrl = model.InteractionsEndpointUrl.IsSpecified ? model.InteractionsEndpointUrl.Value : null;
|
||||
|
||||
if (model.RedirectUris.IsSpecified)
|
||||
RedirectUris = model.RedirectUris.Value.ToImmutableArray();
|
||||
|
||||
ApproximateGuildCount = model.ApproximateGuildCount.IsSpecified ? model.ApproximateGuildCount.Value : null;
|
||||
|
||||
DiscoverabilityState = model.DiscoverabilityState.GetValueOrDefault(ApplicationDiscoverabilityState.None);
|
||||
DiscoveryEligibilityFlags = model.DiscoveryEligibilityFlags.GetValueOrDefault(DiscoveryEligibilityFlags.None);
|
||||
ExplicitContentFilterLevel = model.ExplicitContentFilter.GetValueOrDefault(ApplicationExplicitContentFilterLevel.Disabled);
|
||||
IsHook = model.IsHook;
|
||||
|
||||
InteractionEventTypes = model.InteractionsEventTypes.GetValueOrDefault(Array.Empty<string>()).ToImmutableArray();
|
||||
InteractionsVersion = model.InteractionsVersion.GetValueOrDefault(ApplicationInteractionsVersion.Version1);
|
||||
|
||||
IsMonetized = model.IsMonetized;
|
||||
MonetizationEligibilityFlags = model.MonetizationEligibilityFlags.GetValueOrDefault(ApplicationMonetizationEligibilityFlags.None);
|
||||
MonetizationState = model.MonetizationState.GetValueOrDefault(ApplicationMonetizationState.None);
|
||||
|
||||
RpcState = model.RpcState.GetValueOrDefault(ApplicationRpcState.Disabled);
|
||||
StoreState = model.StoreState.GetValueOrDefault(ApplicationStoreState.None);
|
||||
VerificationState = model.VerificationState.GetValueOrDefault(ApplicationVerificationState.Ineligible);
|
||||
}
|
||||
|
||||
/// <exception cref="InvalidOperationException">Unable to update this object from a different application token.</exception>
|
||||
public async Task UpdateAsync()
|
||||
{
|
||||
var response = await Discord.ApiClient.GetMyApplicationAsync().ConfigureAwait(false);
|
||||
if (response.Id != Id)
|
||||
throw new InvalidOperationException("Unable to update this object from a different application token.");
|
||||
Update(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the application.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Name of the application.
|
||||
/// </returns>
|
||||
public override string ToString() => Name;
|
||||
private string DebuggerDisplay => $"{Name} ({Id})";
|
||||
}
|
||||
internal static RestApplication Create(BaseDiscordClient discord, Model model)
|
||||
{
|
||||
var entity = new RestApplication(discord, model.Id);
|
||||
entity.Update(model);
|
||||
return entity;
|
||||
}
|
||||
internal void Update(Model model)
|
||||
{
|
||||
Description = model.Description;
|
||||
RPCOrigins = model.RPCOrigins.IsSpecified ? model.RPCOrigins.Value.ToImmutableArray() : ImmutableArray<string>.Empty;
|
||||
Name = model.Name;
|
||||
_iconId = model.Icon;
|
||||
IsBotPublic = model.IsBotPublic.IsSpecified ? model.IsBotPublic.Value : null;
|
||||
BotRequiresCodeGrant = model.BotRequiresCodeGrant.IsSpecified ? model.BotRequiresCodeGrant.Value : null;
|
||||
Tags = model.Tags.GetValueOrDefault(null)?.ToImmutableArray() ?? ImmutableArray<string>.Empty;
|
||||
PrivacyPolicy = model.PrivacyPolicy;
|
||||
TermsOfService = model.TermsOfService;
|
||||
|
||||
InstallParams = model.InstallParams.IsSpecified
|
||||
? new ApplicationInstallParams(model.InstallParams.Value.Scopes, (GuildPermission)model.InstallParams.Value.Permission)
|
||||
: null;
|
||||
|
||||
if (model.Flags.IsSpecified)
|
||||
Flags = model.Flags.Value;
|
||||
if (model.Owner.IsSpecified)
|
||||
Owner = RestUser.Create(Discord, model.Owner.Value);
|
||||
if (model.Team != null)
|
||||
Team = RestTeam.Create(Discord, model.Team);
|
||||
|
||||
CustomInstallUrl = model.CustomInstallUrl.IsSpecified ? model.CustomInstallUrl.Value : null;
|
||||
RoleConnectionsVerificationUrl = model.RoleConnectionsUrl.IsSpecified ? model.RoleConnectionsUrl.Value : null;
|
||||
VerifyKey = model.VerifyKey;
|
||||
|
||||
if (model.PartialGuild.IsSpecified)
|
||||
Guild = PartialGuildExtensions.Create(model.PartialGuild.Value);
|
||||
|
||||
InteractionsEndpointUrl = model.InteractionsEndpointUrl.IsSpecified ? model.InteractionsEndpointUrl.Value : null;
|
||||
|
||||
if (model.RedirectUris.IsSpecified)
|
||||
RedirectUris = model.RedirectUris.Value.ToImmutableArray();
|
||||
|
||||
ApproximateGuildCount = model.ApproximateGuildCount.IsSpecified ? model.ApproximateGuildCount.Value : null;
|
||||
|
||||
DiscoverabilityState = model.DiscoverabilityState.GetValueOrDefault(ApplicationDiscoverabilityState.None);
|
||||
DiscoveryEligibilityFlags = model.DiscoveryEligibilityFlags.GetValueOrDefault(DiscoveryEligibilityFlags.None);
|
||||
ExplicitContentFilterLevel = model.ExplicitContentFilter.GetValueOrDefault(ApplicationExplicitContentFilterLevel.Disabled);
|
||||
IsHook = model.IsHook;
|
||||
|
||||
InteractionEventTypes = model.InteractionsEventTypes.GetValueOrDefault(Array.Empty<string>()).ToImmutableArray();
|
||||
InteractionsVersion = model.InteractionsVersion.GetValueOrDefault(ApplicationInteractionsVersion.Version1);
|
||||
|
||||
IsMonetized = model.IsMonetized;
|
||||
MonetizationEligibilityFlags = model.MonetizationEligibilityFlags.GetValueOrDefault(ApplicationMonetizationEligibilityFlags.None);
|
||||
MonetizationState = model.MonetizationState.GetValueOrDefault(ApplicationMonetizationState.None);
|
||||
|
||||
RpcState = model.RpcState.GetValueOrDefault(ApplicationRpcState.Disabled);
|
||||
StoreState = model.StoreState.GetValueOrDefault(ApplicationStoreState.None);
|
||||
VerificationState = model.VerificationState.GetValueOrDefault(ApplicationVerificationState.Ineligible);
|
||||
|
||||
var dict = new Dictionary<ApplicationIntegrationType, ApplicationInstallParams>();
|
||||
if (model.IntegrationTypesConfig.IsSpecified)
|
||||
{
|
||||
foreach (var p in model.IntegrationTypesConfig.Value)
|
||||
{
|
||||
dict.Add(p.Key, new ApplicationInstallParams(p.Value.Scopes ?? Array.Empty<string>(), p.Value.Permission));
|
||||
}
|
||||
}
|
||||
IntegrationTypesConfig = dict.ToImmutableDictionary();
|
||||
}
|
||||
|
||||
/// <exception cref="InvalidOperationException">Unable to update this object from a different application token.</exception>
|
||||
public async Task UpdateAsync()
|
||||
{
|
||||
var response = await Discord.ApiClient.GetMyApplicationAsync().ConfigureAwait(false);
|
||||
if (response.Id != Id)
|
||||
throw new InvalidOperationException("Unable to update this object from a different application token.");
|
||||
Update(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the application.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The name of the application.
|
||||
/// </returns>
|
||||
public override string ToString() => Name;
|
||||
private string DebuggerDisplay => $"{Name} ({Id})";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Discord.Rest;
|
||||
|
||||
internal static class InteractionMetadataExtensions
|
||||
{
|
||||
public static IMessageInteractionMetadata ToInteractionMetadata(this API.MessageInteractionMetadata metadata)
|
||||
{
|
||||
switch (metadata.Type)
|
||||
{
|
||||
case InteractionType.ApplicationCommand:
|
||||
return new ApplicationCommandInteractionMetadata(
|
||||
metadata.Id,
|
||||
metadata.Type,
|
||||
metadata.UserId,
|
||||
metadata.IntegrationOwners.ToImmutableDictionary(),
|
||||
metadata.OriginalResponseMessageId.IsSpecified ? metadata.OriginalResponseMessageId.Value : null,
|
||||
metadata.Name.GetValueOrDefault(null));
|
||||
|
||||
case InteractionType.MessageComponent:
|
||||
return new MessageComponentInteractionMetadata(
|
||||
metadata.Id,
|
||||
metadata.Type,
|
||||
metadata.UserId,
|
||||
metadata.IntegrationOwners.ToImmutableDictionary(),
|
||||
metadata.OriginalResponseMessageId.IsSpecified ? metadata.OriginalResponseMessageId.Value : null,
|
||||
metadata.InteractedMessageId.GetValueOrDefault(0));
|
||||
|
||||
case InteractionType.ModalSubmit:
|
||||
return new ModalSubmitInteractionMetadata(
|
||||
metadata.Id,
|
||||
metadata.Type,
|
||||
metadata.UserId,
|
||||
metadata.IntegrationOwners.ToImmutableDictionary(),
|
||||
metadata.OriginalResponseMessageId.IsSpecified ? metadata.OriginalResponseMessageId.Value : null,
|
||||
metadata.TriggeringInteractionMetadata.GetValueOrDefault(null)?.ToInteractionMetadata());
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user