NonInventPurchasingSystem/CPRNIMS.Infrastructure/Helper/SMTPHelper.cs
2026-03-02 12:25:08 +08:00

168 lines
6.9 KiB
C#

using CPRNIMS.Infrastructure.ViewModel.Common;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
namespace CPRNIMS.Infrastructure.Helper
{
public class SMTPHelper
{
private readonly IConfiguration _configuration;
private readonly EmailValidationService _emailValidator;
public SMTPHelper(EmailValidationService emailValidator, IConfiguration configuration)
{
_emailValidator = emailValidator;
_configuration = configuration;
}
public bool IsAuthError { get; private set; }
public string EMailTemplate(string contentPath)
{
// Get the physical path to the template folder
string templateFolderPath = Path.Combine(contentPath);
// Read the content of the template file
string body = File.ReadAllText(templateFolderPath);
return body;
}
public string GenerateOTP()
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var otp = new string(Enumerable.Repeat(chars, 8)
.Select(s => s[random.Next(s.Length)])
.ToArray());
return otp;
}
public async Task<bool> SendEmailAsync(EmailMessageDetailsVM emailMessageBody)
{
try
{
if (string.IsNullOrWhiteSpace(emailMessageBody?.Recipient))
{
Console.WriteLine("Email address is null or empty. Cannot send email.");
return false;
}
// 👇 Reads live from appsettings.json every time — picks up changes without restart
var excludedEmails = new HashSet<string>(
_configuration.GetSection("Canvass:EmailSettings:ExcludedEmails")
.Get<List<string>>() ?? new List<string>(),
StringComparer.OrdinalIgnoreCase
);
using (MailMessage myMessage = new MailMessage())
{
var recipientList = emailMessageBody.Recipient
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(r => r.Trim())
.Where(r => !string.IsNullOrWhiteSpace(r))
.Where(r =>
{
if (excludedEmails.Contains(r))
{
Console.WriteLine($"[Excluded] Skipping: {r}");
return false;
}
return true;
});
// Validate remaining recipients concurrently
var validationResults = await _emailValidator.ValidateBatchAsync(recipientList);
foreach (var result in validationResults)
{
if (result.IsValid)
myMessage.To.Add(result.Email);
else
Console.WriteLine($"[Skipped] {result.Reason}: {result.Email}");
}
if (myMessage.To.Count == 0)
{
Console.WriteLine("No valid recipients after exclusion/validation. Aborting.");
return false;
}
myMessage.Sender = new MailAddress(emailMessageBody.SenderEmail);
myMessage.From = new MailAddress(emailMessageBody.SenderEmail, emailMessageBody.DisplayName);
// CC with exclusion too
if (!string.IsNullOrWhiteSpace(emailMessageBody.CC))
{
var ccList = emailMessageBody.CC
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(c => c.Trim())
.Where(c => !string.IsNullOrWhiteSpace(c))
.Where(c =>
{
if (excludedEmails.Contains(c))
{
Console.WriteLine($"[Excluded CC] Skipping: {c}");
return false;
}
return true;
});
var ccValidationResults = await _emailValidator.ValidateBatchAsync(ccList);
foreach (var result in ccValidationResults)
{
if (result.IsValid)
myMessage.CC.Add(result.Email);
else
Console.WriteLine($"[Skipped CC] {result.Reason}: {result.Email}");
}
}
myMessage.Subject = emailMessageBody.Subject;
myMessage.Body = emailMessageBody.Message;
myMessage.IsBodyHtml = true;
if (emailMessageBody.IsCanvass && File.Exists(emailMessageBody.AttachPath))
{
Attachment pdfAttachment = new Attachment(emailMessageBody.AttachPath);
pdfAttachment.Name = Path.GetFileName(emailMessageBody.AttachPath);
myMessage.Attachments.Add(pdfAttachment);
}
using (SmtpClient smtp = new SmtpClient(emailMessageBody.Server))
{
smtp.Port = emailMessageBody.OutGoingPort;
smtp.UseDefaultCredentials = emailMessageBody.IsSuccess;
smtp.Credentials = new NetworkCredential(emailMessageBody.UserName, emailMessageBody.NewPassword);
smtp.EnableSsl = true;
try
{
await smtp.SendMailAsync(myMessage);
Console.WriteLine($"Email sent successfully to {myMessage.To.Count} recipient(s).");
return true;
}
catch (Exception ex)
{
var message = ex.InnerException?.ToString() ?? ex.Message;
Console.WriteLine($"Error sending email: {message}");
return false;
}
}
}
}
catch (Exception ex)
{
IsAuthError = true;
var message = ex.InnerException?.ToString() ?? ex.Message;
Console.WriteLine($"Error in SendEmailAsync: {message}");
return false;
}
}
}
}