using System; using System.Configuration; using System.Net; using System.Net.Mail; using log4net; using LeafWeb.Core.DAL; using LeafWeb.Core.Entities; using LeafWeb.Core.Utility; using LeafWeb.WebCms.Models; using Umbraco.Core; namespace LeafWeb.WebCms.Services { public class EmailNotificationService : IDisposable { private static readonly ILog Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private readonly string _emailFromAddress; private const string SuccessSubject = "LeafWeb results"; private const string ErrorSubject = "LeafWeb processing error"; private const string SystemErrorSubject = "LeafWeb system error"; private const string CancelledSubject = "LeafWeb cancelled"; private const string ContactSubject = "LeafWeb Contact Message"; /// /// comma separated values /// private readonly string _adminEmailAddresses; private readonly SmtpClient _smtpClient; private readonly DataService _dataService; private readonly UrlService _urlService; private string FormatSubject(string subject, LeafInput leafInput) { return subject + $" - '{leafInput.Identifier}'"; } public EmailNotificationService(DataService dataService) { _dataService = dataService; _urlService = new UrlService(); _smtpClient = new SmtpClient( ConfigurationManager.AppSettings["SmtpHost"], Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"])); if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["SmtpUserName"])) _smtpClient.Credentials = new NetworkCredential( ConfigurationManager.AppSettings["SmtpUserName"], ConfigurationManager.AppSettings["SmtpPassword"] ); _emailFromAddress = ConfigurationManager.AppSettings["EmailFromAddress"]; _adminEmailAddresses = ConfigurationManager.AppSettings["AdminEmailAddresses"]; } public EmailNotificationService() : this(new DataService()) { } public void SendLeafWebComplete(int leafInputId) { var leafInput = _dataService.GetLeafInput(leafInputId); if (leafInput.CurrentStatus != LeafInputStatusType.Complete) { var notComplete = "Attempting to SendLeafWebComplete when status is not complete" + $" for leafInput: {leafInput}, current status: {leafInput.CurrentStatus}"; Logger.Error(notComplete); throw new ArgumentException(notComplete); } var outputErrorMessage = leafInput.OutputErrorMessage; if (outputErrorMessage != null) SendLeafWebError(leafInput, outputErrorMessage.FileContents.Contents.GetString()); else SendLeafWebSuccess(leafInput); } public void SendLeafWebCancelled(int leafInputId) { var leafInput = _dataService.GetLeafInput(leafInputId); if (leafInput.CurrentStatus != LeafInputStatusType.Cancelled) { var notComplete = "Attempting to SendLeafWebCancelled when status is not complete " + $"for leafInput: {leafInput}, current status: {leafInput.CurrentStatus}"; Logger.Error(notComplete); throw new ArgumentException(notComplete); } var body = $"Your leaf analysis job, {leafInput.Identifier}, has been cancelled. " + "Contact the administrator with any questions."; var message = new MailMessage(_emailFromAddress, leafInput.Email, FormatSubject(CancelledSubject, leafInput), body); SendMessage(message); } public void SendAdministratorMessage(string subject, string body) { var message = new MailMessage(_emailFromAddress, _adminEmailAddresses, subject, body); SendMessage(message); } private void SendLeafWebSuccess(LeafInput leafInput) { var body = $"Your leaf analysis job '{leafInput.Identifier}' has completed. "; body += FormatWarningMessage(leafInput); var downloadLink = true; if (downloadLink) { var downloadUrl = _urlService.GetDownloadUrl(leafInput); var chartUrl = _urlService.GetChartUrl(leafInput); body += Environment.NewLine + Environment.NewLine + "Download results with the following link:" + Environment.NewLine + Environment.NewLine + downloadUrl; body += Environment.NewLine + Environment.NewLine + "Chart results with the following link:" + Environment.NewLine + Environment.NewLine + chartUrl; var message = new MailMessage(_emailFromAddress, leafInput.Email, FormatSubject(SuccessSubject, leafInput), body); SendMessage(message); } //else //{ // body += "Please see the attached results."; // var message = new MailMessage(_emailFromAddress, leafInput.Email, SuccessSubject, body); // var fileStreams = // (from outputFile in // leafInput.OutputFiles // select Tuple.Create(outputFile, new MemoryStream(outputFile.FileContents.Contents))).ToList(); // try // { // foreach (var fileStream in fileStreams) // { // var attachment = new Attachment(fileStream.Item2, fileStream.Item1.Filename); // message.Attachments.Add(attachment); // } // SendMessage(message); // } // finally // { // // can't dispose those memory streams until the message is sent // foreach (var stream in fileStreams.Select(f => f.Item2)) // { // stream.Dispose(); // } // } //} } private void SendLeafWebError(LeafInput leafInput, string errorMessage) { var body = $"Your leaf analysis job '{leafInput.Identifier}' encountered the following errors." + Environment.NewLine + Environment.NewLine + Environment.NewLine + errorMessage + Environment.NewLine + Environment.NewLine + "You will need to correct your input and resubmit."; body += FormatWarningMessage(leafInput); var message = new MailMessage(_emailFromAddress, leafInput.Email, FormatSubject(ErrorSubject, leafInput), body); SendMessage(message); } public void SendLeafWebSystemException(string leafInputIdentifier, string leafInputEmail) { var body = $"A system error occured while processing your leaf analysis job '{leafInputIdentifier}'." + Environment.NewLine + "System administrators have been notified. You will be notified again when the system error " + "has been resolved and your data has been processed."; var message = new MailMessage(_emailFromAddress, leafInputEmail, SystemErrorSubject, body); SendMessage(message); } public void SendContactEmail(ContactForm contact) { var body = $"via LeafWeb, {contact.Name} sent the following message from the Contact form." + Environment.NewLine + Environment.NewLine + "Message" + Environment.NewLine + Environment.NewLine + "--------" + Environment.NewLine + Environment.NewLine + contact.Message; var message = new MailMessage(_emailFromAddress, _adminEmailAddresses, ContactSubject, body) { From = new MailAddress(contact.Email, contact.Name) }; SendMessage(message); } public void SendVerifyMemberEmail(string memberEmail) { var member = ApplicationContext.Current.Services.MemberService.GetByEmail(memberEmail); var verifyEmailURl = _urlService.GetVerifyEmailURl(member); var body = "Welcome to LeafWeb!" + Environment.NewLine + Environment.NewLine + "Please verify your email address with this link " + verifyEmailURl + Environment.NewLine + "Read more information about LeafWeb on the site here: https://leafweb.org/information/about/"; var message = new MailMessage(_emailFromAddress, member.Email, "Welcome to LeafWeb, please verify your email address", body); SendMessage(message); } private string FormatWarningMessage(LeafInput leafInput) { if (leafInput.OutputWarningMessage != null) return Environment.NewLine + Environment.NewLine + "The following warning message was generated." + Environment.NewLine + Environment.NewLine + leafInput.OutputWarningMessage.FileContents.Contents.GetString() + Environment.NewLine; return string.Empty; } private void SendMessage(MailMessage mailMessage) { try { Logger.Info($"Email sending to {mailMessage.To}, subject: {mailMessage.Subject}"); _smtpClient.Send(mailMessage); } catch (SmtpException ex) { Logger.Error($"Failed to send mail: {ex.Message}", ex); } } public void Dispose() { _dataService.Dispose(); } } }