From c956c5b3b2fabe654a3581f1a899419fefb3cc9a Mon Sep 17 00:00:00 2001 From: Francesco Lorenzo D'Amico Date: Tue, 18 Aug 2026 16:46:07 +0200 Subject: [PATCH] Backend-scheudler for telegram notifications by new contact requests --- RazorPagesMovie/Models/ContactMessage.cs | 2 + RazorPagesMovie/Program.cs | 4 + .../ContactMessageNotificationService.cs | 95 +++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 RazorPagesMovie/Services/ContactMessageNotificationService.cs diff --git a/RazorPagesMovie/Models/ContactMessage.cs b/RazorPagesMovie/Models/ContactMessage.cs index 1f5fc3f..c86a107 100644 --- a/RazorPagesMovie/Models/ContactMessage.cs +++ b/RazorPagesMovie/Models/ContactMessage.cs @@ -33,4 +33,6 @@ public class ContactMessage [Display(Name = "Gesendet am")] [DataType(DataType.DateTime)] public DateTime SentAt { get; set; } = DateTime.Now; + + public bool NotificationSent { get; set; } = false; } diff --git a/RazorPagesMovie/Program.cs b/RazorPagesMovie/Program.cs index df4a20b..a72a617 100644 --- a/RazorPagesMovie/Program.cs +++ b/RazorPagesMovie/Program.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.EntityFrameworkCore; using RazorPagesMovie.Data; using RazorPagesMovie.Models; +using RazorPagesMovie.Services; var builder = WebApplication.CreateBuilder(args); builder.Configuration.AddJsonFile("appsettings.Local.json", optional: true, reloadOnChange: true); @@ -21,6 +22,9 @@ builder.Services.AddRazorPages(options => options.Conventions.AuthorizeFolder("/Admin"); }); +builder.Services.AddHttpClient(); +builder.Services.AddHostedService(); + var app = builder.Build(); using (var scope = app.Services.CreateScope()) diff --git a/RazorPagesMovie/Services/ContactMessageNotificationService.cs b/RazorPagesMovie/Services/ContactMessageNotificationService.cs new file mode 100644 index 0000000..5f29ccd --- /dev/null +++ b/RazorPagesMovie/Services/ContactMessageNotificationService.cs @@ -0,0 +1,95 @@ +using System.Net.Http.Json; +using Microsoft.EntityFrameworkCore; +using RazorPagesMovie.Data; + +namespace RazorPagesMovie.Services; + +public class ContactMessageNotificationService : BackgroundService +{ + private static readonly TimeSpan CheckInterval = TimeSpan.FromMinutes(5); + + private readonly IServiceScopeFactory _scopeFactory; + private readonly IHttpClientFactory _httpClientFactory; + private readonly IConfiguration _configuration; + private readonly ILogger _logger; + + public ContactMessageNotificationService( + IServiceScopeFactory scopeFactory, + IHttpClientFactory httpClientFactory, + IConfiguration configuration, + ILogger logger) + { + _scopeFactory = scopeFactory; + _httpClientFactory = httpClientFactory; + _configuration = configuration; + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (!stoppingToken.IsCancellationRequested) + { + await CheckForNewContactMessagesAsync(stoppingToken); + await Task.Delay(CheckInterval, stoppingToken); + } + } + + private async Task CheckForNewContactMessagesAsync(CancellationToken stoppingToken) + { + var botToken = _configuration["Telegram:BotToken"]; + var chatId = _configuration["Telegram:ChatId"]; + + if (string.IsNullOrWhiteSpace(botToken) || string.IsNullOrWhiteSpace(chatId)) + { + return; + } + + using var scope = _scopeFactory.CreateScope(); + var context = scope.ServiceProvider.GetRequiredService(); + + var neueEintraege = await context.ContactMessage + .Where(c => !c.NotificationSent) + .OrderBy(c => c.SentAt) + .ToListAsync(stoppingToken); + + if (neueEintraege.Count == 0) + { + return; + } + + var httpClient = _httpClientFactory.CreateClient(); + var sendMessageUrl = $"https://api.telegram.org/bot{botToken}/sendMessage"; + + foreach (var eintrag in neueEintraege) + { + var text = $"Neue Kontaktanfrage von {eintrag.Name}\n" + + $"E-Mail: {eintrag.Email}\n" + + (string.IsNullOrWhiteSpace(eintrag.Phone) ? "" : $"Telefon: {eintrag.Phone}\n") + + (string.IsNullOrWhiteSpace(eintrag.Subject) ? "" : $"Betreff: {eintrag.Subject}\n") + + $"\n{eintrag.Message}"; + + try + { + var response = await httpClient.PostAsJsonAsync( + sendMessageUrl, + new { chat_id = chatId, text }, + stoppingToken); + + if (response.IsSuccessStatusCode) + { + eintrag.NotificationSent = true; + } + else + { + _logger.LogWarning("Telegram-Versand fehlgeschlagen für ContactMessage {Id}: {StatusCode}", eintrag.Id, response.StatusCode); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Telegram-Versand fehlgeschlagen für ContactMessage {Id}", eintrag.Id); + } + } + + await context.SaveChangesAsync(stoppingToken); + } +}