feat(ops): 배포 알림과 텔레그램 리포트 추가
This commit is contained in:
@@ -33,8 +33,8 @@ public class TelegramNotificationService : ITelegramNotificationService
|
||||
_httpClient = httpClient;
|
||||
_logger = logger;
|
||||
_botToken = config["Telegram:BotToken"] ?? "";
|
||||
_defaultChatId = config["Telegram:ChatId"] ?? "";
|
||||
_inquiryChatId = config["Telegram:InquiryChatId"] ?? "-5434691215";
|
||||
_defaultChatId = config["Telegram:ChatId"] ?? "-5434691215";
|
||||
_inquiryChatId = config["Telegram:InquiryChatId"] ?? _defaultChatId;
|
||||
_systemChatId = config["Telegram:SystemChatId"] ?? "-5585148480";
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public class TelegramNotificationService : ITelegramNotificationService
|
||||
public async Task SendErrorAsync(string title, string details, CancellationToken ct = default)
|
||||
{
|
||||
var message = $"<b>❌ {title}</b>\n\n{details}\n\n<i>{DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC</i>";
|
||||
await SendMessageAsync(message, ct);
|
||||
await SendToChat(_systemChatId, message, ct);
|
||||
}
|
||||
|
||||
public async Task SendInfoAsync(string title, string message, CancellationToken ct = default)
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user