Skip to content

Commit

Permalink
Add weekly schedule
Browse files Browse the repository at this point in the history
  • Loading branch information
Twinki14 committed Nov 7, 2023
1 parent 55baa53 commit b32e094
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 6 deletions.
12 changes: 11 additions & 1 deletion src/Miha.Discord/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
using Miha.Discord.Consumers;
using Miha.Discord.Consumers.GuildEvent;
using Miha.Discord.Services;
using Miha.Discord.Services.Hosted;
using Miha.Discord.Services.Interfaces;
using SlimMessageBus.Host;
using SlimMessageBus.Host.Memory;
using GuildEventMonitorService = Miha.Discord.Services.Hosted.GuildEventMonitorService;

namespace Miha.Discord;

Expand All @@ -19,7 +22,14 @@ public static IServiceCollection AddDiscordOptions(this IServiceCollection servi
return services;
}

public static IServiceCollection AddDiscordClientServices(this IServiceCollection services)
public static IServiceCollection AddDiscordServices(this IServiceCollection services)
{
services.AddSingleton<IGuildScheduledEventService, GuildScheduledEventService>();

return services;
}

public static IServiceCollection AddDiscordHostedServices(this IServiceCollection services)
{
services.AddHostedService<InteractionHandler>();
services.AddHostedService<GuildEventMonitorService>();
Expand Down
50 changes: 50 additions & 0 deletions src/Miha.Discord/Services/GuildScheduledEventService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Discord;
using Discord.WebSocket;
using FluentResults;
using Microsoft.Extensions.Logging;
using Miha.Discord.Services.Interfaces;
using Miha.Shared;
using NodaTime;
using NodaTime.Calendars;
using NodaTime.Extensions;

namespace Miha.Discord.Services;

public class GuildScheduledEventService : IGuildScheduledEventService
{
private readonly DiscordSocketClient _discordClient;
private readonly ILogger<GuildScheduledEventService> _logger;

public GuildScheduledEventService(
DiscordSocketClient discordClient,
ILogger<GuildScheduledEventService> logger)
{
_discordClient = discordClient;
_logger = logger;
}

public async Task<Result<IEnumerable<IGuildScheduledEvent>>> GetScheduledWeeklyEventsAsync(ulong guildId, LocalDate dateOfTheWeek)
{
var weekNumberInYear = WeekYearRules.Iso.GetWeekOfWeekYear(dateOfTheWeek);

var guild = _discordClient.GetGuild(guildId);

if (guild is null)
{
return Result.Fail<IEnumerable<IGuildScheduledEvent>>("Failed to fetch discord guild");
}

var events = await guild.GetEventsAsync();

var eventsThisWeek = events.Where(guildEvent =>
{
var estDate = guildEvent.StartTime.ToZonedDateTime()
.WithZone(DateTimeZoneProviders.Tzdb[Timezones.IanaEasternTime]).Date;
var weekOfDate = WeekYearRules.Iso.GetWeekOfWeekYear(estDate);

return weekOfDate == weekNumberInYear;
}).Cast<IGuildScheduledEvent>();

return Result.Ok(eventsThisWeek);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using Miha.Logic.Services.Interfaces;
using Miha.Shared.ZonedClocks.Interfaces;

namespace Miha.Discord.Services;
namespace Miha.Discord.Services.Hosted;

public class BirthdayAnnouncementService : DiscordClientService
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
using Miha.Shared.ZonedClocks.Interfaces;
using Newtonsoft.Json;

namespace Miha.Discord.Services;
namespace Miha.Discord.Services.Hosted;

public partial class GuildEventMonitorService : DiscordClientService
{
Expand Down
62 changes: 62 additions & 0 deletions src/Miha.Discord/Services/Hosted/GuildEventScheduleService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Cronos;
using Discord.Addons.Hosting;
using Discord.Addons.Hosting.Util;
using Discord.WebSocket;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Miha.Discord.Services.Interfaces;
using Miha.Shared.ZonedClocks.Interfaces;

namespace Miha.Discord.Services.Hosted;

public class GuildEventScheduleService : DiscordClientService
{
private readonly DiscordSocketClient _client;
private readonly IEasternStandardZonedClock _easternStandardZonedClock;
private readonly IGuildScheduledEventService _scheduledEventService;
private readonly DiscordOptions _discordOptions;
private readonly ILogger<GuildEventScheduleService> _logger;
private const string Schedule = "0,5,10,15,20,25,30,35,40,45,50,55 8-19 * * *"; // https://crontab.cronhub.io/

private readonly CronExpression _cron;

public GuildEventScheduleService(
DiscordSocketClient client,
IEasternStandardZonedClock easternStandardZonedClock,
IGuildScheduledEventService scheduledEventService,
IOptions<DiscordOptions> discordOptions,
ILogger<GuildEventScheduleService> logger) : base(client, logger)
{
_client = client;
_easternStandardZonedClock = easternStandardZonedClock;
_scheduledEventService = scheduledEventService;
_discordOptions = discordOptions.Value;
_logger = logger;

_cron = CronExpression.Parse(Schedule, CronFormat.Standard);
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Client.WaitForReadyAsync(stoppingToken);

var eventsThisWeek = await _scheduledEventService.GetScheduledWeeklyEventsAsync(_discordOptions.Guild.Value, _easternStandardZonedClock.GetCurrentDate());

_logger.LogInformation("Events this week {events}", eventsThisWeek.Value);

while (!stoppingToken.IsCancellationRequested)
{
var utcNow = _easternStandardZonedClock.GetCurrentInstant().ToDateTimeUtc();
var nextUtc = _cron.GetNextOccurrence(DateTimeOffset.UtcNow, _easternStandardZonedClock.GetTimeZoneInfo());

if (nextUtc is null)
{
_logger.LogWarning("Next utc occurence is null");
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
continue;
}

await Task.Delay(nextUtc.Value - utcNow, stoppingToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Miha.Discord.Services;
namespace Miha.Discord.Services.Hosted;

public class InteractionHandler : DiscordClientService
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Miha.Shared;
using SlimMessageBus;

namespace Miha.Discord.Services;
namespace Miha.Discord.Services.Hosted;

public class SlimMessageBusService : DiscordClientService
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Discord;
using FluentResults;
using NodaTime;

namespace Miha.Discord.Services.Interfaces;

public interface IGuildScheduledEventService
{
Task<Result<IEnumerable<IGuildScheduledEvent>>> GetScheduledWeeklyEventsAsync(ulong guildId, LocalDate dateOfTheWeek);
}
3 changes: 2 additions & 1 deletion src/Miha/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public static void ConfigureServices(HostBuilderContext context, IServiceCollect

services
.AddDiscordOptions(context.Configuration)
.AddDiscordClientServices()
.AddDiscordServices()
.AddDiscordHostedServices()
.AddDiscordMessageBus();

services
Expand Down

0 comments on commit b32e094

Please sign in to comment.