diff --git a/Catalogger.Backend/Bot/Responders/CustomInteractionResponder.cs b/Catalogger.Backend/Bot/Responders/CustomInteractionResponder.cs
new file mode 100644
index 0000000..b038cfe
--- /dev/null
+++ b/Catalogger.Backend/Bot/Responders/CustomInteractionResponder.cs
@@ -0,0 +1,78 @@
+// Copyright (C) 2021-present sam (starshines.gay)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+using Microsoft.Extensions.Options;
+using Remora.Commands.Services;
+using Remora.Commands.Tokenization;
+using Remora.Commands.Trees;
+using Remora.Discord.API.Abstractions.Gateway.Events;
+using Remora.Discord.API.Abstractions.Rest;
+using Remora.Discord.Commands.Responders;
+using Remora.Discord.Commands.Services;
+using Remora.Discord.Gateway.Responders;
+using Remora.Results;
+
+namespace Catalogger.Backend.Bot.Responders;
+
+///
+/// Wrapper for Remora.Discord's default interaction responder, that ignores all events if test mode is enabled.
+///
+public class CustomInteractionResponder(
+ Config config,
+ ILogger logger,
+ CommandService commandService,
+ IOptions options,
+ IDiscordRestInteractionAPI interactionAPI,
+ ExecutionEventCollectorService eventCollector,
+ IServiceProvider services,
+ ContextInjectionService contextInjection,
+ IOptions tokenizerOptions,
+ IOptions treeSearchOptions,
+ ITreeNameResolver? treeNameResolver = null
+) : IResponder
+{
+ private readonly ILogger _logger = logger.ForContext();
+
+ private readonly InteractionResponder _inner =
+ new(
+ commandService,
+ options,
+ interactionAPI,
+ eventCollector,
+ services,
+ contextInjection,
+ tokenizerOptions,
+ treeSearchOptions,
+ treeNameResolver
+ );
+
+ public async Task RespondAsync(
+ IInteractionCreate gatewayEvent,
+ CancellationToken ct = default
+ )
+ {
+ if (config.Discord.TestMode)
+ {
+ _logger.Information(
+ "Not responding to interaction create event {InteractionId} in {ChannelId} as test mode is enabled",
+ gatewayEvent.ID,
+ gatewayEvent.Channel.Map(c => c.ID).OrDefault()
+ );
+ return Result.Success;
+ }
+
+ return await _inner.RespondAsync(gatewayEvent, ct);
+ }
+}
diff --git a/Catalogger.Backend/Config.cs b/Catalogger.Backend/Config.cs
index 49bae46..2a60d6a 100644
--- a/Catalogger.Backend/Config.cs
+++ b/Catalogger.Backend/Config.cs
@@ -57,6 +57,9 @@ public class Config
public string? SupportGuild { get; init; }
public bool EnableDash { get; init; } = false;
+
+ // If enabled, nothing will be logged.
+ public bool TestMode { get; init; } = false;
}
public class WebConfig
diff --git a/Catalogger.Backend/Extensions/StartupExtensions.cs b/Catalogger.Backend/Extensions/StartupExtensions.cs
index 95c7626..621cb46 100644
--- a/Catalogger.Backend/Extensions/StartupExtensions.cs
+++ b/Catalogger.Backend/Extensions/StartupExtensions.cs
@@ -204,6 +204,11 @@ public static class StartupExtensions
var config = scope.ServiceProvider.GetRequiredService();
var slashService = scope.ServiceProvider.GetRequiredService();
+ if (config.Discord.TestMode)
+ logger.Warning(
+ "Catalogger is running in test mode. This means no logs will be sent and no commands will be responded to."
+ );
+
if (config.Discord.ApplicationId == 0)
{
logger.Warning(
diff --git a/Catalogger.Backend/Program.cs b/Catalogger.Backend/Program.cs
index 4533ce5..035d669 100644
--- a/Catalogger.Backend/Program.cs
+++ b/Catalogger.Backend/Program.cs
@@ -81,7 +81,11 @@ builder
]
);
})
- .AddDiscordCommands(enableSlash: true, useDefaultCommandResponder: false)
+ .AddDiscordCommands(
+ enableSlash: true,
+ useDefaultCommandResponder: false,
+ useDefaultInteractionResponder: false
+ )
.AddCommandTree()
// Start command tree
.WithCommandGroup()
diff --git a/Catalogger.Backend/Services/WebhookExecutorService.cs b/Catalogger.Backend/Services/WebhookExecutorService.cs
index 8cd2679..f733158 100644
--- a/Catalogger.Backend/Services/WebhookExecutorService.cs
+++ b/Catalogger.Backend/Services/WebhookExecutorService.cs
@@ -97,6 +97,15 @@ public class WebhookExecutorService(
if (channelId == 0)
return;
+ if (config.Discord.TestMode)
+ {
+ _logger.Information(
+ "Should have logged to {ChannelId}, but test mode is enabled, ignoring",
+ channelId
+ );
+ return;
+ }
+
var attachments = files
.Select>(f => f)
.ToList();