Allow Interaction Commands to run for up to 15 minutes by replying to discord immediately and handling the command in a separate thread
This commit is contained in:
parent
699a93200b
commit
17cb5951ee
4 changed files with 43 additions and 16 deletions
|
@ -7,6 +7,6 @@ namespace Geekbot.Interactions
|
|||
public interface IInteractionCommandManager
|
||||
{
|
||||
Dictionary<string, Command> CommandsInfo { get; init; }
|
||||
Task<InteractionResponse> RunCommand(Interaction interaction);
|
||||
InteractionResponse? RunCommand(Interaction interaction);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using Geekbot.Core;
|
||||
using Geekbot.Core.GuildSettingsManager;
|
||||
using Geekbot.Core.Logger;
|
||||
using Geekbot.Interactions.ApplicationCommand;
|
||||
using Geekbot.Interactions.Request;
|
||||
using Geekbot.Interactions.Response;
|
||||
|
@ -14,6 +16,8 @@ namespace Geekbot.Interactions
|
|||
|
||||
private readonly IGuildSettingsManager _guildSettingsManager;
|
||||
|
||||
private readonly IGeekbotLogger _logger;
|
||||
|
||||
private readonly Dictionary<CommandType, Dictionary<string, Type>> _commands = new() {
|
||||
{ CommandType.Message, new Dictionary<string, Type>() },
|
||||
{ CommandType.User, new Dictionary<string, Type>() },
|
||||
|
@ -22,10 +26,12 @@ namespace Geekbot.Interactions
|
|||
|
||||
public Dictionary<string, Command> CommandsInfo { get; init; }
|
||||
|
||||
public InteractionCommandManager(IServiceProvider provider, IGuildSettingsManager guildSettingsManager)
|
||||
public InteractionCommandManager(IServiceProvider provider, IGuildSettingsManager guildSettingsManager, IGeekbotLogger logger)
|
||||
{
|
||||
_provider = provider;
|
||||
_guildSettingsManager = guildSettingsManager;
|
||||
_logger = logger;
|
||||
|
||||
var interactions = Assembly.GetCallingAssembly()
|
||||
.GetTypes()
|
||||
.Where(type => type.IsClass && !type.IsAbstract && type.IsSubclassOf(typeof(InteractionBase)))
|
||||
|
@ -42,16 +48,8 @@ namespace Geekbot.Interactions
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<InteractionResponse> RunCommand(Interaction interaction)
|
||||
private async Task HandleInteraction(Interaction interaction, InteractionBase command)
|
||||
{
|
||||
var type = _commands[interaction.Data.Type][interaction.Data.Name];
|
||||
var command = ActivatorUtilities.CreateInstance(_provider, type) as InteractionBase;
|
||||
|
||||
if (command == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var guildSettings = _guildSettingsManager.GetSettings(ulong.Parse(interaction.GuildId));
|
||||
var language = guildSettings.Language;
|
||||
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(language);
|
||||
|
@ -72,7 +70,36 @@ namespace Geekbot.Interactions
|
|||
command.AfterExecute(interaction);
|
||||
}
|
||||
|
||||
return response;
|
||||
try
|
||||
{
|
||||
await HttpAbstractions.Patch(
|
||||
new Uri($"https://discord.com/api/v8/webhooks/{interaction.ApplicationId}/{interaction.Token}/messages/@original"),
|
||||
response.Data
|
||||
);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(LogSource.Interaction, "Failed to send interaction response", e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public InteractionResponse? RunCommand(Interaction interaction)
|
||||
{
|
||||
var type = _commands[interaction.Data.Type][interaction.Data.Name];
|
||||
var command = ActivatorUtilities.CreateInstance(_provider, type) as InteractionBase;
|
||||
|
||||
if (command == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Task.Run(() => HandleInteraction(interaction, command).ConfigureAwait(false));
|
||||
|
||||
return new InteractionResponse()
|
||||
{
|
||||
Type = InteractionResponseType.DeferredChannelMessageWithSource
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ public class InteractionController : ControllerBase
|
|||
return (interaction.Type, interaction.Version) switch
|
||||
{
|
||||
(InteractionType.Ping, 1) => Ping(),
|
||||
(InteractionType.ApplicationCommand, 1) => await ApplicationCommand(interaction),
|
||||
(InteractionType.ApplicationCommand, 1) => ApplicationCommand(interaction),
|
||||
(InteractionType.MessageComponent, 1) => MessageComponent(interaction),
|
||||
_ => StatusCode(501)
|
||||
};
|
||||
|
@ -64,9 +64,9 @@ public class InteractionController : ControllerBase
|
|||
return Ok(response);
|
||||
}
|
||||
|
||||
private async Task<IActionResult> ApplicationCommand(Interaction interaction)
|
||||
private IActionResult ApplicationCommand(Interaction interaction)
|
||||
{
|
||||
var result = await _interactionCommandManager.RunCommand(interaction);
|
||||
var result = _interactionCommandManager.RunCommand(interaction);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ public static class WebApiStartup
|
|||
builder.Services.AddControllers();
|
||||
builder.Services.AddCors(options => options.AddPolicy("AllowSpecificOrigin", cors => cors.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
|
||||
|
||||
var interactionCommandManager = new InteractionCommandManager(commandProvider, commandProvider.GetService<IGuildSettingsManager>());
|
||||
var interactionCommandManager = new InteractionCommandManager(commandProvider, commandProvider.GetService<IGuildSettingsManager>(), logger);
|
||||
var highscoreManager = new HighscoreManager(commandProvider.GetService<DatabaseContext>(), commandProvider.GetService<IUserRepository>());
|
||||
|
||||
builder.Services.AddSingleton(databaseContext);
|
||||
|
|
Loading…
Reference in a new issue