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 @@ namespace Discord.Interactions
///
///
/// 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 @@ namespace Discord.Interactions
}
}
- 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 @@ namespace Discord.Interactions
///
/// 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);