using LiteCharms.Features.Email.Commands; using LiteCharms.Infrastructure.Database; using static LiteCharms.Abstractions.Constants; namespace LiteCharms.Features.Notifications.Events.Handlers; public class ProcessEmailNotificationsEventHandler(IDbContextFactory contextFactory, ILogger logger, ISender mediator) : INotificationHandler { public async ValueTask Handle(ProcessEmailNotificationsEvent message, CancellationToken cancellationToken) { try { using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var notifications = await context.Notifications .OrderByDescending(o => o.Priority) .ThenBy(o => o.CreatedAt) .Where(n => n.CorrelationIdType == Models.CorrelationIdTypes.Email) .Where(n => n.Direction == Models.NotificationDirection.Outgoing) .Take(message.MaxRecords) .ToListAsync(cancellationToken); foreach (var notification in notifications) { var sendResult = await SendEmailAsync(notification, cancellationToken); if(sendResult.IsFailed) { var errors = new List(1000); errors.AddRange(sendResult.Errors.Select(e => e.Message)); if (sendResult.Reasons?.Count > 0) errors.AddRange(sendResult.Reasons.Select(e => e.Message)); notification.HasError = true; notification.Errors = [.. errors]; } notification.Processed = true; } await context.SaveChangesAsync(cancellationToken); } catch (Exception ex) { logger.LogError(ex, ex.Message); } } private async Task SendEmailAsync(Entities.Notification notification, CancellationToken cancellationToken = default) { try { var request = SendEmailCommand.Create(notification.Sender!, notification.SenderName!, ShopEmailFromAddress, ShopEmailFromName, notification.Subject!, notification.Message!); var result = await mediator.Send(request, cancellationToken); return result.IsFailed ? Result.Fail(result.Errors) : Result.Ok(); } catch (Exception ex) { return Result.Fail(new Error(ex.Message).CausedBy(ex)); } } }