diff --git a/Hosting/NetCord.Hosting.Services/ApplicationCommands/ApplicationCommandInteractionHandler.cs b/Hosting/NetCord.Hosting.Services/ApplicationCommands/ApplicationCommandInteractionHandler.cs index 37252124..57b8ccae 100644 --- a/Hosting/NetCord.Hosting.Services/ApplicationCommands/ApplicationCommandInteractionHandler.cs +++ b/Hosting/NetCord.Hosting.Services/ApplicationCommands/ApplicationCommandInteractionHandler.cs @@ -48,7 +48,7 @@ public ApplicationCommandInteractionHandler(IServiceProvider services, _handleAsync = &HandleInteractionAsync; _createContext = optionsValue.CreateContext ?? ContextHelper.CreateContextDelegate(_applicationCommandService.Configuration.ServiceResolverProvider); - _resultHandler = optionsValue.ResultHandler ?? new ApplicationCommandResultHandler(); + _resultHandler = optionsValue.ResultHandler ?? ApplicationCommandResultHandler.Default; _preExecutionHandler = optionsValue.PreExecutionHandler ?? new ApplicationCommandPreExecutionHandler(); _client = client; } diff --git a/Hosting/NetCord.Hosting.Services/ApplicationCommands/ApplicationCommandResultHandler.cs b/Hosting/NetCord.Hosting.Services/ApplicationCommands/ApplicationCommandResultHandler.cs index d1a43fe6..359db5ed 100644 --- a/Hosting/NetCord.Hosting.Services/ApplicationCommands/ApplicationCommandResultHandler.cs +++ b/Hosting/NetCord.Hosting.Services/ApplicationCommands/ApplicationCommandResultHandler.cs @@ -7,30 +7,53 @@ namespace NetCord.Hosting.Services.ApplicationCommands; -public class ApplicationCommandResultHandler(MessageFlags? messageFlags = null) - : IApplicationCommandResultHandler +public class ApplicationCommandResultHandler : IApplicationCommandResultHandler where TContext : IApplicationCommandContext { - public ValueTask HandleResultAsync(IExecutionResult result, TContext context, GatewayClient? client, ILogger logger, IServiceProvider services) + public static ApplicationCommandResultHandler Default => new(); + + public static ApplicationCommandResultHandler Ephemeral => new EphemeralApplicationCommandResultHandler(); + + protected ApplicationCommandResultHandler() { - if (result is not IFailResult failResult) - return default; + } + + private sealed class EphemeralApplicationCommandResultHandler : ApplicationCommandResultHandler + { + public override ValueTask GetFailMessageAsync(IFailResult failResult, TContext context, IServiceProvider services) + { + return new(new InteractionMessageProperties + { + Content = failResult.Message, + Flags = MessageFlags.Ephemeral, + }); + } + } - var resultMessage = failResult.Message; + public async ValueTask HandleResultAsync(IExecutionResult result, TContext context, GatewayClient? client, ILogger logger, IServiceProvider services) + { + if (result is not IFailResult failResult) + return; var interaction = context.Interaction; + var commandName = interaction.Data.Name; + if (failResult is IExceptionResult exceptionResult) - logger.LogError(exceptionResult.Exception, "Execution of an application command of name '{Name}' failed with an exception", interaction.Data.Name); + logger.LogError(exceptionResult.Exception, "Execution of an application command of name '{Name}' failed with an exception", commandName); else - logger.LogDebug("Execution of an application command of name '{Name}' failed with '{Message}'", interaction.Data.Name, resultMessage); + logger.LogDebug("Execution of an application command of name '{Name}' failed with '{Message}'", commandName, failResult.Message); - InteractionMessageProperties message = new() - { - Content = resultMessage, - Flags = messageFlags, - }; + var response = await GetFailMessageAsync(failResult, context, services).ConfigureAwait(false); - return new(interaction.SendResponseAsync(InteractionCallback.Message(message))); + await interaction.SendResponseAsync(InteractionCallback.Message(response)).ConfigureAwait(false); + } + + public virtual ValueTask GetFailMessageAsync(IFailResult failResult, TContext context, IServiceProvider services) + { + return new(new InteractionMessageProperties + { + Content = failResult.Message, + }); } } diff --git a/Hosting/NetCord.Hosting.Services/Commands/CommandHandler.cs b/Hosting/NetCord.Hosting.Services/Commands/CommandHandler.cs index af89d1e4..fb112655 100644 --- a/Hosting/NetCord.Hosting.Services/Commands/CommandHandler.cs +++ b/Hosting/NetCord.Hosting.Services/Commands/CommandHandler.cs @@ -49,7 +49,7 @@ public CommandHandler(IServiceProvider services, _getCommandTextAsync = GetGetCommandTextAsyncDelegate(optionsValue); _createContext = optionsValue.CreateContext ?? ContextHelper.CreateContextDelegate(_commandService.Configuration.ServiceResolverProvider); - _resultHandler = optionsValue.ResultHandler ?? new CommandResultHandler(); + _resultHandler = optionsValue.ResultHandler ?? CommandResultHandler.Default; _preExecutionHandler = optionsValue.PreExecutionHandler ?? new CommandPreExecutionHandler(); _client = client; } diff --git a/Hosting/NetCord.Hosting.Services/Commands/CommandResultHandler.cs b/Hosting/NetCord.Hosting.Services/Commands/CommandResultHandler.cs index cec72244..5df9d17a 100644 --- a/Hosting/NetCord.Hosting.Services/Commands/CommandResultHandler.cs +++ b/Hosting/NetCord.Hosting.Services/Commands/CommandResultHandler.cs @@ -1,33 +1,46 @@ using Microsoft.Extensions.Logging; using NetCord.Gateway; +using NetCord.Rest; using NetCord.Services; using NetCord.Services.Commands; namespace NetCord.Hosting.Services.Commands; -public class CommandResultHandler(MessageFlags? messageFlags = null) : ICommandResultHandler +public class CommandResultHandler : ICommandResultHandler where TContext : ICommandContext { - public ValueTask HandleResultAsync(IExecutionResult result, TContext context, GatewayClient client, ILogger logger, IServiceProvider services) + public static CommandResultHandler Default => new(); + + protected CommandResultHandler() { - if (result is not IFailResult failResult) - return default; + } - var resultMessage = failResult.Message; + public async ValueTask HandleResultAsync(IExecutionResult result, TContext context, GatewayClient client, ILogger logger, IServiceProvider services) + { + if (result is not IFailResult failResult) + return; var message = context.Message; + var messageContent = message.Content; + if (failResult is IExceptionResult exceptionResult) - logger.LogError(exceptionResult.Exception, "Execution of a command with content '{Content}' failed with an exception", message.Content); + logger.LogError(exceptionResult.Exception, "Execution of a command with content '{Content}' failed with an exception", messageContent); else - logger.LogDebug("Execution of a command with content '{Content}' failed with '{Message}'", message.Content, resultMessage); + logger.LogDebug("Execution of a command with content '{Content}' failed with '{Message}'", messageContent, failResult.Message); + + var response = await GetFailMessage(failResult, context, services).ConfigureAwait(false); - return new(message.ReplyAsync(new() + await message.SendAsync(response).ConfigureAwait(false); + } + + public virtual ValueTask GetFailMessage(IFailResult failResult, TContext context, IServiceProvider services) + { + return new(new MessageProperties { - Content = resultMessage, - FailIfNotExists = false, - Flags = messageFlags, - })); + MessageReference = MessageReferenceProperties.Reply(context.Message.Id, false), + Content = failResult.Message, + }); } } diff --git a/Hosting/NetCord.Hosting.Services/ComponentInteractions/ComponentInteractionHandler.cs b/Hosting/NetCord.Hosting.Services/ComponentInteractions/ComponentInteractionHandler.cs index 7dd5d755..3c80ef02 100644 --- a/Hosting/NetCord.Hosting.Services/ComponentInteractions/ComponentInteractionHandler.cs +++ b/Hosting/NetCord.Hosting.Services/ComponentInteractions/ComponentInteractionHandler.cs @@ -49,7 +49,7 @@ public ComponentInteractionHandler(IServiceProvider services, _handleAsync = &HandleInteractionAsync; _createContext = optionsValue.CreateContext ?? ContextHelper.CreateContextDelegate(_componentInteractionService.Configuration.ServiceResolverProvider); - _resultHandler = optionsValue.ResultHandler ?? new ComponentInteractionResultHandler(); + _resultHandler = optionsValue.ResultHandler ?? ComponentInteractionResultHandler.Default; _preExecutionHandler = optionsValue.PreExecutionHandler ?? new ComponentInteractionPreExecutionHandler(); _client = client; } diff --git a/Hosting/NetCord.Hosting.Services/ComponentInteractions/ComponentInteractionResultHandler.cs b/Hosting/NetCord.Hosting.Services/ComponentInteractions/ComponentInteractionResultHandler.cs index 8f86a382..c5e4d4a7 100644 --- a/Hosting/NetCord.Hosting.Services/ComponentInteractions/ComponentInteractionResultHandler.cs +++ b/Hosting/NetCord.Hosting.Services/ComponentInteractions/ComponentInteractionResultHandler.cs @@ -7,29 +7,53 @@ namespace NetCord.Hosting.Services.ComponentInteractions; -public class ComponentInteractionResultHandler(MessageFlags? messageFlags = null) : IComponentInteractionResultHandler +public class ComponentInteractionResultHandler : IComponentInteractionResultHandler where TContext : IComponentInteractionContext { - public ValueTask HandleResultAsync(IExecutionResult result, TContext context, GatewayClient? client, ILogger logger, IServiceProvider services) + public static ComponentInteractionResultHandler Default => new(); + + public static ComponentInteractionResultHandler Ephemeral => new EphemeralComponentInteractionResultHandler(); + + protected ComponentInteractionResultHandler() { - if (result is not IFailResult failResult) - return default; + } + + private sealed class EphemeralComponentInteractionResultHandler : ComponentInteractionResultHandler + { + public override ValueTask GetFailMessageAsync(IFailResult failResult, TContext context, IServiceProvider services) + { + return new(new InteractionMessageProperties + { + Content = failResult.Message, + Flags = MessageFlags.Ephemeral, + }); + } + } - var resultMessage = failResult.Message; + public async ValueTask HandleResultAsync(IExecutionResult result, TContext context, GatewayClient? client, ILogger logger, IServiceProvider services) + { + if (result is not IFailResult failResult) + return; var interaction = context.Interaction; + var customId = interaction.Data.CustomId; + if (failResult is IExceptionResult exceptionResult) - logger.LogError(exceptionResult.Exception, "Execution of an interaction of custom ID '{Id}' failed with an exception", interaction.Data.CustomId); + logger.LogError(exceptionResult.Exception, "Execution of an interaction of custom ID '{Id}' failed with an exception", customId); else - logger.LogDebug("Execution of an interaction of custom ID '{Id}' failed with '{Message}'", interaction.Data.CustomId, resultMessage); + logger.LogDebug("Execution of an interaction of custom ID '{Id}' failed with '{Message}'", customId, failResult.Message); - InteractionMessageProperties message = new() - { - Content = resultMessage, - Flags = messageFlags, - }; + var response = await GetFailMessageAsync(failResult, context, services).ConfigureAwait(false); - return new(interaction.SendResponseAsync(InteractionCallback.Message(message))); + await interaction.SendResponseAsync(InteractionCallback.Message(response)).ConfigureAwait(false); + } + + public virtual ValueTask GetFailMessageAsync(IFailResult failResult, TContext context, IServiceProvider services) + { + return new(new InteractionMessageProperties + { + Content = failResult.Message, + }); } } diff --git a/Tests/NetCord.Test.Hosting/CustomApplicationCommandResultHandler.cs b/Tests/NetCord.Test.Hosting/CustomApplicationCommandResultHandler.cs index 8e42f8d0..5b08db80 100644 --- a/Tests/NetCord.Test.Hosting/CustomApplicationCommandResultHandler.cs +++ b/Tests/NetCord.Test.Hosting/CustomApplicationCommandResultHandler.cs @@ -9,7 +9,7 @@ namespace NetCord.Test.Hosting; internal class CustomApplicationCommandResultHandler : IApplicationCommandResultHandler { - private static readonly ApplicationCommandResultHandler _defaultHandler = new(MessageFlags.Ephemeral); + private static readonly ApplicationCommandResultHandler _defaultHandler = ApplicationCommandResultHandler.Ephemeral; public ValueTask HandleResultAsync(IExecutionResult result, ApplicationCommandContext context, GatewayClient? client, ILogger logger, IServiceProvider services) {