Files
jobtrackingapp/JobTrackerApi/Services/SmtpEmailSender.cs
T

70 lines
2.4 KiB
C#

using System.Net;
using System.Net.Mail;
namespace JobTrackerApi.Services;
public interface IAppEmailSender
{
Task SendAsync(string toEmail, string subject, string bodyText, CancellationToken cancellationToken = default);
}
public sealed class SmtpEmailSender : IAppEmailSender
{
private readonly IConfiguration _cfg;
private readonly ILogger<SmtpEmailSender> _logger;
public SmtpEmailSender(IConfiguration cfg, ILogger<SmtpEmailSender> logger)
{
_cfg = cfg;
_logger = logger;
}
public async Task SendAsync(string toEmail, string subject, string bodyText, CancellationToken cancellationToken = default)
{
var host = (_cfg["Email:SmtpHost"] ?? "").Trim();
var user = (_cfg["Email:SmtpUser"] ?? "").Trim();
var pass = (_cfg["Email:SmtpPassword"] ?? "").Trim();
var from = (_cfg["Email:From"] ?? user).Trim();
var fromName = (_cfg["Email:FromName"] ?? "Jobbjakt").Trim();
var port = _cfg.GetValue("Email:SmtpPort", 587);
if (port <= 0) port = 587;
var enableSsl = _cfg.GetValue("Email:SmtpEnableSsl", true);
var timeoutMs = _cfg.GetValue("Email:SmtpTimeoutMs", 15000);
if (timeoutMs <= 0) timeoutMs = 15000;
var enabled = _cfg.GetValue("Email:Enabled", false);
if (!enabled)
{
_logger.LogWarning("Email sending is disabled (Email:Enabled=false). Suppressed email to {To} subject={Subject}", toEmail, subject);
return;
}
if (string.IsNullOrWhiteSpace(host)) throw new InvalidOperationException("Email:SmtpHost is not configured.");
if (string.IsNullOrWhiteSpace(from)) throw new InvalidOperationException("Email:From is not configured.");
using var msg = new MailMessage();
msg.From = new MailAddress(from, string.IsNullOrWhiteSpace(fromName) ? null : fromName);
msg.To.Add(new MailAddress(toEmail));
msg.Subject = subject;
msg.Body = bodyText;
msg.IsBodyHtml = false;
using var smtp = new SmtpClient(host, port)
{
EnableSsl = enableSsl,
DeliveryMethod = SmtpDeliveryMethod.Network,
Timeout = timeoutMs,
};
if (!string.IsNullOrWhiteSpace(user))
{
smtp.Credentials = new NetworkCredential(user, pass);
}
// SmtpClient has no CancellationToken support; run on thread pool.
await Task.Run(() => smtp.Send(msg), cancellationToken);
}
}