using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Quartz; using SolarPower.Models; using SolarPower.Repository.Interface; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Mail; using System.Threading.Tasks; using System.Text.RegularExpressions; namespace SolarPower.Quartz.Jobs { [DisallowConcurrentExecution] public class SendEmailJob : IJob { private readonly ILogger logger; private readonly IOptions _options; private readonly INoticeScheduleRepository noticeScheduleRepository; private SMTPConfig smtp; public SendEmailJob( ILogger logger, IOptions options, INoticeScheduleRepository noticeScheduleRepository) { this.logger = logger; this.smtp = options.Value; this.noticeScheduleRepository = noticeScheduleRepository; } public async Task Execute(IJobExecutionContext context) { try { //取得要寄信的列表 logger.LogInformation("【SendEmailJob】【任務開始】"); var noticeSchedules = await noticeScheduleRepository.GetNotYetDelivery(); var updateNoticeSchedules = new List(); foreach (var notice in noticeSchedules) { if (notice.RecipientEmail != null && IsValidEmail(notice.RecipientEmail)) { var attachments = new List(); var recipientEmails = new List() { notice.RecipientEmail }; if (!string.IsNullOrEmpty(notice.Attachment)) { attachments = notice.Attachment.Split(',').ToList(); } var result = Send(recipientEmails, notice.Subject, notice.Content, attachments); if (result.CompareTo("成功") == 0) { NoticeSchedule noticeSchedule = new NoticeSchedule(); noticeSchedule.Id = notice.Id; noticeSchedule.IsDelivery = 1; noticeSchedule.DeliveryAt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); updateNoticeSchedules.Add(noticeSchedule); } else { NoticeSchedule noticeSchedule = new NoticeSchedule(); noticeSchedule.Id = notice.Id; noticeSchedule.IsDelivery = 2; noticeSchedule.DeliveryAt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); noticeSchedule.Reason = result; updateNoticeSchedules.Add(noticeSchedule); } List properties = new List() { "Id", "IsDelivery", "DeliveryAt" }; await noticeScheduleRepository.UpdateList(updateNoticeSchedules, properties); } } logger.LogInformation("【SendEmailJob】【任務完成】"); } catch (Exception exception) { logger.LogError("【{0}】{1}", "SendEmailJob", exception.Message); } } private string Send(List recipientEmails, string subject, string content, List attachments) { var reason = string.Empty; var CanDoSend = true; MailMessage MyMail = new MailMessage(); MyMail.SubjectEncoding = System.Text.Encoding.UTF8;//郵件標題編碼 MyMail.BodyEncoding = System.Text.Encoding.UTF8; //郵件內容編碼 MyMail.IsBodyHtml = true; //是否使用html格式 var kkk = $"太陽能電站管理系統通知 <{smtp.UserName}>"; MyMail.From = new System.Net.Mail.MailAddress(kkk); //寄件人 foreach (var email in recipientEmails) { MyMail.To.Add(email); //設定收件者Email } MyMail.Subject = subject; //主題 MyMail.Body = content; //設定信件內容 foreach (var attachment in attachments) { var directoryBase = Directory.GetCurrentDirectory(); var filePath = @$"{directoryBase}\wwwroot{attachment}"; if (File.Exists(filePath)) { var data = new Attachment(filePath); MyMail.Attachments.Add(data); } else { CanDoSend = false; reason = "失敗 - 檔案遺失"; break; } } //讀取 SMTP Config if (CanDoSend) { SmtpClient MySMTP = new SmtpClient(smtp.Host, smtp.Port); MySMTP.EnableSsl = smtp.EnableSsl; MySMTP.Credentials = new System.Net.NetworkCredential(smtp.UserName, smtp.Password); try { MySMTP.Send(MyMail); MySMTP.Dispose(); MyMail.Dispose(); //釋放資源 return "成功"; } catch (Exception ex) { string json = System.Text.Json.JsonSerializer.Serialize(recipientEmails); logger.LogError("【SendEmailJob】 " + "寄送信件失敗"); logger.LogError("【SendEmailJob】 - Emails:" + json); logger.LogError("【SendEmailJob】 - Exception:" + ex.Message); return "失敗 - " + ex.Message; } } else { return reason; } } bool IsValidEmail(string strIn) { // Return true if strIn is in valid e-mail format. return Regex.IsMatch(strIn, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); } } }