mirror of
https://github.com/TeamOctolings/Octobot.git
synced 2025-04-18 16:03:36 +03:00
refactor: split reminder sending into a separate service
This commit is contained in:
parent
a953053f1d
commit
891e31a9a1
3 changed files with 62 additions and 36 deletions
|
@ -81,6 +81,7 @@ public sealed class Program
|
|||
// Services
|
||||
.AddSingleton<AccessControlService>()
|
||||
.AddSingleton<GuildDataService>()
|
||||
.AddSingleton<ReminderService>()
|
||||
.AddSingleton<Utility>()
|
||||
.AddHostedService<GuildDataService>(provider => provider.GetRequiredService<GuildDataService>())
|
||||
.AddHostedService<MemberUpdateService>()
|
||||
|
|
57
TeamOctolings.Octobot/Services/ReminderService.cs
Normal file
57
TeamOctolings.Octobot/Services/ReminderService.cs
Normal file
|
@ -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<Reminder> reminders, List<Result> 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<Result> 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);
|
||||
}
|
||||
}
|
|
@ -31,15 +31,17 @@ public sealed partial class MemberUpdateService : BackgroundService
|
|||
private readonly IDiscordRestGuildAPI _guildApi;
|
||||
private readonly GuildDataService _guildData;
|
||||
private readonly ILogger<MemberUpdateService> _logger;
|
||||
private readonly ReminderService _reminders;
|
||||
|
||||
public MemberUpdateService(AccessControlService access, IDiscordRestChannelAPI channelApi,
|
||||
IDiscordRestGuildAPI guildApi, GuildDataService guildData, ILogger<MemberUpdateService> logger)
|
||||
IDiscordRestGuildAPI guildApi, GuildDataService guildData, ILogger<MemberUpdateService> 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<Result> 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue