From 891e31a9a159331218d6043bb988aff8cdf4f8b7 Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Tue, 25 Jun 2024 14:58:50 +0500 Subject: [PATCH] refactor: split reminder sending into a separate service --- TeamOctolings.Octobot/Program.cs | 1 + .../Services/ReminderService.cs | 57 +++++++++++++++++++ .../Services/Update/MemberUpdateService.cs | 40 ++----------- 3 files changed, 62 insertions(+), 36 deletions(-) create mode 100644 TeamOctolings.Octobot/Services/ReminderService.cs diff --git a/TeamOctolings.Octobot/Program.cs b/TeamOctolings.Octobot/Program.cs index d1d6220..043108f 100644 --- a/TeamOctolings.Octobot/Program.cs +++ b/TeamOctolings.Octobot/Program.cs @@ -81,6 +81,7 @@ public sealed class Program // Services .AddSingleton() .AddSingleton() + .AddSingleton() .AddSingleton() .AddHostedService(provider => provider.GetRequiredService()) .AddHostedService() diff --git a/TeamOctolings.Octobot/Services/ReminderService.cs b/TeamOctolings.Octobot/Services/ReminderService.cs new file mode 100644 index 0000000..914c452 --- /dev/null +++ b/TeamOctolings.Octobot/Services/ReminderService.cs @@ -0,0 +1,57 @@ +using System.Text; +using Remora.Discord.API.Abstractions.Objects; +using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.Extensions.Embeds; +using Remora.Discord.Extensions.Formatting; +using Remora.Rest.Core; +using Remora.Results; +using TeamOctolings.Octobot.Data; +using TeamOctolings.Octobot.Extensions; + +namespace TeamOctolings.Octobot.Services; + +public sealed class ReminderService +{ + private readonly IDiscordRestChannelAPI _channelApi; + + public ReminderService(IDiscordRestChannelAPI channelApi) + { + _channelApi = channelApi; + } + + public async Task TickRemindersAsync(Snowflake guildId, IUser user, List reminders, List failedResults, CancellationToken ct = default) + { + for (var i = reminders.Count - 1; i >= 0; i--) + { + var reminder = reminders[i]; + if (DateTimeOffset.UtcNow < reminder.At) + { + continue; + } + + var sendResult = await SendReminderAsync(guildId, user, reminders[i], ct); + failedResults.AddIfFailed(sendResult); + if (sendResult.IsSuccess) + { + reminders.RemoveAt(i); + } + } + } + + private async Task SendReminderAsync(Snowflake guildId, IUser user, Reminder reminder, CancellationToken ct = default) + { + var builder = new StringBuilder() + .AppendBulletPointLine(string.Format(Messages.DescriptionReminder, Markdown.InlineCode(reminder.Text))) + .AppendBulletPointLine(string.Format(Messages.DescriptionActionJumpToMessage, + $"https://discord.com/channels/{guildId.Value}/{reminder.ChannelId}/{reminder.MessageId}")); + + var embed = new EmbedBuilder().WithSmallTitle( + string.Format(Messages.Reminder, user.GetTag()), user) + .WithDescription(builder.ToString()) + .WithColour(ColorsList.Magenta) + .Build(); + + return await _channelApi.CreateMessageWithEmbedResultAsync( + reminder.ChannelId.ToSnowflake(), Mention.User(user), embedResult: embed, ct: ct); + } +} diff --git a/TeamOctolings.Octobot/Services/Update/MemberUpdateService.cs b/TeamOctolings.Octobot/Services/Update/MemberUpdateService.cs index 51cf647..62f213b 100644 --- a/TeamOctolings.Octobot/Services/Update/MemberUpdateService.cs +++ b/TeamOctolings.Octobot/Services/Update/MemberUpdateService.cs @@ -31,15 +31,17 @@ public sealed partial class MemberUpdateService : BackgroundService private readonly IDiscordRestGuildAPI _guildApi; private readonly GuildDataService _guildData; private readonly ILogger _logger; + private readonly ReminderService _reminders; public MemberUpdateService(AccessControlService access, IDiscordRestChannelAPI channelApi, - IDiscordRestGuildAPI guildApi, GuildDataService guildData, ILogger logger) + IDiscordRestGuildAPI guildApi, GuildDataService guildData, ILogger logger, ReminderService reminders) { _access = access; _channelApi = channelApi; _guildApi = guildApi; _guildData = guildData; _logger = logger; + _reminders = reminders; } protected override async Task ExecuteAsync(CancellationToken ct) @@ -113,11 +115,7 @@ public sealed partial class MemberUpdateService : BackgroundService return failedResults.AggregateErrors(); } - for (var i = data.Reminders.Count - 1; i >= 0; i--) - { - var reminderTickResult = await TickReminderAsync(data.Reminders[i], user, data, guildId, ct); - failedResults.AddIfFailed(reminderTickResult); - } + await _reminders.TickRemindersAsync(guildId, user, data.Reminders, failedResults, ct); if (!canInteract) { @@ -224,34 +222,4 @@ public sealed partial class MemberUpdateService : BackgroundService [GeneratedRegex("[^0-9A-Za-zА-Яа-яЁё]")] private static partial Regex IllegalChars(); - - private async Task TickReminderAsync(Reminder reminder, IUser user, MemberData data, Snowflake guildId, - CancellationToken ct) - { - if (DateTimeOffset.UtcNow < reminder.At) - { - return Result.Success; - } - - var builder = new StringBuilder() - .AppendBulletPointLine(string.Format(Messages.DescriptionReminder, Markdown.InlineCode(reminder.Text))) - .AppendBulletPointLine(string.Format(Messages.DescriptionActionJumpToMessage, - $"https://discord.com/channels/{guildId.Value}/{reminder.ChannelId}/{reminder.MessageId}")); - - var embed = new EmbedBuilder().WithSmallTitle( - string.Format(Messages.Reminder, user.GetTag()), user) - .WithDescription(builder.ToString()) - .WithColour(ColorsList.Magenta) - .Build(); - - var messageResult = await _channelApi.CreateMessageWithEmbedResultAsync( - reminder.ChannelId.ToSnowflake(), Mention.User(user), embedResult: embed, ct: ct); - if (!messageResult.IsSuccess) - { - return ResultExtensions.FromError(messageResult); - } - - data.Reminders.Remove(reminder); - return Result.Success; - } }