NejCommon.NET/Services/Email/SMTPService.cs
2024-12-21 19:38:19 +01:00

81 lines
2.9 KiB
C#

using System.Net.Mail;
using MailKit;
using MailKit.Net.Imap;
using MailKit.Net.Smtp;
using MimeKit;
namespace NejCommon.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<SMTPService> Logger;
public SMTPService(ILogger<SMTPService> logger, SMTPSettings settings)
{
_settings = settings;
Logger = logger;
}
public async Task SendEmailAsync(string recipient, string subject, string message, List<Attachment>? 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<Attachment>())
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 Task.Delay(100);
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);
await Task.Delay(100);
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);
}
}
}