From 5c055871e3cb76e77ac584caefb34ec87e00096a Mon Sep 17 00:00:00 2001 From: spiral Date: Sun, 19 Jun 2022 20:28:55 -0400 Subject: [PATCH] feat(bot): store command message info in redis --- .../CommandSystem/Context/Context.cs | 8 ++--- PluralKit.Bot/Commands/Message.cs | 10 +++--- PluralKit.Bot/Handlers/ReactionAdded.cs | 10 +++--- .../Services/CommandMessageService.cs | 26 ++++++++------ .../ModelRepository.CommandMessage.cs | 36 ------------------- PluralKit.ScheduledTasks/TaskHandler.cs | 16 --------- 6 files changed, 31 insertions(+), 75 deletions(-) delete mode 100644 PluralKit.Core/Database/Repository/ModelRepository.CommandMessage.cs diff --git a/PluralKit.Bot/CommandSystem/Context/Context.cs b/PluralKit.Bot/CommandSystem/Context/Context.cs index 9efc7511..3a0fb4be 100644 --- a/PluralKit.Bot/CommandSystem/Context/Context.cs +++ b/PluralKit.Bot/CommandSystem/Context/Context.cs @@ -94,12 +94,12 @@ public class Context AllowedMentions = mentions ?? new AllowedMentions() }); - if (embed != null) - { + // if (embed != null) + // { // Sensitive information that might want to be deleted by :x: reaction is typically in an embed format (member cards, for example) - // This may need to be changed at some point but works well enough for now + // but since we can, we just store all sent messages for possible deletion await _commandMessageService.RegisterMessage(msg.Id, msg.ChannelId, Author.Id); - } + // } return msg; } diff --git a/PluralKit.Bot/Commands/Message.cs b/PluralKit.Bot/Commands/Message.cs index 811e38ae..49384356 100644 --- a/PluralKit.Bot/Commands/Message.cs +++ b/PluralKit.Bot/Commands/Message.cs @@ -2,6 +2,8 @@ using System.Text; using System.Text.RegularExpressions; +using Autofac; + using Myriad.Builders; using Myriad.Cache; using Myriad.Extensions; @@ -304,14 +306,14 @@ public class ProxiedMessage private async Task DeleteCommandMessage(Context ctx, ulong messageId) { - var message = await ctx.Repository.GetCommandMessage(messageId); - if (message == null) + var (authorId, channelId) = await ctx.Services.Resolve().GetCommandMessage(messageId); + if (authorId == null) throw Errors.MessageNotFound(messageId); - if (message.AuthorId != ctx.Author.Id) + if (authorId != ctx.Author.Id) throw new PKError("You can only delete command messages queried by this account."); - await ctx.Rest.DeleteMessage(message.ChannelId, message.MessageId); + await ctx.Rest.DeleteMessage(channelId!.Value, messageId); if (ctx.Guild != null) await ctx.Rest.DeleteMessage(ctx.Message); diff --git a/PluralKit.Bot/Handlers/ReactionAdded.cs b/PluralKit.Bot/Handlers/ReactionAdded.cs index 482aa39c..155e2bf8 100644 --- a/PluralKit.Bot/Handlers/ReactionAdded.cs +++ b/PluralKit.Bot/Handlers/ReactionAdded.cs @@ -73,10 +73,10 @@ public class ReactionAdded: IEventHandler return; } - var commandMsg = await _commandMessageService.GetCommandMessage(evt.MessageId); - if (commandMsg != null) + var (authorId, _) = await _commandMessageService.GetCommandMessage(evt.MessageId); + if (authorId != null) { - await HandleCommandDeleteReaction(evt, commandMsg); + await HandleCommandDeleteReaction(evt, authorId.Value); return; } } @@ -141,11 +141,11 @@ public class ReactionAdded: IEventHandler await _repo.DeleteMessage(evt.MessageId); } - private async ValueTask HandleCommandDeleteReaction(MessageReactionAddEvent evt, CommandMessage? msg) + private async ValueTask HandleCommandDeleteReaction(MessageReactionAddEvent evt, ulong? authorId) { // Can only delete your own message // (except in DMs, where msg will be null) - if (msg != null && msg.AuthorId != evt.UserId) + if (authorId != null && authorId != evt.UserId) return; // todo: don't try to delete the user's own messages in DMs diff --git a/PluralKit.Bot/Services/CommandMessageService.cs b/PluralKit.Bot/Services/CommandMessageService.cs index ee097d2a..568af21b 100644 --- a/PluralKit.Bot/Services/CommandMessageService.cs +++ b/PluralKit.Bot/Services/CommandMessageService.cs @@ -8,16 +8,13 @@ namespace PluralKit.Bot; public class CommandMessageService { - private readonly IClock _clock; - private readonly IDatabase _db; + private readonly RedisService _redis; private readonly ILogger _logger; - private readonly ModelRepository _repo; + private static readonly TimeSpan CommandMessageRetention = TimeSpan.FromHours(24); - public CommandMessageService(IDatabase db, ModelRepository repo, IClock clock, ILogger logger) + public CommandMessageService(RedisService redis, IClock clock, ILogger logger) { - _db = db; - _repo = repo; - _clock = clock; + _redis = redis; _logger = logger.ForContext(); } @@ -27,9 +24,18 @@ public class CommandMessageService "Registering command response {MessageId} from author {AuthorId} in {ChannelId}", messageId, authorId, channelId ); - await _repo.SaveCommandMessage(messageId, channelId, authorId); + + await _redis.Connection.GetDatabase().StringSetAsync(messageId.ToString(), $"{authorId}-{channelId}", expiry: CommandMessageRetention); } - public async Task GetCommandMessage(ulong messageId) => - await _repo.GetCommandMessage(messageId); + public async Task<(ulong?, ulong?)> GetCommandMessage(ulong messageId) + { + var str = await _redis.Connection.GetDatabase().StringGetAsync(messageId.ToString()); + if (str.HasValue) + { + var split = ((string)str).Split("-"); + return (ulong.Parse(split[0]), ulong.Parse(split[1])); + } + return (null, null); + } } \ No newline at end of file diff --git a/PluralKit.Core/Database/Repository/ModelRepository.CommandMessage.cs b/PluralKit.Core/Database/Repository/ModelRepository.CommandMessage.cs deleted file mode 100644 index c5072d9d..00000000 --- a/PluralKit.Core/Database/Repository/ModelRepository.CommandMessage.cs +++ /dev/null @@ -1,36 +0,0 @@ -using SqlKata; - -namespace PluralKit.Core; - -public partial class ModelRepository -{ - public Task SaveCommandMessage(ulong messageId, ulong channelId, ulong authorId) - { - var query = new Query("command_messages").AsInsert(new - { - message_id = messageId, - channel_id = channelId, - author_id = authorId, - }); - return _db.ExecuteQuery(query); - } - - public Task GetCommandMessage(ulong messageId) - { - var query = new Query("command_messages").Where("message_id", messageId); - return _db.QueryFirst(query); - } - - public Task DeleteCommandMessagesBefore(ulong messageIdThreshold) - { - var query = new Query("command_messages").AsDelete().Where("message_id", "<", messageIdThreshold); - return _db.QueryFirst(query); - } -} - -public class CommandMessage -{ - public ulong AuthorId { get; set; } - public ulong MessageId { get; set; } - public ulong ChannelId { get; set; } -} \ No newline at end of file diff --git a/PluralKit.ScheduledTasks/TaskHandler.cs b/PluralKit.ScheduledTasks/TaskHandler.cs index 2fe44670..a25f4f02 100644 --- a/PluralKit.ScheduledTasks/TaskHandler.cs +++ b/PluralKit.ScheduledTasks/TaskHandler.cs @@ -19,7 +19,6 @@ namespace PluralKit.ScheduledTasks; public class TaskHandler { - private static readonly Duration CommandMessageRetention = Duration.FromHours(24); private readonly IDatabase _db; private readonly RedisService _redis; private readonly bool _useRedisMetrics; @@ -65,9 +64,6 @@ public class TaskHandler if (_useRedisMetrics) await CollectBotStats(); - // Clean up message cache in postgres - await CleanupOldMessages(); - stopwatch.Stop(); _logger.Information("Ran scheduled tasks in {Time}", stopwatch.ElapsedDuration()); } @@ -108,18 +104,6 @@ public class TaskHandler _logger.Debug("Submitted metrics to backend"); } - private async Task CleanupOldMessages() - { - var deleteThresholdInstant = SystemClock.Instance.GetCurrentInstant() - CommandMessageRetention; - var deleteThresholdSnowflake = InstantToSnowflake(deleteThresholdInstant); - - var deletedRows = await _repo.DeleteCommandMessagesBefore(deleteThresholdSnowflake); - - _logger.Information( - "Pruned {DeletedRows} command messages older than retention {Retention} (older than {DeleteThresholdInstant} / {DeleteThresholdSnowflake})", - deletedRows, CommandMessageRetention, deleteThresholdInstant, deleteThresholdSnowflake); - } - // we don't have access to PluralKit.Bot here, so this needs to be vendored public static ulong InstantToSnowflake(Instant time) => (ulong)(time - Instant.FromUtc(2015, 1, 1, 0, 0, 0)).TotalMilliseconds << 22;