diff --git a/PluralKit.Bot/Services/LoggerCleanService.cs b/PluralKit.Bot/Services/LoggerCleanService.cs index 29563335..ce71bd19 100644 --- a/PluralKit.Bot/Services/LoggerCleanService.cs +++ b/PluralKit.Bot/Services/LoggerCleanService.cs @@ -8,6 +8,7 @@ using Dapper; using DSharpPlus; using DSharpPlus.Entities; +using DSharpPlus.Exceptions; using PluralKit.Core; @@ -78,44 +79,55 @@ namespace PluralKit.Bot // If we didn't find anything before, or what we found is an unsupported bot, bail if (bot == null) return; - // We try two ways of extracting the actual message, depending on the bots - if (bot.FuzzyExtractFunc != null) + try { - // Some bots (Carl, Circle, etc) only give us a user ID and a rough timestamp, so we try our best to - // "cross-reference" those with the message DB. We know the deletion event happens *after* the message - // was sent, so we're checking for any messages sent in the same guild within 3 seconds before the - // delete event timestamp, which is... good enough, I think? Potential for false positives and negatives - // either way but shouldn't be too much, given it's constrained by user ID and guild. - var fuzzy = bot.FuzzyExtractFunc(msg); - if (fuzzy == null) return; + // We try two ways of extracting the actual message, depending on the bots + if (bot.FuzzyExtractFunc != null) + { + // Some bots (Carl, Circle, etc) only give us a user ID and a rough timestamp, so we try our best to + // "cross-reference" those with the message DB. We know the deletion event happens *after* the message + // was sent, so we're checking for any messages sent in the same guild within 3 seconds before the + // delete event timestamp, which is... good enough, I think? Potential for false positives and negatives + // either way but shouldn't be too much, given it's constrained by user ID and guild. + var fuzzy = bot.FuzzyExtractFunc(msg); + if (fuzzy == null) return; - using var conn = await _db.Obtain(); - var mid = await conn.QuerySingleOrDefaultAsync( - "select mid from messages where sender = @User and mid > @ApproxID and guild = @Guild limit 1", - new - { - fuzzy.Value.User, - Guild = msg.Channel.GuildId, - ApproxId = DiscordUtils.InstantToSnowflake(fuzzy.Value.ApproxTimestamp - TimeSpan.FromSeconds(3)) - }); - if (mid == null) return; // If we didn't find a corresponding message, bail - // Otherwise, we can *reasonably assume* that this is a logged deletion, so delete the log message. - await msg.DeleteAsync(); + using var conn = await _db.Obtain(); + var mid = await conn.QuerySingleOrDefaultAsync( + "select mid from messages where sender = @User and mid > @ApproxID and guild = @Guild limit 1", + new + { + fuzzy.Value.User, + Guild = msg.Channel.GuildId, + ApproxId = DiscordUtils.InstantToSnowflake( + fuzzy.Value.ApproxTimestamp - TimeSpan.FromSeconds(3)) + }); + if (mid == null) return; // If we didn't find a corresponding message, bail + // Otherwise, we can *reasonably assume* that this is a logged deletion, so delete the log message. + await msg.DeleteAsync(); + } + else if (bot.ExtractFunc != null) + { + // Other bots give us the message ID itself, and we can just extract that from the database directly. + var extractedId = bot.ExtractFunc(msg); + if (extractedId == null) return; // If we didn't find anything, bail. + + using var conn = await _db.Obtain(); + // We do this through an inline query instead of through DataStore since we don't need all the joins it does + var mid = await conn.QuerySingleOrDefaultAsync( + "select mid from messages where original_mid = @Mid", new {Mid = extractedId.Value}); + if (mid == null) return; + + // If we've gotten this far, we found a logged deletion of a trigger message. Just yeet it! + await msg.DeleteAsync(); + } // else should not happen, but idk, it might } - else if (bot.ExtractFunc != null) + catch (NotFoundException) { - // Other bots give us the message ID itself, and we can just extract that from the database directly. - var extractedId = bot.ExtractFunc(msg); - if (extractedId == null) return; // If we didn't find anything, bail. - - using var conn = await _db.Obtain(); - // We do this through an inline query instead of through DataStore since we don't need all the joins it does - var mid = await conn.QuerySingleOrDefaultAsync("select mid from messages where original_mid = @Mid", new {Mid = extractedId.Value}); - if (mid == null) return; - - // If we've gotten this far, we found a logged deletion of a trigger message. Just yeet it! - await msg.DeleteAsync(); - } // else should not happen, but idk, it might + // Sort of a temporary measure: getting an error in Sentry about a NotFoundException from D#+ here + // The only thing I can think of that'd cause this are the DeleteAsync() calls which 404 when + // the message doesn't exist anyway - so should be safe to just ignore it, right? + } } private static ulong? ExtractAuttaja(DiscordMessage msg)