/// <summary> /// Sends the specified rock message. /// </summary> /// <param name="rockMessage">The rock message.</param> /// <param name="mediumEntityTypeId">The medium entity type identifier.</param> /// <param name="mediumAttributes">The medium attributes.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Send(RockMessage rockMessage, int mediumEntityTypeId, Dictionary <string, string> mediumAttributes, out List <string> errorMessages) { errorMessages = new List <string>(); var emailMessage = rockMessage as RockEmailMessage; if (emailMessage == null) { return(false); } var mergeFields = GetAllMergeFields(rockMessage.CurrentPerson, rockMessage.AdditionalMergeFields); var globalAttributes = GlobalAttributesCache.Get(); var fromAddress = GetFromAddress(emailMessage, mergeFields, globalAttributes); if (fromAddress.IsNullOrWhiteSpace()) { errorMessages.Add("A From address was not provided."); return(false); } var templateMailMessage = GetTemplateRockEmailMessage(emailMessage, mergeFields, globalAttributes); var organizationEmail = globalAttributes.GetValue("OrganizationEmail"); foreach (var rockMessageRecipient in rockMessage.GetRecipients()) { try { var recipientEmailMessage = GetRecipientRockEmailMessage(templateMailMessage, rockMessageRecipient, mergeFields, organizationEmail); var result = SendEmail(recipientEmailMessage); // Create the communication record if (recipientEmailMessage.CreateCommunicationRecord) { var transaction = new SaveCommunicationTransaction(rockMessageRecipient, recipientEmailMessage.FromName, recipientEmailMessage.FromEmail, recipientEmailMessage.Subject, recipientEmailMessage.Message); transaction.RecipientGuid = recipientEmailMessage.MessageMetaData["communication_recipient_guid"].AsGuidOrNull(); RockQueue.TransactionQueue.Enqueue(transaction); } } catch (Exception ex) { errorMessages.Add(ex.Message); ExceptionLogService.LogException(ex); } } return(!errorMessages.Any()); }
/// <summary> /// Sends the specified rock message. /// </summary> /// <param name="rockMessage">The rock message.</param> /// <param name="mediumEntityTypeId">The medium entity type identifier.</param> /// <param name="mediumAttributes">The medium attributes.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Send(RockMessage rockMessage, int mediumEntityTypeId, Dictionary <string, string> mediumAttributes, out List <string> errorMessages) { errorMessages = new List <string>(); var emailMessage = rockMessage as RockEmailMessage; if (emailMessage != null) { // Common Merge Field var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null, rockMessage.CurrentPerson); foreach (var mergeField in rockMessage.AdditionalMergeFields) { mergeFields.AddOrReplace(mergeField.Key, mergeField.Value); } string fromAddress = emailMessage.FromEmail; string fromName = emailMessage.FromName; // Resolve any possible merge fields in the from address fromAddress = fromAddress.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands); fromName = fromName.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands); // From - if none is set, use the one in the Organization's GlobalAttributes. var globalAttributes = GlobalAttributesCache.Get(); if (string.IsNullOrWhiteSpace(fromAddress)) { fromAddress = globalAttributes.GetValue("OrganizationEmail"); } if (string.IsNullOrWhiteSpace(fromName)) { fromName = globalAttributes.GetValue("OrganizationName"); } if (fromAddress.IsNullOrWhiteSpace()) { errorMessages.Add("A From address was not provided and no Organization email address is configured."); return(false); } MailMessage message = new MailMessage(); // Reply To try { if (emailMessage.ReplyToEmail.IsNotNullOrWhiteSpace()) { // Resolve any possible merge fields in the replyTo address message.ReplyToList.Add(new MailAddress(emailMessage.ReplyToEmail.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands))); } } catch { } message.IsBodyHtml = true; message.Priority = MailPriority.Normal; using (var smtpClient = GetSmtpClient()) { foreach (var messageRecipient in rockMessage.GetRecipients()) { try { foreach (var mergeField in mergeFields) { messageRecipient.MergeFields.AddOrIgnore(mergeField.Key, mergeField.Value); } message.To.Clear(); message.CC.Clear(); message.Bcc.Clear(); message.Headers.Clear(); // Set From/To and check safe sender message.From = new MailAddress(fromAddress, fromName); message.To.Add(new MailAddress( messageRecipient.To.ResolveMergeFields(messageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands), messageRecipient.Name.ResolveMergeFields(messageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands))); CheckSafeSender(message, globalAttributes); // cc foreach (string cc in emailMessage.CCEmails.Where(e => e != "")) { // Resolve any possible merge fields in the cc address string ccRecipient = cc.ResolveMergeFields(messageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands); message.CC.Add(new MailAddress(ccRecipient)); } // bcc foreach (string bcc in emailMessage.BCCEmails.Where(e => e != "")) { // Resolve any possible merge fields in the cc address string bccRecipient = bcc.ResolveMergeFields(messageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands); message.Bcc.Add(new MailAddress(bccRecipient)); } // Subject string subject = ResolveText(emailMessage.Subject, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands, messageRecipient.MergeFields, emailMessage.AppRoot, emailMessage.ThemeRoot); // Body string body = ResolveText(emailMessage.Message, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands, messageRecipient.MergeFields, emailMessage.AppRoot, emailMessage.ThemeRoot); body = Regex.Replace(body, @"\[\[\s*UnsubscribeOption\s*\]\]", string.Empty); message.Subject = subject.Left(998); message.Body = body; var metaData = new Dictionary <string, string>(emailMessage.MessageMetaData); // If a communication is going to get created, create a guid for tracking the opens/clicks Guid?recipientGuid = null; if (emailMessage.CreateCommunicationRecord) { recipientGuid = Guid.NewGuid(); metaData.Add("communication_recipient_guid", recipientGuid.Value.ToString()); } using (var rockContext = new RockContext()) { // Recreate the attachments message.Attachments.Clear(); if (emailMessage.Attachments.Any()) { var binaryFileService = new BinaryFileService(rockContext); foreach (var binaryFileId in emailMessage.Attachments.Where(a => a != null).Select(a => a.Id)) { var attachment = binaryFileService.Get(binaryFileId); if (attachment != null) { message.Attachments.Add(new Attachment(attachment.ContentStream, attachment.FileName)); } } } AddAdditionalHeaders(message, metaData); smtpClient.Send(message); } if (emailMessage.CreateCommunicationRecord) { var transaction = new SaveCommunicationTransaction(messageRecipient, emailMessage.FromName, emailMessage.FromEmail, subject, body); transaction.RecipientGuid = recipientGuid; RockQueue.TransactionQueue.Enqueue(transaction); } } catch (Exception ex) { errorMessages.Add(ex.Message); ExceptionLogService.LogException(ex); } } } } return(!errorMessages.Any()); }
/// <summary> /// Sends the specified rock message. /// </summary> /// <param name="rockMessage">The rock message.</param> /// <param name="mediumEntityTypeId">The medium entity type identifier. Not used.</param> /// <param name="mediumAttributes">The medium attributes. Not used.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Send(RockMessage rockMessage, int mediumEntityTypeId, Dictionary <string, string> mediumAttributes, out List <string> errorMessages) { errorMessages = new List <string>(); var emailMessage = rockMessage as RockEmailMessage; if (emailMessage == null) { return(!errorMessages.Any()); } var globalAttributes = GlobalAttributesCache.Get(); // Common Merge Field var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null, rockMessage.CurrentPerson); foreach (var mergeField in rockMessage.AdditionalMergeFields) { mergeFields.AddOrReplace(mergeField.Key, mergeField.Value); } // Resolve any possible merge fields in the from address string fromAddress = emailMessage.FromEmail.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands); string fromName = emailMessage.FromName.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands); // Replace blank values with organizational defaults fromAddress = fromAddress.IsNullOrWhiteSpace() ? globalAttributes.GetValue("OrganizationEmail") : fromAddress; fromName = fromName.IsNullOrWhiteSpace() ? globalAttributes.GetValue("OrganizationName") : fromName; if (!fromAddress.IsValidEmail()) { errorMessages.Add("A From address was not provided."); return(false); } RestRequest restRequest = null; foreach (var rockMessageRecipient in rockMessage.GetRecipients()) { try { restRequest = new RestRequest(GetAttributeValue("Resource"), Method.POST); restRequest.AddParameter("domian", GetAttributeValue("Domain"), ParameterType.UrlSegment); // Reply To if (emailMessage.ReplyToEmail.IsNotNullOrWhiteSpace()) { // Resolve any possible merge fields in the replyTo address restRequest.AddParameter("h:Reply-To", emailMessage.ReplyToEmail.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands)); } foreach (var mergeField in mergeFields) { rockMessageRecipient.MergeFields.AddOrIgnore(mergeField.Key, mergeField.Value); } // From restRequest.AddParameter("from", new MailAddress(fromAddress, fromName).ToString()); // To restRequest.AddParameter( "to", new MailAddress( rockMessageRecipient.To.ResolveMergeFields(rockMessageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands), rockMessageRecipient.Name.ResolveMergeFields(rockMessageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands))); // Safe Sender checks CheckSafeSender(restRequest, fromAddress, globalAttributes.GetValue("OrganizationEmail")); // CC foreach (string cc in emailMessage.CCEmails.Where(e => e != string.Empty)) { string ccRecipient = cc.ResolveMergeFields(rockMessageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands); restRequest.AddParameter("cc", ccRecipient); } // BCC foreach (string bcc in emailMessage.BCCEmails.Where(e => e != string.Empty)) { string bccRecipient = bcc.ResolveMergeFields(rockMessageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands); restRequest.AddParameter("bcc", bccRecipient); } // Subject string subject = ResolveText(emailMessage.Subject, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands, rockMessageRecipient.MergeFields, emailMessage.AppRoot, emailMessage.ThemeRoot).Left(998); restRequest.AddParameter("subject", subject); // Body (html) string body = ResolveText(emailMessage.Message, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands, rockMessageRecipient.MergeFields, emailMessage.AppRoot, emailMessage.ThemeRoot); body = Regex.Replace(body, @"\[\[\s*UnsubscribeOption\s*\]\]", string.Empty); restRequest.AddParameter("html", body); // Communication record for tracking opens & clicks var metaData = new Dictionary <string, string>(emailMessage.MessageMetaData); Guid?recipientGuid = null; if (emailMessage.CreateCommunicationRecord) { recipientGuid = Guid.NewGuid(); metaData.Add("communication_recipient_guid", recipientGuid.Value.ToString()); } // Additional headers AddAdditionalHeaders(restRequest, metaData); // Attachments if (emailMessage.Attachments.Any()) { using (var rockContext = new RockContext()) { var binaryFileService = new BinaryFileService(rockContext); foreach (var binaryFileId in emailMessage.Attachments.Where(a => a != null).Select(a => a.Id)) { var attachment = binaryFileService.Get(binaryFileId); if (attachment != null) { MemoryStream ms = new MemoryStream(); attachment.ContentStream.CopyTo(ms); restRequest.AddFile("attachment", ms.ToArray(), attachment.FileName); } } } } // Send it RestClient restClient = new RestClient { BaseUrl = new Uri(GetAttributeValue("BaseURL")), Authenticator = new HttpBasicAuthenticator("api", GetAttributeValue("APIKey")) }; // Call the API and get the response Response = restClient.Execute(restRequest); // Create the communication record if (emailMessage.CreateCommunicationRecord) { var transaction = new SaveCommunicationTransaction(rockMessageRecipient, emailMessage.FromName, emailMessage.FromEmail, subject, body); transaction.RecipientGuid = recipientGuid; RockQueue.TransactionQueue.Enqueue(transaction); } } catch (Exception ex) { errorMessages.Add(ex.Message); ExceptionLogService.LogException(ex); } } return(!errorMessages.Any()); }
/// <summary> /// Sends the specified recipients. /// </summary> /// <param name="recipients">The recipients.</param> /// <param name="from">From.</param> /// <param name="fromName">From name.</param> /// <param name="subject">The subject.</param> /// <param name="body">The body.</param> /// <param name="appRoot">The application root.</param> /// <param name="themeRoot">The theme root.</param> /// <param name="attachments">Attachments.</param> /// <param name="createCommunicationHistory">if set to <c>true</c> [create communication history].</param> public void Send(List <string> recipients, string from, string fromName, string subject, string body, string appRoot, string themeRoot, List <Attachment> attachments, bool createCommunicationHistory) { try { var globalAttributes = GlobalAttributesCache.Read(); if (string.IsNullOrWhiteSpace(from)) { from = globalAttributes.GetValue("OrganizationEmail"); } if (!string.IsNullOrWhiteSpace(from)) { // Resolve any possible merge fields in the from address var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); string msgFrom = from.ResolveMergeFields(mergeFields); string msgSubject = subject; string msgBody = body; if (!string.IsNullOrWhiteSpace(themeRoot)) { msgSubject = msgSubject.Replace("~~/", themeRoot); msgBody = msgBody.Replace("~~/", themeRoot); } if (!string.IsNullOrWhiteSpace(appRoot)) { msgSubject = msgSubject.Replace("~/", appRoot); msgBody = msgBody.Replace("~/", appRoot); msgBody = msgBody.Replace(@" src=""/", @" src=""" + appRoot); msgBody = msgBody.Replace(@" href=""/", @" href=""" + appRoot); } MailMessage message = new MailMessage(); // set from if (!string.IsNullOrWhiteSpace(fromName)) { message.From = new MailAddress(msgFrom, fromName); } else { message.From = new MailAddress(msgFrom); } CheckSafeSender(message, globalAttributes); message.IsBodyHtml = true; message.Priority = MailPriority.Normal; message.To.Clear(); recipients.ForEach(r => message.To.Add(r)); message.Subject = msgSubject; // strip out any unsubscribe links since we don't know the person msgBody = Regex.Replace(msgBody, @"\[\[\s*UnsubscribeOption\s*\]\]", string.Empty); message.Body = msgBody; // add attachments if (attachments != null) { foreach (var attachment in attachments) { message.Attachments.Add(attachment); } } AddAdditionalHeaders(message, null); using (var smtpClient = GetSmtpClient()) { smtpClient.Send(message); } if (createCommunicationHistory) { var transaction = new SaveCommunicationTransaction( recipients, fromName, from, subject, body); RockQueue.TransactionQueue.Enqueue(transaction); } } } catch (Exception ex) { ExceptionLogService.LogException(ex, null); } }
/// <summary> /// Sends the specified medium data to the specified list of recipients. /// </summary> /// <param name="mediumData">The medium data.</param> /// <param name="recipients">The recipients.</param> /// <param name="appRoot">The application root.</param> /// <param name="themeRoot">The theme root.</param> /// <param name="createCommunicationHistory">if set to <c>true</c> [create communication history].</param> /// <param name="metaData">The meta data.</param> public void Send(Dictionary <string, string> mediumData, List <string> recipients, string appRoot, string themeRoot, bool createCommunicationHistory, Dictionary <string, string> metaData) { try { var globalAttributes = GlobalAttributesCache.Read(); string from = string.Empty; string fromName = string.Empty; mediumData.TryGetValue("From", out from); if (string.IsNullOrWhiteSpace(from)) { from = globalAttributes.GetValue("OrganizationEmail"); fromName = globalAttributes.GetValue("OrganizationName"); } if (!string.IsNullOrWhiteSpace(from)) { // Resolve any possible merge fields in the from address var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); from = from.ResolveMergeFields(mergeFields); fromName = fromName.ResolveMergeFields(mergeFields); string subject = string.Empty; mediumData.TryGetValue("Subject", out subject); string body = string.Empty; mediumData.TryGetValue("Body", out body); if (!string.IsNullOrWhiteSpace(themeRoot)) { subject = subject.Replace("~~/", themeRoot); body = body.Replace("~~/", themeRoot); } if (!string.IsNullOrWhiteSpace(appRoot)) { subject = subject.Replace("~/", appRoot); body = body.Replace("~/", appRoot); body = body.Replace(@" src=""/", @" src=""" + appRoot); body = body.Replace(@" href=""/", @" href=""" + appRoot); } MailMessage message = new MailMessage(); if (string.IsNullOrWhiteSpace(fromName)) { message.From = new MailAddress(from); } else { message.From = new MailAddress(from, fromName); } // Reply To try { string replyTo = string.Empty; mediumData.TryGetValue("ReplyTo", out replyTo); if (!string.IsNullOrWhiteSpace(replyTo)) { message.ReplyToList.Add(new MailAddress(replyTo)); } } catch { } CheckSafeSender(message, globalAttributes); message.IsBodyHtml = true; message.Priority = MailPriority.Normal; message.To.Clear(); recipients.ForEach(r => message.To.Add(r)); message.Subject = subject; message.Body = body; AddAdditionalHeaders(message, metaData); using (var smtpClient = GetSmtpClient()) { smtpClient.Send(message); } if (createCommunicationHistory) { var transaction = new SaveCommunicationTransaction( recipients, fromName, from, subject, body); RockQueue.TransactionQueue.Enqueue(transaction); } } } catch (Exception ex) { ExceptionLogService.LogException(ex, null); } }
/// <summary> /// Sends the specified template. /// </summary> /// <param name="template">The template.</param> /// <param name="recipients">The recipients.</param> /// <param name="appRoot">The application root.</param> /// <param name="themeRoot">The theme root.</param> /// <param name="createCommunicationHistory">if set to <c>true</c> [create communication history].</param> public void Send(SystemEmail template, List <RecipientData> recipients, string appRoot, string themeRoot, bool createCommunicationHistory) { var globalAttributes = GlobalAttributesCache.Read(); string from = template.From; if (string.IsNullOrWhiteSpace(from)) { from = globalAttributes.GetValue("OrganizationEmail"); } string fromName = template.FromName; if (string.IsNullOrWhiteSpace(fromName)) { fromName = globalAttributes.GetValue("OrganizationName"); } if (!string.IsNullOrWhiteSpace(from)) { // Resolve any possible merge fields in the from address var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); from = from.ResolveMergeFields(mergeFields); fromName = fromName.ResolveMergeFields(mergeFields); MailMessage message = new MailMessage(); if (string.IsNullOrWhiteSpace(fromName)) { message.From = new MailAddress(from); } else { message.From = new MailAddress(from, fromName); } CheckSafeSender(message, globalAttributes); if (!string.IsNullOrWhiteSpace(template.Cc)) { foreach (string ccRecipient in template.Cc.SplitDelimitedValues()) { message.CC.Add(new MailAddress(ccRecipient)); } } if (!string.IsNullOrWhiteSpace(template.Bcc)) { foreach (string ccRecipient in template.Bcc.SplitDelimitedValues()) { message.Bcc.Add(new MailAddress(ccRecipient)); } } message.IsBodyHtml = true; message.Priority = MailPriority.Normal; using (var smtpClient = GetSmtpClient()) { foreach (var recipientData in recipients) { foreach (var g in mergeFields) { if (recipientData.MergeFields.ContainsKey(g.Key)) { recipientData.MergeFields[g.Key] = g.Value; } } // Add the recipients from the template List <string> sendTo = SplitRecipient(template.To); // Add the recipient from merge data ( if it's not null and not already added ) if (!string.IsNullOrWhiteSpace(recipientData.To) && !sendTo.Contains(recipientData.To, StringComparer.OrdinalIgnoreCase)) { sendTo.Add(recipientData.To); } foreach (string to in sendTo) { message.To.Clear(); message.To.Add(to); message.Headers.Clear(); string subject = template.Subject.ResolveMergeFields(recipientData.MergeFields); string body = Regex.Replace(template.Body.ResolveMergeFields(recipientData.MergeFields), @"\[\[\s*UnsubscribeOption\s*\]\]", string.Empty); if (!string.IsNullOrWhiteSpace(themeRoot)) { subject = subject.Replace("~~/", themeRoot); body = body.Replace("~~/", themeRoot); } if (!string.IsNullOrWhiteSpace(appRoot)) { subject = subject.Replace("~/", appRoot); body = body.Replace("~/", appRoot); body = body.Replace(@" src=""/", @" src=""" + appRoot); body = body.Replace(@" src='/", @" src='" + appRoot); body = body.Replace(@" href=""/", @" href=""" + appRoot); body = body.Replace(@" href='/", @" href='" + appRoot); } message.Subject = subject; message.Body = body; AddAdditionalHeaders(message, null); smtpClient.Send(message); if (createCommunicationHistory) { var transaction = new SaveCommunicationTransaction( to, fromName, from, subject, body); RockQueue.TransactionQueue.Enqueue(transaction); } } } } } }