diff --git a/src/Responders/GuildUnloadedResponder.cs b/src/Responders/GuildUnloadedResponder.cs
new file mode 100644
index 0000000..0cffe25
--- /dev/null
+++ b/src/Responders/GuildUnloadedResponder.cs
@@ -0,0 +1,38 @@
+using JetBrains.Annotations;
+using Microsoft.Extensions.Logging;
+using Octobot.Data;
+using Octobot.Services;
+using Remora.Discord.API.Abstractions.Gateway.Events;
+using Remora.Discord.Gateway.Responders;
+using Remora.Results;
+
+namespace Octobot.Responders;
+
+///
+/// Handles removing guild ID from if the guild becomes unavailable.
+///
+[UsedImplicitly]
+public class GuildUnloadedResponder : IResponder
+{
+ private readonly GuildDataService _guildData;
+ private readonly ILogger _logger;
+
+ public GuildUnloadedResponder(
+ GuildDataService guildData, ILogger logger)
+ {
+ _guildData = guildData;
+ _logger = logger;
+ }
+
+ public Task RespondAsync(IGuildDelete gatewayEvent, CancellationToken ct = default)
+ {
+ var guildId = gatewayEvent.ID;
+ var isDataRemoved = _guildData.UnloadGuildData(guildId);
+ if (isDataRemoved)
+ {
+ _logger.LogInformation("Left guild {GuildId}", guildId);
+ }
+
+ return Task.FromResult(Result.FromSuccess());
+ }
+}
diff --git a/src/Services/GuildDataService.cs b/src/Services/GuildDataService.cs
index f5c7faa..73d4a25 100644
--- a/src/Services/GuildDataService.cs
+++ b/src/Services/GuildDataService.cs
@@ -142,4 +142,9 @@ public sealed class GuildDataService : IHostedService
{
return _datas.Keys;
}
+
+ public bool UnloadGuildData(Snowflake id)
+ {
+ return _datas.TryRemove(id, out _);
+ }
}