From ae95d284faff7bcb361d6df73119e9e53d179733 Mon Sep 17 00:00:00 2001 From: quin lynch Date: Sat, 21 Aug 2021 02:40:10 -0300 Subject: [PATCH] Simply internal usage of context menus --- src/Discord.Net.Core/Discord.Net.Core.xml | 197 +++--- .../ApplicationCommandProperties.cs | 26 +- .../Interactions/ApplicationCommandTypes.cs | 10 +- .../MessageCommandBuilder.cs | 11 +- .../Context Menus/MessageCommandProperties.cs | 16 + .../{ => Context Menus}/UserCommandBuilder.cs | 9 +- .../Context Menus/UserCommandProperties.cs | 16 + .../ContextMenuCommandCreationProperties.cs | 24 - .../Interactions/IApplicationCommand.cs | 12 +- .../Interactions/SlashCommandBuilder.cs | 9 +- ...roperties.cs => SlashCommandProperties.cs} | 17 +- .../UserCommandCreationProperties.cs | 30 - .../API/Common/ApplicationCommand.cs | 8 + src/Discord.Net.Rest/API/Net/IResolvable.cs | 1 - .../Rest/ModifyApplicationCommandParams.cs | 3 - src/Discord.Net.Rest/Discord.Net.Rest.xml | 121 +--- src/Discord.Net.Rest/DiscordRestClient.cs | 28 +- .../Interactions/InteractionHelper.cs | 568 ++++-------------- .../Interactions/RestApplicationCommand.cs | 39 +- .../RestApplicationCommandOption.cs | 7 +- .../RestApplicationCommandType.cs | 28 - .../Interactions/RestGlobalCommand.cs | 11 +- .../Interactions/RestGlobalMessageCommand.cs | 41 -- .../Interactions/RestGlobalUserCommand.cs | 41 -- .../Entities/Interactions/RestGuildCommand.cs | 10 +- .../Interactions/RestGuildMessageCommand.cs | 61 -- .../Interactions/RestGuildUserCommand.cs | 61 -- .../ApplicationCommandCreatedUpdatedEvent.cs | 22 +- .../Discord.Net.WebSocket.xml | 25 +- .../DiscordSocketClient.cs | 33 +- .../SocketApplicationCommand.cs | 70 ++- 31 files changed, 429 insertions(+), 1126 deletions(-) rename src/Discord.Net.Core/Entities/Interactions/{ => Context Menus}/MessageCommandBuilder.cs (81%) create mode 100644 src/Discord.Net.Core/Entities/Interactions/Context Menus/MessageCommandProperties.cs rename src/Discord.Net.Core/Entities/Interactions/{ => Context Menus}/UserCommandBuilder.cs (81%) create mode 100644 src/Discord.Net.Core/Entities/Interactions/Context Menus/UserCommandProperties.cs delete mode 100644 src/Discord.Net.Core/Entities/Interactions/ContextMenuCommandCreationProperties.cs rename src/Discord.Net.Core/Entities/Interactions/{SlashCommandCreationProperties.cs => SlashCommandProperties.cs} (66%) delete mode 100644 src/Discord.Net.Core/Entities/Interactions/UserCommandCreationProperties.cs delete mode 100644 src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandType.cs delete mode 100644 src/Discord.Net.Rest/Entities/Interactions/RestGlobalMessageCommand.cs delete mode 100644 src/Discord.Net.Rest/Entities/Interactions/RestGlobalUserCommand.cs delete mode 100644 src/Discord.Net.Rest/Entities/Interactions/RestGuildMessageCommand.cs delete mode 100644 src/Discord.Net.Rest/Entities/Interactions/RestGuildUserCommand.cs diff --git a/src/Discord.Net.Core/Discord.Net.Core.xml b/src/Discord.Net.Core/Discord.Net.Core.xml index 8be13e6bd..187461b93 100644 --- a/src/Discord.Net.Core/Discord.Net.Core.xml +++ b/src/Discord.Net.Core/Discord.Net.Core.xml @@ -4461,7 +4461,7 @@ - Provides properties that are used to modify a with the specified changes. + Represents the base class to create/modify application commands. @@ -4469,64 +4469,101 @@ Gets or sets the name of this command. - + - Gets or sets the discription of this command. + ApplicationCommandType is enum of current valid Application Command Types: Slash, User, Message - + - Gets or sets the type for this command. + ApplicationCommandType.Slash is Slash command type - + - Gets or sets the options for this command. + ApplicationCommandType.User is Context Menu User command type - + - Whether the command is enabled by default when the app is added to a guild. Default is + ApplicationCommandType.Message is Context Menu Message command type - + - ApplicationCommandType is enum of current valid Application Command Types: Slash, User, Message + A class used to build Message commands. - + + + Returns the maximun length a commands name allowed by Discord + + + - ApplicationCommandType.Slash is Slash command type + The name of this Message command. - + - ApplicationCommandType.User is Context Menu User command type + Build the current builder into a class. + + A that can be used to create message commands. + - + - ApplicationCommandType.Message is Context Menu Message command type + Sets the field name. + The value to set the field name to. + + The current builder. + - + - A class used to create Message commands. + A class used to create message commands. - + - The name of this command. + A class used to build user commands. + + + + + Returns the maximun length a commands name allowed by Discord + + + + + The name of this User command. + + + + + Build the current builder into a class. + A that can be used to create user commands. - + - Gets or sets the type for this command. + Sets the field name. + + The value to set the field name to. + + The current builder. + + + + + A class used to create User commands. - The base command model that belongs to an application. see + The base command model that belongs to an application. @@ -4559,6 +4596,16 @@ If the option is a subcommand or subcommand group type, this nested options will be the parameters. + + + Modifies the current application command. + + The new properties to use when modifying the command. + The options to be used when sending the request. + + A task that represents the asynchronous modification operation. + + Represents data of an Interaction Command, see . @@ -5571,36 +5618,6 @@ Will render this option as selected by default. - - - A class used to build Message commands. - - - - - Returns the maximun length a commands name allowed by Discord - - - - - The name of this Message command. - - - - - Build the current builder into a class. - - A that can be used to create message commands over rest. - - - - Sets the field name. - - The value to set the field name to. - - The current builder. - - A class used to build slash commands. @@ -5643,9 +5660,9 @@ - Build the current builder into a class. + Build the current builder into a class. - A that can be used to create slash commands over rest. + A that can be used to create slash commands over rest. @@ -5833,86 +5850,26 @@ The type to set. The current builder. - + A class used to create slash commands. - - - The name of this command. - - - + The discription of this command. - - - Gets or sets the type for this command. - - - + Gets or sets the options for this command. - + Whether the command is enabled by default when the app is added to a guild. Default is - - - A class used to build user commands. - - - - - Returns the maximun length a commands name allowed by Discord - - - - - The name of this User command. - - - - - Build the current builder into a class. - - A that can be used to create user commands over rest. - - - - Sets the field name. - - The value to set the field name to. - - The current builder. - - - - - A class used to create User commands. - - - - - The name of this command. - - - - - The discription of this command. - - - - - Gets or sets the type for this command. - - Represents a generic invite object. diff --git a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs index 70b430bfc..2ccb0148b 100644 --- a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs +++ b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs @@ -7,33 +7,17 @@ using System.Threading.Tasks; namespace Discord { /// - /// Provides properties that are used to modify a with the specified changes. + /// Represents the base class to create/modify application commands. /// - public class ApplicationCommandProperties + public abstract class ApplicationCommandProperties { + internal abstract ApplicationCommandType Type { get; } + /// /// Gets or sets the name of this command. /// public Optional Name { get; set; } - /// - /// Gets or sets the discription of this command. - /// - public Optional Description { get; set; } - - /// - /// Gets or sets the type for this command. - /// - public Optional Type { get; set; } - - /// - /// Gets or sets the options for this command. - /// - public Optional> Options { get; set; } - - /// - /// Whether the command is enabled by default when the app is added to a guild. Default is - /// - public Optional DefaultPermission { get; set; } + internal ApplicationCommandProperties() { } } } diff --git a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandTypes.cs b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandTypes.cs index de9c1a263..3cfa97a5a 100644 --- a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandTypes.cs +++ b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandTypes.cs @@ -7,20 +7,22 @@ using System.Threading.Tasks; namespace Discord { /// - /// ApplicationCommandType is enum of current valid Application Command Types: Slash, User, Message + /// ApplicationCommandType is enum of current valid Application Command Types: Slash, User, Message /// public enum ApplicationCommandType : byte { /// - /// ApplicationCommandType.Slash is Slash command type + /// ApplicationCommandType.Slash is Slash command type /// Slash = 1, + /// - /// ApplicationCommandType.User is Context Menu User command type + /// ApplicationCommandType.User is Context Menu User command type /// User = 2, + /// - /// ApplicationCommandType.Message is Context Menu Message command type + /// ApplicationCommandType.Message is Context Menu Message command type /// Message = 3 } diff --git a/src/Discord.Net.Core/Entities/Interactions/MessageCommandBuilder.cs b/src/Discord.Net.Core/Entities/Interactions/Context Menus/MessageCommandBuilder.cs similarity index 81% rename from src/Discord.Net.Core/Entities/Interactions/MessageCommandBuilder.cs rename to src/Discord.Net.Core/Entities/Interactions/Context Menus/MessageCommandBuilder.cs index b658a181b..9907dd2cf 100644 --- a/src/Discord.Net.Core/Entities/Interactions/MessageCommandBuilder.cs +++ b/src/Discord.Net.Core/Entities/Interactions/Context Menus/MessageCommandBuilder.cs @@ -44,15 +44,16 @@ namespace Discord private string _name { get; set; } /// - /// Build the current builder into a class. + /// Build the current builder into a class. /// - /// A that can be used to create message commands over rest. - public ContextMenuCommandCreationProperties Build() + /// + /// A that can be used to create message commands. + /// + public MessageCommandProperties Build() { - ContextMenuCommandCreationProperties props = new ContextMenuCommandCreationProperties() + MessageCommandProperties props = new MessageCommandProperties() { Name = this.Name, - Type=ApplicationCommandType.Message }; return props; diff --git a/src/Discord.Net.Core/Entities/Interactions/Context Menus/MessageCommandProperties.cs b/src/Discord.Net.Core/Entities/Interactions/Context Menus/MessageCommandProperties.cs new file mode 100644 index 000000000..3af9b47f3 --- /dev/null +++ b/src/Discord.Net.Core/Entities/Interactions/Context Menus/MessageCommandProperties.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Discord +{ + /// + /// A class used to create message commands. + /// + public class MessageCommandProperties : ApplicationCommandProperties + { + internal override ApplicationCommandType Type => ApplicationCommandType.Message; + } +} diff --git a/src/Discord.Net.Core/Entities/Interactions/UserCommandBuilder.cs b/src/Discord.Net.Core/Entities/Interactions/Context Menus/UserCommandBuilder.cs similarity index 81% rename from src/Discord.Net.Core/Entities/Interactions/UserCommandBuilder.cs rename to src/Discord.Net.Core/Entities/Interactions/Context Menus/UserCommandBuilder.cs index f10b6b123..d415a99a6 100644 --- a/src/Discord.Net.Core/Entities/Interactions/UserCommandBuilder.cs +++ b/src/Discord.Net.Core/Entities/Interactions/Context Menus/UserCommandBuilder.cs @@ -44,15 +44,14 @@ namespace Discord private string _name { get; set; } /// - /// Build the current builder into a class. + /// Build the current builder into a class. /// - /// A that can be used to create user commands over rest. - public ContextMenuCommandCreationProperties Build() + /// A that can be used to create user commands. + public UserCommandProperties Build() { - ContextMenuCommandCreationProperties props = new ContextMenuCommandCreationProperties() + UserCommandProperties props = new UserCommandProperties() { Name = this.Name, - Type=ApplicationCommandType.User }; return props; diff --git a/src/Discord.Net.Core/Entities/Interactions/Context Menus/UserCommandProperties.cs b/src/Discord.Net.Core/Entities/Interactions/Context Menus/UserCommandProperties.cs new file mode 100644 index 000000000..091166a17 --- /dev/null +++ b/src/Discord.Net.Core/Entities/Interactions/Context Menus/UserCommandProperties.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Discord +{ + /// + /// A class used to create User commands. + /// + public class UserCommandProperties : ApplicationCommandProperties + { + internal override ApplicationCommandType Type => ApplicationCommandType.User; + } +} diff --git a/src/Discord.Net.Core/Entities/Interactions/ContextMenuCommandCreationProperties.cs b/src/Discord.Net.Core/Entities/Interactions/ContextMenuCommandCreationProperties.cs deleted file mode 100644 index 4ddc0a7b1..000000000 --- a/src/Discord.Net.Core/Entities/Interactions/ContextMenuCommandCreationProperties.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Discord -{ - /// - /// A class used to create Message commands. - /// - public class ContextMenuCommandCreationProperties - { - /// - /// The name of this command. - /// - public string Name { get; set; } - - /// - /// Gets or sets the type for this command. - /// - public ApplicationCommandType Type { get; set; } - } -} diff --git a/src/Discord.Net.Core/Entities/Interactions/IApplicationCommand.cs b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommand.cs index e15843d98..e0cf605d2 100644 --- a/src/Discord.Net.Core/Entities/Interactions/IApplicationCommand.cs +++ b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommand.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace Discord { /// - /// The base command model that belongs to an application. see + /// The base command model that belongs to an application. /// public interface IApplicationCommand : ISnowflakeEntity, IDeletable { @@ -40,5 +40,15 @@ namespace Discord /// If the option is a subcommand or subcommand group type, this nested options will be the parameters. /// IReadOnlyCollection Options { get; } + + /// + /// Modifies the current application command. + /// + /// The new properties to use when modifying the command. + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous modification operation. + /// + Task ModifyAsync(Action func, RequestOptions options = null); } } diff --git a/src/Discord.Net.Core/Entities/Interactions/SlashCommandBuilder.cs b/src/Discord.Net.Core/Entities/Interactions/SlashCommandBuilder.cs index 933f511e1..8a1bd8314 100644 --- a/src/Discord.Net.Core/Entities/Interactions/SlashCommandBuilder.cs +++ b/src/Discord.Net.Core/Entities/Interactions/SlashCommandBuilder.cs @@ -93,17 +93,16 @@ namespace Discord private List _options { get; set; } /// - /// Build the current builder into a class. + /// Build the current builder into a class. /// - /// A that can be used to create slash commands over rest. - public SlashCommandCreationProperties Build() + /// A that can be used to create slash commands over rest. + public SlashCommandProperties Build() { - SlashCommandCreationProperties props = new SlashCommandCreationProperties() + SlashCommandProperties props = new SlashCommandProperties() { Name = this.Name, Description = this.Description, DefaultPermission = this.DefaultPermission, - Type = ApplicationCommandType.Slash }; if (this.Options != null && this.Options.Any()) diff --git a/src/Discord.Net.Core/Entities/Interactions/SlashCommandCreationProperties.cs b/src/Discord.Net.Core/Entities/Interactions/SlashCommandProperties.cs similarity index 66% rename from src/Discord.Net.Core/Entities/Interactions/SlashCommandCreationProperties.cs rename to src/Discord.Net.Core/Entities/Interactions/SlashCommandProperties.cs index 3021d7a2c..72c7c322b 100644 --- a/src/Discord.Net.Core/Entities/Interactions/SlashCommandCreationProperties.cs +++ b/src/Discord.Net.Core/Entities/Interactions/SlashCommandProperties.cs @@ -9,22 +9,13 @@ namespace Discord /// /// A class used to create slash commands. /// - public class SlashCommandCreationProperties + public class SlashCommandProperties : ApplicationCommandProperties { - /// - /// The name of this command. - /// - public string Name { get; set; } - + internal override ApplicationCommandType Type => ApplicationCommandType.Slash; /// /// The discription of this command. /// - public string Description { get; set; } - - /// - /// Gets or sets the type for this command. - /// - public ApplicationCommandType Type { get; set; } + public Optional Description { get; set; } /// /// Gets or sets the options for this command. @@ -35,5 +26,7 @@ namespace Discord /// Whether the command is enabled by default when the app is added to a guild. Default is /// public Optional DefaultPermission { get; set; } + + internal SlashCommandProperties() { } } } diff --git a/src/Discord.Net.Core/Entities/Interactions/UserCommandCreationProperties.cs b/src/Discord.Net.Core/Entities/Interactions/UserCommandCreationProperties.cs deleted file mode 100644 index 323b2ce1d..000000000 --- a/src/Discord.Net.Core/Entities/Interactions/UserCommandCreationProperties.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Discord -{ - /// - /// A class used to create User commands. - /// - public class UserCommandCreationProperties - { - /// - /// The name of this command. - /// - public string Name { get; set; } - - /// - /// The discription of this command. - /// - public string Description { get; set; } - - - /// - /// Gets or sets the type for this command. - /// - public ApplicationCommandType Type { get; set; } - } -} diff --git a/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs b/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs index 39c40a1ee..9de272706 100644 --- a/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs +++ b/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs @@ -11,14 +11,22 @@ namespace Discord.API { [JsonProperty("id")] public ulong Id { get; set; } + + [JsonProperty("type")] + public ApplicationCommandType Type { get; set; } = ApplicationCommandType.Slash; // defaults to 1 which is slash. + [JsonProperty("application_id")] public ulong ApplicationId { get; set; } + [JsonProperty("name")] public string Name { get; set; } + [JsonProperty("description")] public string Description { get; set; } + [JsonProperty("options")] public Optional Options { get; set; } + [JsonProperty("default_permission")] public Optional DefaultPermissions { get; set; } } diff --git a/src/Discord.Net.Rest/API/Net/IResolvable.cs b/src/Discord.Net.Rest/API/Net/IResolvable.cs index fe31cd75e..7485f5de8 100644 --- a/src/Discord.Net.Rest/API/Net/IResolvable.cs +++ b/src/Discord.Net.Rest/API/Net/IResolvable.cs @@ -9,6 +9,5 @@ namespace Discord.API internal interface IResolvable { Optional Resolved { get; } - } } diff --git a/src/Discord.Net.Rest/API/Rest/ModifyApplicationCommandParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyApplicationCommandParams.cs index 29a6ff796..2ed9466c0 100644 --- a/src/Discord.Net.Rest/API/Rest/ModifyApplicationCommandParams.cs +++ b/src/Discord.Net.Rest/API/Rest/ModifyApplicationCommandParams.cs @@ -15,9 +15,6 @@ namespace Discord.API.Rest [JsonProperty("description")] public Optional Description { get; set; } - [JsonProperty("type")] - public Optional Type { get; set; } - [JsonProperty("options")] public Optional Options { get; set; } diff --git a/src/Discord.Net.Rest/Discord.Net.Rest.xml b/src/Discord.Net.Rest/Discord.Net.Rest.xml index 0fc188b2e..0378df092 100644 --- a/src/Discord.Net.Rest/Discord.Net.Rest.xml +++ b/src/Discord.Net.Rest/Discord.Net.Rest.xml @@ -3762,17 +3762,15 @@ The options of this command. - - - The type of this rest application command. - - + + + Represents a Rest-based implementation of . @@ -3814,24 +3812,9 @@ A collection of 's for this command. - - - Represents a type of Rest-based command. - - - - - Specifies that this command is a Global command. - - - - - Specifies that this command is a Guild specific command. - - - Represents a global Slash command. + Represents a Rest-based global application command. @@ -3847,35 +3830,9 @@ The modified command. - - - - - - Modifies this . - - The delegate containing the properties to modify the command with. - The options to be used when sending the request. - - The modified command. - - - - - - - - Modifies this . - - The delegate containing the properties to modify the command with. - The options to be used when sending the request. - - The modified command. - - - Represents a Rest-based guild command. + Represents a Rest-based guild application command. @@ -3928,74 +3885,6 @@ . - - - Represents a Rest-based guild command. - - - - - The guild Id where this command originates. - - - - - - - - Modifies this . - - The delegate containing the properties to modify the command with. - The options to be used when sending the request. - - The modified command - - - - - Gets the guild that this slash command resides in. - - if you want the approximate member and presence counts for the guild, otherwise . - The options to be used when sending the request. - - A task that represents the asynchronous get operation. The task result contains a - . - - - - - Represents a Rest-based guild command. - - - - - The guild Id where this command originates. - - - - - - - - Modifies this . - - The delegate containing the properties to modify the command with. - The options to be used when sending the request. - - The modified command - - - - - Gets the guild that this slash command resides in. - - if you want the approximate member and presence counts for the guild, otherwise . - The options to be used when sending the request. - - A task that represents the asynchronous get operation. The task result contains a - . - - diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs index c204a2d1c..32dbaf40e 100644 --- a/src/Discord.Net.Rest/DiscordRestClient.cs +++ b/src/Discord.Net.Rest/DiscordRestClient.cs @@ -108,37 +108,21 @@ namespace Discord.Rest public Task GetWebhookAsync(ulong id, RequestOptions options = null) => ClientHelper.GetWebhookAsync(this, id, options); - public Task CreateGlobalCommand(SlashCommandCreationProperties properties, RequestOptions options = null) + public Task CreateGlobalCommand(ApplicationCommandProperties properties, RequestOptions options = null) => InteractionHelper.CreateGlobalCommand(this, properties, options); - public Task CreateGlobalCommand(Action func, RequestOptions options = null) + public Task CreateGlobalCommand(Action func, RequestOptions options = null) => InteractionHelper.CreateGlobalCommand(this, func, options); - public Task CreateGlobalUserCommand(ContextMenuCommandCreationProperties properties, RequestOptions options = null) - => InteractionHelper.CreateGlobalUserCommand(this, properties, options); - public Task CreateGlobalUserCommand(Action func, RequestOptions options = null) - => InteractionHelper.CreateGlobalUserCommand(this, func, options); - public Task CreateGlobalMessageCommand(ContextMenuCommandCreationProperties properties, RequestOptions options = null) - => InteractionHelper.CreateGlobalMessageCommand(this, properties, options); - public Task CreateGlobalMessageCommand(Action func, RequestOptions options = null) - => InteractionHelper.CreateGlobalMessageCommand(this, func, options); - public Task CreateGuildCommand(SlashCommandCreationProperties properties, ulong guildId, RequestOptions options = null) + public Task CreateGuildCommand(ApplicationCommandProperties properties, ulong guildId, RequestOptions options = null) => InteractionHelper.CreateGuildCommand(this, guildId, properties, options); - public Task CreateGuildCommand(Action func, ulong guildId, RequestOptions options = null) + public Task CreateGuildCommand(Action func, ulong guildId, RequestOptions options = null) => InteractionHelper.CreateGuildCommand(this, guildId, func, options); - public Task CreateGuildUserCommand(ContextMenuCommandCreationProperties properties, ulong guildId, RequestOptions options = null) - => InteractionHelper.CreateGuildUserCommand(this, guildId, properties, options); - public Task CreateGuildUserCommand(Action func, ulong guildId, RequestOptions options = null) - => InteractionHelper.CreateGuildUserCommand(this, guildId, func, options); - public Task CreateGuildMessageCommand(ContextMenuCommandCreationProperties properties, ulong guildId, RequestOptions options = null) - => InteractionHelper.CreateGuildMessageCommand(this, guildId, properties, options); - public Task CreateGuildMessageCommand(Action func, ulong guildId, RequestOptions options = null) - => InteractionHelper.CreateGuildMessageCommand(this, guildId, func, options); public Task> GetGlobalApplicationCommands(RequestOptions options = null) => ClientHelper.GetGlobalApplicationCommands(this, options); public Task> GetGuildApplicationCommands(ulong guildId, RequestOptions options = null) => ClientHelper.GetGuildApplicationCommands(this, guildId, options); - public Task> BulkOverwriteGlobalCommands(SlashCommandCreationProperties[] commandProperties, RequestOptions options = null) + public Task> BulkOverwriteGlobalCommands(ApplicationCommandProperties[] commandProperties, RequestOptions options = null) => InteractionHelper.BulkOverwriteGlobalCommands(this, commandProperties, options); - public Task> BulkOverwriteGuildCommands(SlashCommandCreationProperties[] commandProperties, ulong guildId, RequestOptions options = null) + public Task> BulkOverwriteGuildCommands(ApplicationCommandProperties[] commandProperties, ulong guildId, RequestOptions options = null) => InteractionHelper.BulkOverwriteGuildCommands(this, guildId, commandProperties, options); public Task> BatchEditGuildCommandPermissions(ulong guildId, IDictionary permissions, RequestOptions options = null) => InteractionHelper.BatchEditGuildCommandPermissionsAsync(this, guildId, permissions, options); diff --git a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs index b5c354047..fbbce4f4b 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs @@ -44,41 +44,45 @@ namespace Discord.Rest } // Global commands - public static async Task CreateGlobalCommand(BaseDiscordClient client, - Action func, RequestOptions options = null) + public static async Task CreateGlobalCommand(BaseDiscordClient client, + Action func, RequestOptions options) where TArg : ApplicationCommandProperties { - var args = new SlashCommandCreationProperties(); - func(args); - return await CreateGlobalCommand(client, args, options).ConfigureAwait(false); + var args = Activator.CreateInstance(typeof(TArg)); + func((TArg)args); + return await CreateGlobalCommand(client, (TArg)args, options); } public static async Task CreateGlobalCommand(BaseDiscordClient client, - SlashCommandCreationProperties arg, RequestOptions options = null) + ApplicationCommandProperties arg, RequestOptions options = null) { Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - Preconditions.NotNullOrEmpty(arg.Description, nameof(arg.Description)); - - if (arg.Options.IsSpecified) - Preconditions.AtMost(arg.Options.Value.Count, 25, nameof(arg.Options)); var model = new CreateApplicationCommandParams() { - Name = arg.Name, - Description = arg.Description, - Type= arg.Type, - Options = arg.Options.IsSpecified - ? arg.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() - : Optional.Unspecified, - DefaultPermission = arg.DefaultPermission.IsSpecified - ? arg.DefaultPermission.Value - : Optional.Unspecified + Name = arg.Name.Value, + Type = arg.Type, }; + if (arg is SlashCommandProperties slashProps) + { + Preconditions.NotNullOrEmpty(slashProps.Description, nameof(slashProps.Description)); + + model.Description = slashProps.Description.Value; + + model.Options = slashProps.Options.IsSpecified + ? slashProps.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() + : Optional.Unspecified; + + model.DefaultPermission = slashProps.DefaultPermission.IsSpecified + ? slashProps.DefaultPermission.Value + : Optional.Unspecified; + } + var cmd = await client.ApiClient.CreateGlobalApplicationCommandAsync(model, options).ConfigureAwait(false); return RestGlobalCommand.Create(client, cmd); } public static async Task> BulkOverwriteGlobalCommands(BaseDiscordClient client, - SlashCommandCreationProperties[] args, RequestOptions options = null) + ApplicationCommandProperties[] args, RequestOptions options = null) { Preconditions.NotNull(args, nameof(args)); @@ -87,24 +91,28 @@ namespace Discord.Rest foreach (var arg in args) { Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - Preconditions.NotNullOrEmpty(arg.Description, nameof(arg.Description)); - - if (arg.Options.IsSpecified) - Preconditions.AtMost(arg.Options.Value.Count, 25, nameof(arg.Options)); var model = new CreateApplicationCommandParams() { - Name = arg.Name, - Description = arg.Description, + Name = arg.Name.Value, Type = arg.Type, - Options = arg.Options.IsSpecified - ? arg.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() - : Optional.Unspecified, - DefaultPermission = arg.DefaultPermission.IsSpecified - ? arg.DefaultPermission.Value - : Optional.Unspecified }; + if (arg is SlashCommandProperties slashProps) + { + Preconditions.NotNullOrEmpty(slashProps.Description, nameof(slashProps.Description)); + + model.Description = slashProps.Description.Value; + + model.Options = slashProps.Options.IsSpecified + ? slashProps.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() + : Optional.Unspecified; + + model.DefaultPermission = slashProps.DefaultPermission.IsSpecified + ? slashProps.DefaultPermission.Value + : Optional.Unspecified; + } + models.Add(model); } @@ -114,7 +122,7 @@ namespace Discord.Rest } public static async Task> BulkOverwriteGuildCommands(BaseDiscordClient client, ulong guildId, - SlashCommandCreationProperties[] args, RequestOptions options = null) + ApplicationCommandProperties[] args, RequestOptions options = null) { Preconditions.NotNull(args, nameof(args)); @@ -123,236 +131,88 @@ namespace Discord.Rest foreach (var arg in args) { Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - Preconditions.NotNullOrEmpty(arg.Description, nameof(arg.Description)); - - if (arg.Options.IsSpecified) - Preconditions.AtMost(arg.Options.Value.Count, 25, nameof(arg.Options)); var model = new CreateApplicationCommandParams() { - Name = arg.Name, - Description = arg.Description, + Name = arg.Name.Value, Type = arg.Type, - Options = arg.Options.IsSpecified - ? arg.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() - : Optional.Unspecified, - DefaultPermission = arg.DefaultPermission.IsSpecified - ? arg.DefaultPermission.Value - : Optional.Unspecified }; - models.Add(model); - } - - var apiModels = await client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, models.ToArray(), options); - - return apiModels.Select(x => RestGuildCommand.Create(client, x, guildId)).ToArray(); - } + if (arg is SlashCommandProperties slashProps) + { + Preconditions.NotNullOrEmpty(slashProps.Description, nameof(slashProps.Description)); - public static async Task ModifyGlobalCommand(BaseDiscordClient client, RestGlobalCommand command, - Action func, RequestOptions options = null) - { - ApplicationCommandProperties args = new ApplicationCommandProperties(); - func(args); + model.Description = slashProps.Description.Value; - if (args.Name.IsSpecified) - { - Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name)); - Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name)); - } - if (args.Description.IsSpecified) - { - Preconditions.AtMost(args.Description.Value.Length, 100, nameof(args.Description)); - Preconditions.AtLeast(args.Description.Value.Length, 1, nameof(args.Description)); - } + model.Options = slashProps.Options.IsSpecified + ? slashProps.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() + : Optional.Unspecified; + model.DefaultPermission = slashProps.DefaultPermission.IsSpecified + ? slashProps.DefaultPermission.Value + : Optional.Unspecified; + } - if (args.Options.IsSpecified) - { - if (args.Options.Value.Count > 10) - throw new ArgumentException("Option count must be 10 or less"); + models.Add(model); } - var model = new Discord.API.Rest.ModifyApplicationCommandParams() - { - Name = args.Name, - Description = args.Description, - Type = args.Type, - Options = args.Options.IsSpecified - ? args.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() - : Optional.Unspecified, - DefaultPermission = args.DefaultPermission.IsSpecified - ? args.DefaultPermission.Value - : Optional.Unspecified - }; - - var msg = await client.ApiClient.ModifyGlobalApplicationCommandAsync(model, command.Id, options).ConfigureAwait(false); - command.Update(msg); - return command; - } - - - public static async Task DeleteGlobalCommand(BaseDiscordClient client, RestGlobalCommand command, RequestOptions options = null) - { - Preconditions.NotNull(command, nameof(command)); - Preconditions.NotEqual(command.Id, 0, nameof(command.Id)); - - await client.ApiClient.DeleteGlobalApplicationCommandAsync(command.Id, options).ConfigureAwait(false); - } - - public static async Task CreateGlobalUserCommand(BaseDiscordClient client, Action func, RequestOptions options = null) - { - var args = new ContextMenuCommandCreationProperties(); - func(args); - return await CreateGlobalUserCommand(client, args, options).ConfigureAwait(false); - } - - public static async Task CreateGlobalUserCommand(BaseDiscordClient client, ContextMenuCommandCreationProperties arg, RequestOptions options = null) - { - Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - - var model = new CreateApplicationCommandParams() - { - Name = arg.Name, - Type = arg.Type - }; - - var cmd = await client.ApiClient.CreateGlobalApplicationUserCommandAsync(model, options).ConfigureAwait(false); - return RestGlobalUserCommand.Create(client, cmd); - } + var apiModels = await client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, models.ToArray(), options); - public static async Task CreateGlobalMessageCommand(BaseDiscordClient client, Action func, RequestOptions options = null) - { - var args = new ContextMenuCommandCreationProperties(); - func(args); - return await CreateGlobalMessageCommand(client, args, options).ConfigureAwait(false); + return apiModels.Select(x => RestGuildCommand.Create(client, x, guildId)).ToArray(); } - public static async Task CreateGlobalMessageCommand(BaseDiscordClient client, ContextMenuCommandCreationProperties arg, RequestOptions options = null) + public static Task ModifyGlobalCommand(BaseDiscordClient client, IApplicationCommand command, + Action func, RequestOptions options = null) where TArg : ApplicationCommandProperties { - Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - - var model = new CreateApplicationCommandParams() - { - Name = arg.Name, - Type = arg.Type - }; - - var cmd = await client.ApiClient.CreateGlobalApplicationMessageCommandAsync(model, options).ConfigureAwait(false); - return RestGlobalMessageCommand.Create(client, cmd); + var arg = (TArg)Activator.CreateInstance(typeof(TArg)); + func(arg); + return ModifyGlobalCommand(client, command, arg, options); } - public static async Task> BulkOverwriteGlobalUserCommands(BaseDiscordClient client, ContextMenuCommandCreationProperties[] args, RequestOptions options = null) + public static async Task ModifyGlobalCommand(BaseDiscordClient client, IApplicationCommand command, + ApplicationCommandProperties args, RequestOptions options = null) { - Preconditions.NotNull(args, nameof(args)); - - List models = new List(); - - foreach (var arg in args) - { - Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - Preconditions.Equals(arg.Type, ApplicationCommandType.User); - - var model = new CreateApplicationCommandParams() - { - Name = arg.Name, - Type = arg.Type - }; - - models.Add(model); - } - - var apiModels = await client.ApiClient.BulkOverwriteGlobalApplicationUserCommands(models.ToArray(), options); - - return apiModels.Select(x => RestGlobalUserCommand.Create(client, x)).ToArray(); - } - public static async Task ModifyGlobalUserCommand(BaseDiscordClient client, RestGlobalUserCommand command, - Action func, RequestOptions options = null) - { - ApplicationCommandProperties args = new ApplicationCommandProperties(); - func(args); - if (args.Name.IsSpecified) { Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name)); Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name)); } - if (args.Description.IsSpecified) - { - Preconditions.Equals(args.Description.Value, ""); - } var model = new Discord.API.Rest.ModifyApplicationCommandParams() { Name = args.Name, - Description = args.Description }; - var msg = await client.ApiClient.ModifyGlobalApplicationUserCommandAsync(model, command.Id, options).ConfigureAwait(false); - command.Update(msg); - return command; - } - - public static async Task DeleteGlobalUserCommand(BaseDiscordClient client, RestGlobalUserCommand command, RequestOptions options = null) - { - Preconditions.NotNull(command, nameof(command)); - Preconditions.NotEqual(command.Id, 0, nameof(command.Id)); - - await client.ApiClient.DeleteGlobalApplicationCommandAsync(command.Id, options).ConfigureAwait(false); - } - - public static async Task> BulkOverwriteGlobalMessageCommands(BaseDiscordClient client, ContextMenuCommandCreationProperties[] args, RequestOptions options = null) - { - Preconditions.NotNull(args, nameof(args)); - - List models = new List(); - - foreach (var arg in args) + if(args is SlashCommandProperties slashProps) { - Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - Preconditions.Equals(arg.Type, ApplicationCommandType.Message); - - var model = new CreateApplicationCommandParams() + if (slashProps.Description.IsSpecified) { - Name = arg.Name, - Type = arg.Type - }; + Preconditions.AtMost(slashProps.Description.Value.Length, 100, nameof(slashProps.Description)); + Preconditions.AtLeast(slashProps.Description.Value.Length, 1, nameof(slashProps.Description)); + } - models.Add(model); - } + if (slashProps.Options.IsSpecified) + { + if (slashProps.Options.Value.Count > 10) + throw new ArgumentException("Option count must be 10 or less"); + } - var apiModels = await client.ApiClient.BulkOverwriteGlobalApplicationMessageCommands(models.ToArray(), options); + model.Description = slashProps.Description; - return apiModels.Select(x => RestGlobalMessageCommand.Create(client, x)).ToArray(); - } - public static async Task ModifyGlobalMessageCommand(BaseDiscordClient client, RestGlobalMessageCommand command, - Action func, RequestOptions options = null) - { - ApplicationCommandProperties args = new ApplicationCommandProperties(); - func(args); + model.Options = slashProps.Options.IsSpecified + ? slashProps.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() + : Optional.Unspecified; - if (args.Name.IsSpecified) - { - Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name)); - Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name)); - } - if (args.Description.IsSpecified) - { - Preconditions.Equals(args.Description.Value, ""); + model.DefaultPermission = slashProps.DefaultPermission.IsSpecified + ? slashProps.DefaultPermission.Value + : Optional.Unspecified; } - var model = new Discord.API.Rest.ModifyApplicationCommandParams() - { - Name = args.Name, - Description = args.Description - }; - - var msg = await client.ApiClient.ModifyGlobalApplicationMessageCommandAsync(model, command.Id, options).ConfigureAwait(false); - command.Update(msg); - return command; + return await client.ApiClient.ModifyGlobalApplicationCommandAsync(model, command.Id, options).ConfigureAwait(false); } - public static async Task DeleteGlobalMessageCommand(BaseDiscordClient client, RestGlobalMessageCommand command, RequestOptions options = null) + + public static async Task DeleteGlobalCommand(BaseDiscordClient client, IApplicationCommand command, RequestOptions options = null) { Preconditions.NotNull(command, nameof(command)); Preconditions.NotEqual(command.Id, 0, nameof(command.Id)); @@ -361,197 +221,77 @@ namespace Discord.Rest } // Guild Commands - public static async Task CreateGuildCommand(BaseDiscordClient client, ulong guildId, - Action func, RequestOptions options = null) + public static async Task CreateGuildCommand(BaseDiscordClient client, ulong guildId, + Action func, RequestOptions options) where TArg : ApplicationCommandProperties { - var args = new SlashCommandCreationProperties(); - func(args); - - return await CreateGuildCommand(client, guildId, args, options).ConfigureAwait(false); + var args = Activator.CreateInstance(typeof(TArg)); + func((TArg)args); + return await CreateGuildCommand(client, guildId, (TArg)args, options); } + public static async Task CreateGuildCommand(BaseDiscordClient client, ulong guildId, - SlashCommandCreationProperties args, RequestOptions options = null) + ApplicationCommandProperties arg, RequestOptions options = null) { - Preconditions.NotNullOrEmpty(args.Name, nameof(args.Name)); - Preconditions.NotNullOrEmpty(args.Description, nameof(args.Description)); - - Preconditions.AtMost(args.Name.Length, 32, nameof(args.Name)); - Preconditions.AtLeast(args.Name.Length, 3, nameof(args.Name)); - Preconditions.AtMost(args.Description.Length, 100, nameof(args.Description)); - Preconditions.AtLeast(args.Description.Length, 1, nameof(args.Description)); - - if (args.Options.IsSpecified) - { - if (args.Options.Value.Count > 10) - throw new ArgumentException("Option count must be 10 or less"); - - foreach (var item in args.Options.Value) - { - Preconditions.NotNullOrEmpty(item.Name, nameof(item.Name)); - Preconditions.NotNullOrEmpty(item.Description, nameof(item.Description)); - } - } - var model = new CreateApplicationCommandParams() { - Name = args.Name, - Description = args.Description, - Type = args.Type, - Options = args.Options.IsSpecified - ? args.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() - : Optional.Unspecified, - DefaultPermission = args.DefaultPermission.IsSpecified - ? args.DefaultPermission.Value - : Optional.Unspecified + Name = arg.Name.Value, + Type = arg.Type, }; - var cmd = await client.ApiClient.CreateGuildApplicationCommandAsync(model, guildId, options).ConfigureAwait(false); - return RestGuildCommand.Create(client, cmd, guildId); - } - public static async Task ModifyGuildCommand(BaseDiscordClient client, RestGuildCommand command, - Action func, RequestOptions options = null) - { - ApplicationCommandProperties args = new ApplicationCommandProperties(); - func(args); - - if (args.Name.IsSpecified) - { - Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name)); - Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name)); - } - if (args.Description.IsSpecified) + if (arg is SlashCommandProperties slashProps) { - Preconditions.AtMost(args.Description.Value.Length, 100, nameof(args.Description)); - Preconditions.AtLeast(args.Description.Value.Length, 1, nameof(args.Description)); - } + Preconditions.NotNullOrEmpty(slashProps.Description, nameof(slashProps.Description)); - if (args.Options.IsSpecified) - { - if (args.Options.Value.Count > 10) - throw new ArgumentException("Option count must be 10 or less"); - } + model.Description = slashProps.Description.Value; - var model = new Discord.API.Rest.ModifyApplicationCommandParams() - { - Name = args.Name, - Description = args.Description, - Type = args.Type, - Options = args.Options.IsSpecified - ? args.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() - : Optional.Unspecified, - DefaultPermission = args.DefaultPermission.IsSpecified - ? args.DefaultPermission.Value - : Optional.Unspecified - }; - - var msg = await client.ApiClient.ModifyGuildApplicationCommandAsync(model, command.GuildId, command.Id, options).ConfigureAwait(false); - command.Update(msg); - return command; - } - - public static async Task DeleteGuildCommand(BaseDiscordClient client, ulong guildId, IApplicationCommand command, RequestOptions options = null) - { - Preconditions.NotNull(command, nameof(command)); - Preconditions.NotEqual(command.Id, 0, nameof(command.Id)); - - await client.ApiClient.DeleteGuildApplicationCommandAsync(guildId, command.Id, options).ConfigureAwait(false); - } - - public static async Task CreateGuildUserCommand(BaseDiscordClient client, ulong guildId, Action func, RequestOptions options = null) - { - var args = new ContextMenuCommandCreationProperties(); - func(args); - return await CreateGuildUserCommand(client, guildId, args, options).ConfigureAwait(false); - } + model.Options = slashProps.Options.IsSpecified + ? slashProps.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() + : Optional.Unspecified; - public static async Task CreateGuildUserCommand(BaseDiscordClient client, ulong guildId, ContextMenuCommandCreationProperties arg, RequestOptions options = null) - { - Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - - var model = new CreateApplicationCommandParams() - { - Name = arg.Name, - Type = arg.Type - }; + model.DefaultPermission = slashProps.DefaultPermission.IsSpecified + ? slashProps.DefaultPermission.Value + : Optional.Unspecified; + } - var cmd = await client.ApiClient.CreateGuildApplicationUserCommandAsync(model, guildId, options).ConfigureAwait(false); - return RestGuildUserCommand.Create(client, cmd, guildId); + var cmd = await client.ApiClient.CreateGuildApplicationCommandAsync(model, guildId, options).ConfigureAwait(false); + return RestGuildCommand.Create(client, cmd, guildId); } - public static async Task CreateGuildMessageCommand(BaseDiscordClient client, ulong guildId, Action func, RequestOptions options = null) + public static Task ModifyGuildCommand(BaseDiscordClient client, IApplicationCommand command, ulong guildId, + Action func, RequestOptions options = null) where TArg : ApplicationCommandProperties { - var args = new ContextMenuCommandCreationProperties(); - func(args); - return await CreateGuildMessageCommand(client, guildId, args, options).ConfigureAwait(false); + var arg = (TArg)Activator.CreateInstance(typeof(TArg)); + func(arg); + return ModifyGuildCommand(client, command, guildId, arg, options); } - public static async Task CreateGuildMessageCommand(BaseDiscordClient client, ulong guildId, ContextMenuCommandCreationProperties arg, RequestOptions options = null) + public static async Task ModifyGuildCommand(BaseDiscordClient client, IApplicationCommand command, ulong guildId, + ApplicationCommandProperties arg, RequestOptions options = null) { - Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - - var model = new CreateApplicationCommandParams() + var model = new ModifyApplicationCommandParams() { - Name = arg.Name, - Type = arg.Type + Name = arg.Name.Value, }; - var cmd = await client.ApiClient.CreateGuildApplicationMessageCommandAsync(model, guildId, options).ConfigureAwait(false); - return RestGuildMessageCommand.Create(client, cmd, guildId); - } - - public static async Task> BulkOverwriteGuildUserCommands(BaseDiscordClient client, ulong guildId, ContextMenuCommandCreationProperties[] args, RequestOptions options = null) - { - Preconditions.NotNull(args, nameof(args)); - - List models = new List(); - - foreach (var arg in args) + if (arg is SlashCommandProperties slashProps) { - Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - Preconditions.Equals(arg.Type, ApplicationCommandType.User); + Preconditions.NotNullOrEmpty(slashProps.Description, nameof(slashProps.Description)); - var model = new CreateApplicationCommandParams() - { - Name = arg.Name, - Type = arg.Type - }; + model.Description = slashProps.Description.Value; - models.Add(model); - } - - var apiModels = await client.ApiClient.BulkOverwriteGuildApplicationUserCommands(guildId, models.ToArray(), options); - - return apiModels.Select(x => RestGuildUserCommand.Create(client, x, guildId)).ToArray(); - } - public static async Task ModifyGuildUserCommand(BaseDiscordClient client, RestGuildUserCommand command, - Action func, RequestOptions options = null) - { - ApplicationCommandProperties args = new ApplicationCommandProperties(); - func(args); + model.Options = slashProps.Options.IsSpecified + ? slashProps.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() + : Optional.Unspecified; - if (args.Name.IsSpecified) - { - Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name)); - Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name)); - } - if (args.Description.IsSpecified) - { - Preconditions.Equals(args.Description.Value, ""); + model.DefaultPermission = slashProps.DefaultPermission.IsSpecified + ? slashProps.DefaultPermission.Value + : Optional.Unspecified; } - var model = new Discord.API.Rest.ModifyApplicationCommandParams() - { - Name = args.Name, - Description = args.Description, - Type=args.Type - }; - - var msg = await client.ApiClient.ModifyGuildApplicationUserCommandAsync(model, command.GuildId, command.Id, options).ConfigureAwait(false); - command.Update(msg); - return command; + return await client.ApiClient.ModifyGuildApplicationCommandAsync(model, guildId, command.Id, options).ConfigureAwait(false); } - public static async Task DeleteGuildUserCommand(BaseDiscordClient client, ulong guildId, RestGuildUserCommand command, RequestOptions options = null) + public static async Task DeleteGuildCommand(BaseDiscordClient client, ulong guildId, IApplicationCommand command, RequestOptions options = null) { Preconditions.NotNull(command, nameof(command)); Preconditions.NotEqual(command.Id, 0, nameof(command.Id)); @@ -559,67 +299,19 @@ namespace Discord.Rest await client.ApiClient.DeleteGuildApplicationCommandAsync(guildId, command.Id, options).ConfigureAwait(false); } - public static async Task> BulkOverwriteGuildMessageCommands(BaseDiscordClient client, ulong guildId, ContextMenuCommandCreationProperties[] args, RequestOptions options = null) + public static Task DeleteUnknownApplicationCommand(BaseDiscordClient client, ulong? guildId, IApplicationCommand command, RequestOptions options = null) { - Preconditions.NotNull(args, nameof(args)); - - List models = new List(); - - foreach (var arg in args) + if (guildId.HasValue) { - Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); - Preconditions.Equals(arg.Type, ApplicationCommandType.Message); - - var model = new CreateApplicationCommandParams() - { - Name = arg.Name, - Type = arg.Type - }; - - models.Add(model); - } - - var apiModels = await client.ApiClient.BulkOverwriteGuildApplicationMessageCommands(guildId, models.ToArray(), options); - - return apiModels.Select(x => RestGuildMessageCommand.Create(client, x, guildId)).ToArray(); - } - public static async Task ModifyGuildMessageCommand(BaseDiscordClient client, RestGuildMessageCommand command, - Action func, RequestOptions options = null) - { - ApplicationCommandProperties args = new ApplicationCommandProperties(); - func(args); - - if (args.Name.IsSpecified) - { - Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name)); - Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name)); + return DeleteGuildCommand(client, guildId.Value, command, options); } - if (args.Description.IsSpecified) + else { - Preconditions.Equals(args.Description.Value, ""); + return DeleteGlobalCommand(client, command, options); } - - var model = new Discord.API.Rest.ModifyApplicationCommandParams() - { - Name = args.Name, - Description = args.Description, - Type = args.Type - }; - - var msg = await client.ApiClient.ModifyGuildApplicationMessageCommandAsync(model, command.GuildId, command.Id, options).ConfigureAwait(false); - command.Update(msg); - return command; } - public static async Task DeleteGuildMessageCommand(BaseDiscordClient client, ulong guildId, RestGuildMessageCommand command, RequestOptions options = null) - { - Preconditions.NotNull(command, nameof(command)); - Preconditions.NotEqual(command.Id, 0, nameof(command.Id)); - - await client.ApiClient.DeleteGuildApplicationCommandAsync(guildId, command.Id, options).ConfigureAwait(false); - } - - + // Responses public static async Task ModifyFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, Action func, RequestOptions options = null) { diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs index 2744c7967..dcba1ee87 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs @@ -33,11 +33,6 @@ namespace Discord.Rest /// public IReadOnlyCollection Options { get; private set; } - /// - /// The type of this rest application command. - /// - public RestApplicationCommandType CommandType { get; internal set; } - /// public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(this.Id); @@ -48,31 +43,15 @@ namespace Discord.Rest } - internal static RestApplicationCommand Create(BaseDiscordClient client, Model model, RestApplicationCommandType type, ulong guildId = 0) + internal static RestApplicationCommand Create(BaseDiscordClient client, Model model, ulong? guildId) { - switch (type) + if (guildId.HasValue) + { + return RestGuildCommand.Create(client, model, guildId.Value); + } + else { - case RestApplicationCommandType.GlobalCommand: - return RestGlobalCommand.Create(client, model); - break; - case RestApplicationCommandType.GlobalUserCommand: - return RestGlobalUserCommand.Create(client, model); - break; - case RestApplicationCommandType.GlobalMessageCommand: - return RestGlobalMessageCommand.Create(client, model); - break; - case RestApplicationCommandType.GuildCommand: - return RestGuildCommand.Create(client, model, guildId); - break; - case RestApplicationCommandType.GuildUserCommand: - return RestGuildUserCommand.Create(client, model, guildId); - break; - case RestApplicationCommandType.GuildMessageCommand: - return RestGuildMessageCommand.Create(client, model, guildId); - break; - default: - return null; - break; + return RestGlobalCommand.Create(client, model); } } @@ -92,7 +71,9 @@ namespace Discord.Rest /// public abstract Task DeleteAsync(RequestOptions options = null); - IReadOnlyCollection IApplicationCommand.Options => Options; + /// + public abstract Task ModifyAsync(Action func, RequestOptions options = null); + IReadOnlyCollection IApplicationCommand.Options => Options; } } diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs index a8e37873e..b135ae578 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs @@ -68,7 +68,10 @@ namespace Discord.Rest : null; } - IReadOnlyCollection IApplicationCommandOption.Options => Options; - IReadOnlyCollection IApplicationCommandOption.Choices => Choices; + //IApplicationCommandOption + IReadOnlyCollection IApplicationCommandOption.Options + => Options; + IReadOnlyCollection IApplicationCommandOption.Choices + => Choices; } } diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandType.cs b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandType.cs deleted file mode 100644 index cf2fb1110..000000000 --- a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandType.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Discord.Rest -{ - /// - /// Represents a type of Rest-based command. - /// - public enum RestApplicationCommandType - { - /// - /// Specifies that this command is a Global command. - /// - GlobalCommand, - GlobalUserCommand, - GlobalMessageCommand, - - /// - /// Specifies that this command is a Guild specific command. - /// - GuildCommand, - GuildUserCommand, - GuildMessageCommand - } -} diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestGlobalCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/RestGlobalCommand.cs index 230243c7a..7e3ca0a4e 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/RestGlobalCommand.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/RestGlobalCommand.cs @@ -8,14 +8,14 @@ using Model = Discord.API.ApplicationCommand; namespace Discord.Rest { /// - /// Represents a global Slash command. + /// Represents a Rest-based global application command. /// public class RestGlobalCommand : RestApplicationCommand { internal RestGlobalCommand(BaseDiscordClient client, ulong id) : base(client, id) { - this.CommandType = RestApplicationCommandType.GlobalCommand; + } internal static RestGlobalCommand Create(BaseDiscordClient client, Model model) @@ -37,7 +37,10 @@ namespace Discord.Rest /// /// The modified command. /// - public async Task ModifyAsync(Action func, RequestOptions options = null) - => await InteractionHelper.ModifyGlobalCommand(Discord, this, func, options).ConfigureAwait(false); + public override async Task ModifyAsync(Action func, RequestOptions options = null) + { + var cmd = await InteractionHelper.ModifyGlobalCommand(Discord, this, func, options).ConfigureAwait(false); + this.Update(cmd); + } } } diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestGlobalMessageCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/RestGlobalMessageCommand.cs deleted file mode 100644 index 2c0ed222c..000000000 --- a/src/Discord.Net.Rest/Entities/Interactions/RestGlobalMessageCommand.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using Model = Discord.API.ApplicationCommand; - -namespace Discord.Rest -{ - public class RestGlobalMessageCommand : RestApplicationCommand - { - internal RestGlobalMessageCommand(BaseDiscordClient client, ulong id) - : base(client, id) - { - this.CommandType = RestApplicationCommandType.GlobalMessageCommand; -} - - internal static RestGlobalMessageCommand Create(BaseDiscordClient client, Model model) - { - var entity = new RestGlobalMessageCommand(client, model.Id); - entity.Update(model); - return entity; - } - - /// - public override async Task DeleteAsync(RequestOptions options = null) - => await InteractionHelper.DeleteGlobalMessageCommand(Discord, this).ConfigureAwait(false); - - /// - /// Modifies this . - /// - /// The delegate containing the properties to modify the command with. - /// The options to be used when sending the request. - /// - /// The modified command. - /// - public async Task ModifyAsync(Action func, RequestOptions options = null) - => await InteractionHelper.ModifyGlobalMessageCommand(Discord, this, func, options).ConfigureAwait(false); - } -} diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestGlobalUserCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/RestGlobalUserCommand.cs deleted file mode 100644 index 981686379..000000000 --- a/src/Discord.Net.Rest/Entities/Interactions/RestGlobalUserCommand.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using Model = Discord.API.ApplicationCommand; - -namespace Discord.Rest -{ - public class RestGlobalUserCommand : RestApplicationCommand - { - internal RestGlobalUserCommand(BaseDiscordClient client, ulong id) - : base(client, id) - { - this.CommandType = RestApplicationCommandType.GlobalUserCommand; - } - - internal static RestGlobalUserCommand Create(BaseDiscordClient client, Model model) - { - var entity = new RestGlobalUserCommand(client, model.Id); - entity.Update(model); - return entity; - } - - /// - public override async Task DeleteAsync(RequestOptions options = null) - => await InteractionHelper.DeleteGlobalUserCommand(Discord, this).ConfigureAwait(false); - - /// - /// Modifies this . - /// - /// The delegate containing the properties to modify the command with. - /// The options to be used when sending the request. - /// - /// The modified command. - /// - public async Task ModifyAsync(Action func, RequestOptions options = null) - => await InteractionHelper.ModifyGlobalUserCommand(Discord, this, func, options).ConfigureAwait(false); - } -} diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestGuildCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/RestGuildCommand.cs index 33ab78dbb..aa236d4b1 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/RestGuildCommand.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/RestGuildCommand.cs @@ -8,7 +8,7 @@ using Model = Discord.API.ApplicationCommand; namespace Discord.Rest { /// - /// Represents a Rest-based guild command. + /// Represents a Rest-based guild application command. /// public class RestGuildCommand : RestApplicationCommand { @@ -20,7 +20,6 @@ namespace Discord.Rest internal RestGuildCommand(BaseDiscordClient client, ulong id, ulong guildId) : base(client, id) { - this.CommandType = RestApplicationCommandType.GuildCommand; this.GuildId = guildId; } @@ -43,8 +42,11 @@ namespace Discord.Rest /// /// The modified command /// - public async Task ModifyAsync(Action func, RequestOptions options = null) - => await InteractionHelper.ModifyGuildCommand(Discord, this, func, options).ConfigureAwait(false); + public override async Task ModifyAsync(Action func, RequestOptions options = null) + { + var model = await InteractionHelper.ModifyGuildCommand(Discord, this, GuildId, func, options).ConfigureAwait(false); + this.Update(model); + } /// /// Gets this commands permissions inside of the current guild. diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestGuildMessageCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/RestGuildMessageCommand.cs deleted file mode 100644 index e057b2fe3..000000000 --- a/src/Discord.Net.Rest/Entities/Interactions/RestGuildMessageCommand.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Model = Discord.API.ApplicationCommand; - -namespace Discord.Rest -{ - /// - /// Represents a Rest-based guild command. - /// - public class RestGuildMessageCommand : RestApplicationCommand - { - /// - /// The guild Id where this command originates. - /// - public ulong GuildId { get; private set; } - - internal RestGuildMessageCommand(BaseDiscordClient client, ulong id, ulong guildId) - : base(client, id) - { - this.CommandType = RestApplicationCommandType.GuildMessageCommand; - this.GuildId = guildId; - } - - internal static RestGuildMessageCommand Create(BaseDiscordClient client, Model model, ulong guildId) - { - var entity = new RestGuildMessageCommand(client, model.Id, guildId); - entity.Update(model); - return entity; - } - - /// - public override async Task DeleteAsync(RequestOptions options = null) - => await InteractionHelper.DeleteGuildMessageCommand(Discord, GuildId, this).ConfigureAwait(false); - - /// - /// Modifies this . - /// - /// The delegate containing the properties to modify the command with. - /// The options to be used when sending the request. - /// - /// The modified command - /// - public async Task ModifyAsync(Action func, RequestOptions options = null) - => await InteractionHelper.ModifyGuildMessageCommand(Discord, this, func, options).ConfigureAwait(false); - - /// - /// Gets the guild that this slash command resides in. - /// - /// if you want the approximate member and presence counts for the guild, otherwise . - /// The options to be used when sending the request. - /// - /// A task that represents the asynchronous get operation. The task result contains a - /// . - /// - public Task GetGuild(bool withCounts = false, RequestOptions options = null) - => ClientHelper.GetGuildAsync(this.Discord, this.GuildId, withCounts, options); - } -} diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestGuildUserCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/RestGuildUserCommand.cs deleted file mode 100644 index 02dc173db..000000000 --- a/src/Discord.Net.Rest/Entities/Interactions/RestGuildUserCommand.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Model = Discord.API.ApplicationCommand; - -namespace Discord.Rest -{ - /// - /// Represents a Rest-based guild command. - /// - public class RestGuildUserCommand : RestApplicationCommand - { - /// - /// The guild Id where this command originates. - /// - public ulong GuildId { get; private set; } - - internal RestGuildUserCommand(BaseDiscordClient client, ulong id, ulong guildId) - : base(client, id) - { - this.CommandType = RestApplicationCommandType.GuildUserCommand; - this.GuildId = guildId; - } - - internal static RestGuildUserCommand Create(BaseDiscordClient client, Model model, ulong guildId) - { - var entity = new RestGuildUserCommand(client, model.Id, guildId); - entity.Update(model); - return entity; - } - - /// - public override async Task DeleteAsync(RequestOptions options = null) - => await InteractionHelper.DeleteGuildUserCommand(Discord, GuildId, this).ConfigureAwait(false); - - /// - /// Modifies this . - /// - /// The delegate containing the properties to modify the command with. - /// The options to be used when sending the request. - /// - /// The modified command - /// - public async Task ModifyAsync(Action func, RequestOptions options = null) - => await InteractionHelper.ModifyGuildUserCommand(Discord, this, func, options).ConfigureAwait(false); - - /// - /// Gets the guild that this slash command resides in. - /// - /// if you want the approximate member and presence counts for the guild, otherwise . - /// The options to be used when sending the request. - /// - /// A task that represents the asynchronous get operation. The task result contains a - /// . - /// - public Task GetGuild(bool withCounts = false, RequestOptions options = null) - => ClientHelper.GetGuildAsync(this.Discord, this.GuildId, withCounts, options); - } -} diff --git a/src/Discord.Net.WebSocket/API/Gateway/ApplicationCommandCreatedUpdatedEvent.cs b/src/Discord.Net.WebSocket/API/Gateway/ApplicationCommandCreatedUpdatedEvent.cs index 190eca89d..9d41ecf48 100644 --- a/src/Discord.Net.WebSocket/API/Gateway/ApplicationCommandCreatedUpdatedEvent.cs +++ b/src/Discord.Net.WebSocket/API/Gateway/ApplicationCommandCreatedUpdatedEvent.cs @@ -7,27 +7,9 @@ using System.Threading.Tasks; namespace Discord.API.Gateway { - internal class ApplicationCommandCreatedUpdatedEvent + internal class ApplicationCommandCreatedUpdatedEvent : API.ApplicationCommand { - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("id")] - public ulong Id { get; set; } - - [JsonProperty("description")] - public string Description { get; set; } - - [JsonProperty("application_id")] - public ulong ApplicationId { get; set; } - [JsonProperty("guild_id")] - public ulong GuildId { get; set; } - - [JsonProperty("options")] - public Optional> Options { get; set; } - - [JsonProperty("default_permission")] - public Optional DefaultPermission { get; set; } + public Optional GuildId { get; set; } } } diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml index f7137c90c..b2a823741 100644 --- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml +++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml @@ -3752,7 +3752,12 @@ - Represends a Websocket-based recieved over the gateway. + Represends a Websocket-based . + + + + + if this command is a global command, otherwise . @@ -3772,20 +3777,34 @@ - A collection of 's recieved over the gateway. + A collection of 's for this command. + + If the is not a slash command, this field will be an empty collection. + - The where this application was created. + Returns the guild this command resides in, if this command is a global command then it will return + + + Modifies the current application command. + + The new properties to use when modifying the command. + The options to be used when sending the request. + + A task that represents the asynchronous modification operation. + + Thrown when you pass in an invalid type. + Represents a choice for a . diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 52a5d309d..0da71faf2 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -1946,11 +1946,14 @@ namespace Discord.WebSocket var data = (payload as JToken).ToObject(_serializer); - var guild = State.GetGuild(data.GuildId); - if(guild == null) + if (data.GuildId.IsSpecified) { - await UnknownGuildAsync(type, data.GuildId).ConfigureAwait(false); - return; + var guild = State.GetGuild(data.GuildId.Value); + if (guild == null) + { + await UnknownGuildAsync(type, data.GuildId.Value).ConfigureAwait(false); + return; + } } var applicationCommand = SocketApplicationCommand.Create(this, data); @@ -1964,11 +1967,14 @@ namespace Discord.WebSocket var data = (payload as JToken).ToObject(_serializer); - var guild = State.GetGuild(data.GuildId); - if (guild == null) + if (data.GuildId.IsSpecified) { - await UnknownGuildAsync(type, data.GuildId).ConfigureAwait(false); - return; + var guild = State.GetGuild(data.GuildId.Value); + if (guild == null) + { + await UnknownGuildAsync(type, data.GuildId.Value).ConfigureAwait(false); + return; + } } var applicationCommand = SocketApplicationCommand.Create(this, data); @@ -1982,11 +1988,14 @@ namespace Discord.WebSocket var data = (payload as JToken).ToObject(_serializer); - var guild = State.GetGuild(data.GuildId); - if (guild == null) + if (data.GuildId.IsSpecified) { - await UnknownGuildAsync(type, data.GuildId).ConfigureAwait(false); - return; + var guild = State.GetGuild(data.GuildId.Value); + if (guild == null) + { + await UnknownGuildAsync(type, data.GuildId.Value).ConfigureAwait(false); + return; + } } var applicationCommand = SocketApplicationCommand.Create(this, data); diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs index 9f53af562..8d4a4d485 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs @@ -10,10 +10,16 @@ using Model = Discord.API.Gateway.ApplicationCommandCreatedUpdatedEvent; namespace Discord.WebSocket { /// - /// Represends a Websocket-based recieved over the gateway. + /// Represends a Websocket-based . /// public class SocketApplicationCommand : SocketEntity, IApplicationCommand { + /// + /// if this command is a global command, otherwise . + /// + public bool IsGlobalCommand + => Guild == null; + /// public ulong ApplicationId { get; private set; } @@ -30,8 +36,11 @@ namespace Discord.WebSocket public bool DefaultPermission { get; private set; } /// - /// A collection of 's recieved over the gateway. + /// A collection of 's for this command. /// + /// + /// If the is not a slash command, this field will be an empty collection. + /// public IReadOnlyCollection Options { get; private set; } /// @@ -39,32 +48,31 @@ namespace Discord.WebSocket => SnowflakeUtils.FromSnowflake(this.Id); /// - /// The where this application was created. + /// Returns the guild this command resides in, if this command is a global command then it will return /// public SocketGuild Guild - => Discord.GetGuild(this.GuildId); - private ulong GuildId { get; set; } + => GuildId.HasValue ? Discord.GetGuild(this.GuildId.Value) : null; + + private ulong? GuildId { get; set; } - internal SocketApplicationCommand(DiscordSocketClient client, ulong id) + internal SocketApplicationCommand(DiscordSocketClient client, ulong id, ulong? guildId) : base(client, id) { - + this.GuildId = guildId; } internal static SocketApplicationCommand Create(DiscordSocketClient client, Model model) { - var entity = new SocketApplicationCommand(client, model.Id); + var entity = new SocketApplicationCommand(client, model.Id, model.GuildId.ToNullable()); entity.Update(model); return entity; } - internal void Update(Model model) + internal void Update(API.ApplicationCommand model) { this.ApplicationId = model.ApplicationId; this.Description = model.Description; this.Name = model.Name; - this.GuildId = model.GuildId; - this.DefaultPermission = model.DefaultPermission.GetValueOrDefault(true); - + this.DefaultPermission = model.DefaultPermissions.GetValueOrDefault(true); this.Options = model.Options.IsSpecified ? model.Options.Value.Select(x => SocketApplicationCommandOption.Create(x)).ToImmutableArray() @@ -73,8 +81,44 @@ namespace Discord.WebSocket /// public Task DeleteAsync(RequestOptions options = null) - => InteractionHelper.DeleteGuildCommand(Discord, this.GuildId, this, options); + => InteractionHelper.DeleteUnknownApplicationCommand(Discord, this.GuildId, this, options); + + /// + /// Modifies the current application command. + /// + /// The new properties to use when modifying the command. + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous modification operation. + /// + /// Thrown when you pass in an invalid type. + public async Task ModifyAsync(Action func, RequestOptions options = null) where TArg : ApplicationCommandProperties + { + switch (typeof(TArg)) + { + case Type messageCommand when messageCommand == typeof(MessageCommandProperties) && this.Type != ApplicationCommandType.Message: + case Type slashCommand when slashCommand == typeof(SlashCommandProperties) && this.Type != ApplicationCommandType.Slash: + case Type userCommand when userCommand == typeof(UserCommandProperties) && this.Type != ApplicationCommandType.User: + throw new InvalidOperationException($"Cannot modify this application command with the parameter type {nameof(TArg)}"); + } + + API.ApplicationCommand command = null; + + if (this.IsGlobalCommand) + { + command = await InteractionHelper.ModifyGlobalCommand(Discord, this, func, options).ConfigureAwait(false); + } + else + { + command = await InteractionHelper.ModifyGuildCommand(Discord, this, this.GuildId.Value, func, options); + } + + this.Update(command); + } + // IApplicationCommand IReadOnlyCollection IApplicationCommand.Options => Options; + Task IApplicationCommand.ModifyAsync(Action func, RequestOptions options) + => ModifyAsync(func, options); } }