using LiteCharms.Features.Email.Commands; using LiteCharms.Models.Configuraton.Email; namespace LiteCharms.Features.Email.Commands.Handlers; public class SendEmailCommandHandler(IOptions smtpOptions) : IRequestHandler { public async ValueTask Handle(SendEmailCommand request, CancellationToken cancellationToken) { try { var settings = smtpOptions.Value; if(settings == null) return Result.Fail(new Error("SMTP settings are not configured.")); if(settings.Credentials == null) return Result.Fail(new Error("SMTP credentials are not configured.")); if(string.IsNullOrWhiteSpace(settings?.Credentials.Username) || string.IsNullOrWhiteSpace(settings.Credentials.Password)) return Result.Fail(new Error("SMTP credentials are incomplete.")); if(string.IsNullOrWhiteSpace(settings.Host) || settings.Port == 0) return Result.Fail(new Error("SMTP host and port must be configured.")); var message = new MimeMessage(); message.From.Add(new MailboxAddress(request.SenderName, request.From!)); message.To.Add(new MailboxAddress(request.RecipientName, request.To!)); message.Subject = request.Subject!; var bodyBuilder = new BodyBuilder(); if(request.Attachment?.Length > 0 && !string.IsNullOrEmpty(request.AttachmentFileName)) bodyBuilder.Attachments.Add(request.AttachmentFileName!, request.Attachment!, cancellationToken); if (!request.IsHtml) bodyBuilder.TextBody = request.Message; if (request.IsHtml) bodyBuilder.HtmlBody = request.Message; message.Body = bodyBuilder.ToMessageBody(); using var client = new SmtpClient(); await client.ConnectAsync(settings.Host!, settings.Port, settings.UseSsl, cancellationToken); await client.AuthenticateAsync(settings.Credentials!.Username!, settings.Credentials.Password!, cancellationToken); var response = await client.SendAsync(message, cancellationToken); bool emailSent = response.Contains("OK", StringComparison.InvariantCultureIgnoreCase); await client.DisconnectAsync(true, cancellationToken); return emailSent ? Result.Ok() : Result.Fail(new Error("Failed to send email. SMTP response: " + response)); } catch (Exception ex) { return Result.Fail(new Error(ex.Message).CausedBy(ex)); } } }