using MailKit.Net.Smtp; using MailSharp.MailClient.Models; using MimeKit; using System.Diagnostics; namespace MailSharp.MailClient.Services; public interface ISmtpService { Task SendAsync(Account account, string password, MimeMessage message, CancellationToken ct = default); } public class SmtpService(ILogger logger) : ISmtpService { public async Task SendAsync(Account account, string password, MimeMessage message, CancellationToken ct = default) { using var scope = logger.BeginScope(new Dictionary { ["accountId"] = account.Id, ["to"] = message.To.ToString() }); var sw = Stopwatch.StartNew(); using var client = new SmtpClient(); var secureSocket = account.SmtpSecurity switch { SecurityMode.SslTls => MailKit.Security.SecureSocketOptions.SslOnConnect, SecurityMode.StartTls => MailKit.Security.SecureSocketOptions.StartTls, _ => MailKit.Security.SecureSocketOptions.None }; try { await client.ConnectAsync(account.SmtpHost, account.SmtpPort, secureSocket, ct); await client.AuthenticateAsync(account.Username, password, ct); await client.SendAsync(message, ct); await client.DisconnectAsync(true, ct); logger.LogInformation("Sent message {Subject} for account {AccountId} in {DurationMs}ms", message.Subject, account.Id, sw.ElapsedMilliseconds); } catch (Exception ex) { logger.LogError(ex, "Failed to send message {Subject} for account {AccountId} after {DurationMs}ms", message.Subject, account.Id, sw.ElapsedMilliseconds); throw; } } }