using System.Net.Mail; using MailKit; using MailKit.Net.Imap; using MailKit.Net.Smtp; using MimeKit; namespace NejAccountingAPI.Services.Email; public class SMTPService : IEmailService { public record SMTPSettings(string From, string Host, int Port, int ImapPort, string Username, string Password); private readonly SMTPSettings _settings; private readonly ILogger Logger; public SMTPService(ILogger logger, SMTPSettings settings) { _settings = settings; Logger = logger; } public async Task SendEmailAsync(string recipient, string subject, string message, List? attachments = null) { var mess = new MimeMessage(); mess.From.Add(MailboxAddress.Parse(_settings.From)); mess.To.Add(MailboxAddress.Parse(recipient)); mess.Subject = subject; var bodyBuilder = new BodyBuilder(); bodyBuilder.HtmlBody = message; bodyBuilder.TextBody = ""; foreach (var attachment in attachments ?? new List()) bodyBuilder.Attachments.Add(attachment.Name, attachment.ContentStream, ContentType.Parse(attachment.ContentType.ToString())); mess.Body = bodyBuilder.ToMessageBody(); using (var client = new MailKit.Net.Smtp.SmtpClient()) { await client.ConnectAsync(_settings.Host, _settings.Port); // Note: only needed if the SMTP server requires authentication await client.AuthenticateAsync(_settings.Username, _settings.Password); await client.SendAsync(mess); await client.DisconnectAsync(true); using (var imap = new MailKit.Net.Imap.ImapClient()) { await imap.ConnectAsync(_settings.Host, _settings.ImapPort); // or ConnectSSL for SSL await imap.AuthenticateAsync(_settings.Username, _settings.Password); //get the sent folder IMailFolder sent = null; if (imap.Capabilities.HasFlag(ImapCapabilities.SpecialUse)) sent = imap.GetFolder(SpecialFolder.Sent); if (sent == null) { // get the default personal namespace root folder var personal = imap.GetFolder(imap.PersonalNamespaces[0]); // This assumes the sent folder's name is "Sent", but use whatever the real name is sent = await personal.GetSubfolderAsync("Sent").ConfigureAwait(false); } if (sent != null) { await sent.AppendAsync(mess, MessageFlags.Seen); } await imap.DisconnectAsync(true); } Logger.LogInformation("Email {0} sent to {1} - {2} attachments", subject, recipient, attachments?.Count ?? 0); } } }