Files
taxbaik/TaxBaik.Web/Services/TelegramReportBackgroundService.cs

83 lines
3.1 KiB
C#

namespace TaxBaik.Web.Services;
using Microsoft.Extensions.Hosting;
using TaxBaik.Application.Services;
public class TelegramReportBackgroundService(
IServiceScopeFactory scopeFactory,
ILogger<TelegramReportBackgroundService> logger) : BackgroundService
{
private static readonly TimeZoneInfo KoreaTimeZone = GetKoreaTimeZone();
private DateOnly? _lastDailyReportDate;
private DateOnly? _lastWeeklyReportWeekStart;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(30));
while (await timer.WaitForNextTickAsync(stoppingToken))
{
try
{
var now = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, KoreaTimeZone);
await TrySendReportsAsync(now, stoppingToken);
}
catch (Exception ex)
{
logger.LogError(ex, "Telegram report background loop failed");
}
}
}
private async Task TrySendReportsAsync(DateTimeOffset nowKst, CancellationToken ct)
{
if (nowKst.Hour is 9 or 10)
await SendDailyIfNeededAsync(DateOnly.FromDateTime(nowKst.DateTime), ct);
if (nowKst.DayOfWeek == DayOfWeek.Monday && nowKst.Hour is 9 or 10)
await SendWeeklyIfNeededAsync(DateOnly.FromDateTime(nowKst.DateTime).AddDays(-7), ct);
}
private async Task SendDailyIfNeededAsync(DateOnly date, CancellationToken ct)
{
if (_lastDailyReportDate == date)
return;
using var scope = scopeFactory.CreateScope();
var reportService = scope.ServiceProvider.GetRequiredService<TelegramReportService>();
var telegram = scope.ServiceProvider.GetRequiredService<ITelegramNotificationService>();
var report = await reportService.BuildDailyReportAsync(date, ct);
await telegram.SendSystemNotificationAsync(TelegramReportService.FormatDailyMessage(report), ct);
_lastDailyReportDate = date;
logger.LogInformation("Daily telegram report sent for {Date}", date);
}
private async Task SendWeeklyIfNeededAsync(DateOnly weekStart, CancellationToken ct)
{
if (_lastWeeklyReportWeekStart == weekStart)
return;
using var scope = scopeFactory.CreateScope();
var reportService = scope.ServiceProvider.GetRequiredService<TelegramReportService>();
var telegram = scope.ServiceProvider.GetRequiredService<ITelegramNotificationService>();
var report = await reportService.BuildWeeklyReportAsync(weekStart, ct);
await telegram.SendSystemNotificationAsync(TelegramReportService.FormatWeeklyMessage(report), ct);
_lastWeeklyReportWeekStart = weekStart;
logger.LogInformation("Weekly telegram report sent for {WeekStart}", weekStart);
}
private static TimeZoneInfo GetKoreaTimeZone()
{
try
{
return TimeZoneInfo.FindSystemTimeZoneById("Korea Standard Time");
}
catch (TimeZoneNotFoundException)
{
return TimeZoneInfo.FindSystemTimeZoneById("Asia/Seoul");
}
}
}