using Discord; using Discord.Interactions; using Discord.WebSocket; using Microsoft.Extensions.Configuration; using System; using System.Reflection; using System.Threading.Tasks; namespace InteractionFramework { public class InteractionHandler { private readonly DiscordSocketClient _client; private readonly InteractionService _handler; private readonly IServiceProvider _services; private readonly IConfiguration _configuration; public InteractionHandler(DiscordSocketClient client, InteractionService handler, IServiceProvider services, IConfiguration config) { _client = client; _handler = handler; _services = services; _configuration = config; } public async Task InitializeAsync() { // Process when the client is ready, so we can register our commands. _client.Ready += ReadyAsync; _handler.Log += LogAsync; // Add the public modules that inherit InteractionModuleBase<T> to the InteractionService await _handler.AddModulesAsync(Assembly.GetEntryAssembly(), _services); // Process the InteractionCreated payloads to execute Interactions commands _client.InteractionCreated += HandleInteraction; } private async Task LogAsync(LogMessage log) => Console.WriteLine(log); private async Task ReadyAsync() { // Context & Slash commands can be automatically registered, but this process needs to happen after the client enters the READY state. // Since Global Commands take around 1 hour to register, we should use a test guild to instantly update and test our commands. if (Program.IsDebug()) await _handler.RegisterCommandsToGuildAsync(_configuration.GetValue<ulong>("testGuild"), true); else await _handler.RegisterCommandsGloballyAsync(true); } private async Task HandleInteraction(SocketInteraction interaction) { try { // Create an execution context that matches the generic type parameter of your InteractionModuleBase<T> modules. var context = new SocketInteractionContext(_client, interaction); // Execute the incoming command. var result = await _handler.ExecuteCommandAsync(context, _services); if (!result.IsSuccess) switch (result.Error) { case InteractionCommandError.UnmetPrecondition: // implement break; default: break; } } catch { // If 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 (interaction.Type is InteractionType.ApplicationCommand) await interaction.GetOriginalResponseAsync().ContinueWith(async (msg) => await msg.Result.DeleteAsync()); } } } }