83 lines
3.1 KiB
C#
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");
|
|
}
|
|
}
|
|
}
|