66 lines
2.2 KiB
C#
66 lines
2.2 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 IEmailSettingsResolver _settings;
|
|
private readonly ILogger<SmtpEmailSender> _logger;
|
|
|
|
public SmtpEmailSender(IEmailSettingsResolver settings, ILogger<SmtpEmailSender> logger)
|
|
{
|
|
_settings = settings;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task SendAsync(string toEmail, string subject, string bodyText, CancellationToken cancellationToken = default)
|
|
{
|
|
var snapshot = await _settings.GetSnapshotAsync(cancellationToken);
|
|
var host = snapshot.Host;
|
|
var user = snapshot.User;
|
|
var pass = snapshot.Password;
|
|
var from = snapshot.From;
|
|
var fromName = snapshot.FromName;
|
|
var port = snapshot.Port;
|
|
var enableSsl = snapshot.EnableSsl;
|
|
var timeoutMs = snapshot.TimeoutMs;
|
|
|
|
var enabled = snapshot.Enabled;
|
|
if (!enabled)
|
|
{
|
|
_logger.LogWarning("Email sending is disabled. 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);
|
|
}
|
|
|
|
await Task.Run(() => smtp.Send(msg), cancellationToken);
|
|
}
|
|
}
|