using Discord; using Discord.Interactions; using Discord.WebSocket; using System; using System.Reflection; using System.Threading.Tasks; namespace InteractionFramework { public class CommandHandler { private readonly DiscordSocketClient _client; private readonly InteractionService _commands; private readonly IServiceProvider _services; public CommandHandler(DiscordSocketClient client, InteractionService commands, IServiceProvider services) { _client = client; _commands = commands; _services = services; } public async Task InitializeAsync ( ) { // Add the public modules that inherit InteractionModuleBase<T> to the InteractionService await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); // Another approach to get the assembly of a specific type is: // typeof(CommandHandler).Assembly // Process the InteractionCreated payloads to execute Interactions commands _client.InteractionCreated += HandleInteraction; // Process the command execution results _commands.SlashCommandExecuted += SlashCommandExecuted; _commands.ContextCommandExecuted += ContextCommandExecuted; _commands.ComponentCommandExecuted += ComponentCommandExecuted; } # region Error Handling private Task ComponentCommandExecuted (ComponentCommandInfo arg1, Discord.IInteractionContext arg2, IResult arg3) { if (!arg3.IsSuccess) { switch (arg3.Error) { case InteractionCommandError.UnmetPrecondition: // implement break; case InteractionCommandError.UnknownCommand: // implement break; case InteractionCommandError.BadArgs: // implement break; case InteractionCommandError.Exception: // implement break; case InteractionCommandError.Unsuccessful: // implement break; default: break; } } return Task.CompletedTask; } private Task ContextCommandExecuted (ContextCommandInfo arg1, Discord.IInteractionContext arg2, IResult arg3) { if (!arg3.IsSuccess) { switch (arg3.Error) { case InteractionCommandError.UnmetPrecondition: // implement break; case InteractionCommandError.UnknownCommand: // implement break; case InteractionCommandError.BadArgs: // implement break; case InteractionCommandError.Exception: // implement break; case InteractionCommandError.Unsuccessful: // implement break; default: break; } } return Task.CompletedTask; } private Task SlashCommandExecuted (SlashCommandInfo arg1, Discord.IInteractionContext arg2, IResult arg3) { if (!arg3.IsSuccess) { switch (arg3.Error) { case InteractionCommandError.UnmetPrecondition: // implement break; case InteractionCommandError.UnknownCommand: // implement break; case InteractionCommandError.BadArgs: // implement break; case InteractionCommandError.Exception: // implement break; case InteractionCommandError.Unsuccessful: // implement break; default: break; } } return Task.CompletedTask; } # endregion # region Execution private async Task HandleInteraction (SocketInteraction arg) { try { // Create an execution context that matches the generic type parameter of your InteractionModuleBase<T> modules var ctx = new SocketInteractionContext(_client, arg); await _commands.ExecuteCommandAsync(ctx, _services); } catch (Exception ex) { Console.WriteLine(ex); // If a Slash Command execution fails it is most likely that the original interaction acknowledgement will persist. It is a good idea to delete the original // response, or at least let the user know that something went wrong during the command execution. if(arg.Type == InteractionType.ApplicationCommand) await arg.GetOriginalResponseAsync().ContinueWith(async (msg) => await msg.Result.DeleteAsync()); } } # endregion } }