From 58559018e510ab6a6b52cc854e1e7b913f08c8b0 Mon Sep 17 00:00:00 2001 From: Cenk Ergen <57065323+Cenngo@users.noreply.github.com> Date: Sun, 28 Nov 2021 20:49:26 +0300 Subject: [PATCH] add methods for manually registering global comands --- .../InteractionService.cs | 87 ++++++++++++++++--- 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/src/Discord.Net.Interactions/InteractionService.cs b/src/Discord.Net.Interactions/InteractionService.cs index 510a5952d..8e2c672a2 100644 --- a/src/Discord.Net.Interactions/InteractionService.cs +++ b/src/Discord.Net.Interactions/InteractionService.cs @@ -358,22 +358,20 @@ public async Task> RegisterCommandsGlobal /// /// /// Commands will be registered as standalone commands, if you want the to take effect, - /// use . + /// use . Registering a commands without group names might cause the command traversal to fail. /// /// The target guild. /// Commands to be registered to Discord. /// /// A task representing the command registration process. The task result contains the active application commands of the target guild. /// - public async Task> AddCommandsToGuildAsync (IGuild guild, params IApplicationCommandInfo[] commands) + public async Task> AddCommandsToGuildAsync(IGuild guild, bool deleteMissing = false, params ICommandInfo[] commands) { EnsureClientReady(); if (guild is null) throw new ArgumentNullException(nameof(guild)); - var existing = await RestClient.GetGuildApplicationCommands(guild.Id).ConfigureAwait(false); - var props = new List(); foreach (var command in commands) @@ -391,9 +389,10 @@ public async Task> AddCommandsToGuildAsync } } - if (existing != null) + if (!deleteMissing) { - var missing = existing.Where(oldCommand => !props.Any(newCommand => newCommand.Name.IsSpecified && newCommand.Name.Value == oldCommand.Name)); + var existing = await RestClient.GetGuildApplicationCommands(guild.Id).ConfigureAwait(false); + var missing = existing.Where(x => !props.Any(y => y.Name.IsSpecified && y.Name.Value == x.Name)); props.AddRange(missing.Select(x => x.ToApplicationCommandProps())); } @@ -408,22 +407,90 @@ public async Task> AddCommandsToGuildAsync /// /// A task representing the command registration process. The task result contains the active application commands of the target guild. /// - public async Task> AddModulesToGuildAsync (IGuild guild, params ModuleInfo[] modules) + public async Task> AddModulesToGuildAsync(IGuild guild, bool deleteMissing = false, params ModuleInfo[] modules) { EnsureClientReady(); if (guild is null) throw new ArgumentNullException(nameof(guild)); - var existing = await RestClient.GetGuildApplicationCommands(guild.Id).ConfigureAwait(false); var props = modules.SelectMany(x => x.ToApplicationCommandProps(true)).ToList(); - foreach (var command in existing) - props.Add(command.ToApplicationCommandProps()); + if (!deleteMissing) + { + var existing = await RestClient.GetGuildApplicationCommands(guild.Id).ConfigureAwait(false); + var missing = existing.Where(x => !props.Any(y => y.Name.IsSpecified && y.Name.Value == x.Name)); + props.AddRange(missing.Select(x => x.ToApplicationCommandProps())); + } return await RestClient.BulkOverwriteGuildCommands(props.ToArray(), guild.Id).ConfigureAwait(false); } + /// + /// Register Application Commands from modules provided in as global commands. + /// + /// Modules to be registered to Discord. + /// + /// A task representing the command registration process. The task result contains the active application commands of the target guild. + /// + public async Task> AddModulesGloballyAsync(bool deleteMissing = false, params ModuleInfo[] modules) + { + EnsureClientReady(); + + var props = modules.SelectMany(x => x.ToApplicationCommandProps(true)).ToList(); + + if (!deleteMissing) + { + var existing = await RestClient.GetGlobalApplicationCommands().ConfigureAwait(false); + var missing = existing.Where(x => !props.Any(y => y.Name.IsSpecified && y.Name.Value == x.Name)); + props.AddRange(missing.Select(x => x.ToApplicationCommandProps())); + } + + return await RestClient.BulkOverwriteGlobalCommands(props.ToArray()).ConfigureAwait(false); + } + + /// + /// Register Application Commands from as global commands. + /// + /// + /// Commands will be registered as standalone commands, if you want the to take effect, + /// use . Registering a commands without group names might cause the command traversal to fail. + /// + /// Commands to be registered to Discord. + /// + /// A task representing the command registration process. The task result contains the active application commands of the target guild. + /// + public async Task> AddCommandsGloballyAsync(bool deleteMissing = false, params IApplicationCommandInfo[] commands) + { + EnsureClientReady(); + + var props = new List(); + + foreach (var command in commands) + { + switch (command) + { + case SlashCommandInfo slashCommand: + props.Add(slashCommand.ToApplicationCommandProps()); + break; + case ContextCommandInfo contextCommand: + props.Add(contextCommand.ToApplicationCommandProps()); + break; + default: + throw new InvalidOperationException($"Command type {command.GetType().FullName} isn't supported yet"); + } + } + + if (!deleteMissing) + { + var existing = await RestClient.GetGlobalApplicationCommands().ConfigureAwait(false); + var missing = existing.Where(x => !props.Any(y => y.Name.IsSpecified && y.Name.Value == x.Name)); + props.AddRange(missing.Select(x => x.ToApplicationCommandProps())); + } + + return await RestClient.BulkOverwriteGlobalCommands(props.ToArray()).ConfigureAwait(false); + } + private void LoadModuleInternal (ModuleInfo module) { _moduleDefs.Add(module);