/// <summary> /// Job that will sync groups. /// /// Called by the <see cref="IScheduler" /> when a /// <see cref="ITrigger" /> fires that is associated with /// the <see cref="IJob" />. /// </summary> public virtual void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; try { int notificationsSent = 0; int errorsEncountered = 0; int pendingMembersCount = 0; // get groups set to sync RockContext rockContext = new RockContext(); Guid?groupTypeGuid = dataMap.GetString("GroupType").AsGuidOrNull(); Guid?systemEmailGuid = dataMap.GetString("NotificationEmail").AsGuidOrNull(); Guid?groupRoleFilterGuid = dataMap.GetString("GroupRoleFilter").AsGuidOrNull(); int? pendingAge = dataMap.GetString("PendingAge").AsIntegerOrNull(); bool includePreviouslyNotificed = dataMap.GetString("IncludePreviouslyNotified").AsBoolean(); // get system email SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (!systemEmailGuid.HasValue || systemEmailGuid == Guid.Empty) { context.Result = "Job failed. Unable to find System Email"; throw new Exception("No system email found."); } systemEmail = emailService.Get(systemEmailGuid.Value); // get group members if (!groupTypeGuid.HasValue || groupTypeGuid == Guid.Empty) { context.Result = "Job failed. Unable to find group type"; throw new Exception("No group type found"); } var qry = new GroupMemberService(rockContext).Queryable("Person, Group, Group.Members.GroupRole") .Where(m => m.Group.GroupType.Guid == groupTypeGuid.Value && m.GroupMemberStatus == GroupMemberStatus.Pending); if (!includePreviouslyNotificed) { qry = qry.Where(m => m.IsNotified == false); } if (groupRoleFilterGuid.HasValue) { qry = qry.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } if (pendingAge.HasValue && pendingAge.Value > 0) { var ageDate = RockDateTime.Now.AddDays(pendingAge.Value * -1); qry = qry.Where(m => m.ModifiedDateTime > ageDate); } var pendingGroupMembers = qry.ToList(); var groups = pendingGroupMembers.GroupBy(m => m.Group); var errorList = new List <string>(); foreach (var groupKey in groups) { var group = groupKey.Key; // get list of pending people var qryPendingIndividuals = group.Members.Where(m => m.GroupMemberStatus == GroupMemberStatus.Pending); if (!includePreviouslyNotificed) { qryPendingIndividuals = qryPendingIndividuals.Where(m => m.IsNotified == false); } if (groupRoleFilterGuid.HasValue) { qryPendingIndividuals = qryPendingIndividuals.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } var pendingIndividuals = qryPendingIndividuals.Select(m => m.Person).ToList(); if (!pendingIndividuals.Any()) { continue; } // get list of leaders var groupLeaders = group.Members.Where(m => m.GroupRole.IsLeader == true && m.Person != null && m.Person.Email != null && m.Person.Email != string.Empty); if (!groupLeaders.Any()) { errorList.Add("Unable to send emails to members in group " + group.Name + " because there is no group leader"); continue; } var recipients = new List <RecipientData>(); foreach (var leader in groupLeaders) { // create merge object var mergeFields = new Dictionary <string, object>(); mergeFields.Add("PendingIndividuals", pendingIndividuals); mergeFields.Add("Group", group); mergeFields.Add("ParentGroup", group.ParentGroup); mergeFields.Add("Person", leader.Person); recipients.Add(new RecipientData(leader.Person.Email, mergeFields)); } var errorMessages = new List <string>(); var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); var sendSuccess = emailMessage.Send(out errorMessages); errorsEncountered += errorMessages.Count; errorList.AddRange(errorMessages); // be conservative: only mark as notified if we are sure the email didn't fail if (sendSuccess == false) { continue; } notificationsSent += recipients.Count(); // mark pending members as notified as we go in case the job fails var notifiedPersonIds = pendingIndividuals.Select(p => p.Id); foreach (var pendingGroupMember in pendingGroupMembers.Where(m => m.IsNotified == false && notifiedPersonIds.Contains(m.PersonId))) { pendingGroupMember.IsNotified = true; } rockContext.SaveChanges(); } context.Result = string.Format("Sent {0} emails to leaders for {1} pending individuals. {2} errors encountered.", notificationsSent, pendingMembersCount, errorsEncountered); if (errorList.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append("Errors in GroupLeaderPendingNotificationJob: "); errorList.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errors = sb.ToString(); context.Result += errors; throw new Exception(errors); } } catch (Exception ex) { HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(ex, context2); throw; } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var rockContext = new RockContext(); var personService = new PersonService(rockContext); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? systemEmailGuid = dataMap.GetString("BirthdayEmail").AsGuidOrNull(); SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (systemEmailGuid.HasValue) { systemEmail = emailService.Get(systemEmailGuid.Value); } if (systemEmail == null) { // no email specified, so nothing to do return; } var activeStatusGuid = Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid(); // only include alive people that have record status of Active var personQry = personService.Queryable(false, false).Where(a => a.RecordStatusValue.Guid == activeStatusGuid && a.IsDeceased == false); var ageRange = (dataMap.GetString("AgeRange") ?? string.Empty).Split(','); if (ageRange.Length == 2) { int?minimumAge = ageRange[0].AsIntegerOrNull(); int?maximumAge = ageRange[1].AsIntegerOrNull(); personQry = personQry.WhereAgeRange(minimumAge, maximumAge, true); } // only include people whose birthday is today (which can be determined from the computed DaysUntilBirthday column) personQry = personQry.Where(a => a.DaysUntilBirthday.HasValue && a.DaysUntilBirthday == 0); var connectionStatusGuids = (dataMap.GetString("ConnectionStatuses") ?? string.Empty).Split(',').AsGuidList(); if (connectionStatusGuids.Any()) { personQry = personQry.Where(a => connectionStatusGuids.Contains(a.ConnectionStatusValue.Guid)); } // only include people that have an email address and want an email personQry = personQry.Where(a => (a.Email != null) && (a.Email != string.Empty) && (a.EmailPreference != EmailPreference.DoNotEmail) && (a.IsEmailActive)); var recipients = new List <RecipientData>(); var personList = personQry.AsNoTracking().ToList(); foreach (var person in personList) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("Person", person); recipients.Add(new RecipientData(person.Email, mergeFields)); } var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); var errors = new List <string>(); emailMessage.Send(out errors); context.Result = string.Format("{0} birthday emails sent", recipients.Count()); if (errors.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append(string.Format("{0} Errors: ", errors.Count())); errors.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errorMessage = sb.ToString(); context.Result += errorMessage; var exception = new Exception(errorMessage); HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(exception, context2); throw exception; } }
/// <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> public abstract void Send( SystemEmail template, Dictionary<string, Dictionary<string, object>> recipients, string appRoot, string themeRoot );
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var rockContext = new RockContext(); var personService = new PersonService(rockContext); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? systemEmailGuid = dataMap.GetString("BirthdayEmail").AsGuidOrNull(); SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (systemEmailGuid.HasValue) { systemEmail = emailService.Get(systemEmailGuid.Value); } if (systemEmail == null) { // no email specified, so nothing to do return; } var activeStatusGuid = Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid(); // only include alive people that have record status of Active var personQry = personService.Queryable(false, false).Where(a => a.RecordStatusValue.Guid == activeStatusGuid && a.IsDeceased == false); var ageRange = (dataMap.GetString("AgeRange") ?? string.Empty).Split(','); if (ageRange.Length == 2) { int?minimumAge = ageRange[0].AsIntegerOrNull(); int?maximumAge = ageRange[1].AsIntegerOrNull(); personQry = personQry.WhereAgeRange(minimumAge, maximumAge, true); } // only include people whose birthday is today (which can be determined from the computed DaysUntilBirthday column) personQry = personQry.Where(a => a.DaysUntilBirthday.HasValue && a.DaysUntilBirthday == 0); var connectionStatusGuids = (dataMap.GetString("ConnectionStatuses") ?? string.Empty).Split(',').AsGuidList(); if (connectionStatusGuids.Any()) { personQry = personQry.Where(a => connectionStatusGuids.Contains(a.ConnectionStatusValue.Guid)); } // only include people that have an email address and want an email personQry = personQry.Where(a => (a.Email != null) && (a.Email != "") && (a.EmailPreference == EmailPreference.EmailAllowed)); var recipients = new List <RecipientData>(); var personList = personQry.AsNoTracking().ToList(); foreach (var person in personList) { var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", person); var globalAttributeFields = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields(null); globalAttributeFields.ToList().ForEach(d => mergeFields.Add(d.Key, d.Value)); recipients.Add(new RecipientData(person.Email, mergeFields)); } var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read(rockContext).GetValue("ExternalApplicationRoot"); Email.Send(systemEmail.Guid, recipients, appRoot); }
/// <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> public abstract void Send(SystemEmail template, List <RecipientData> recipients, string appRoot, string themeRoot);
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var rockContext = new RockContext(); JobDataMap dataMap = context.JobDetail.JobDataMap; // Get the details for the email that we'll be sending out. Guid?systemEmailGuid = dataMap.GetString("ExpiringCreditCardEmail").AsGuidOrNull(); SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (systemEmailGuid.HasValue) { systemEmail = emailService.Get(systemEmailGuid.Value); } if (systemEmail == null) { throw new Exception("Expiring credit card email is missing."); } // Fetch the configured Workflow once if one was set, we'll use it later. Guid?workflowGuid = dataMap.GetString("Workflow").AsGuidOrNull(); WorkflowTypeCache workflowType = null; var workflowService = new WorkflowService(rockContext); if (workflowGuid != null) { workflowType = WorkflowTypeCache.Get(workflowGuid.Value); } var qry = new FinancialScheduledTransactionService(rockContext) .Queryable("ScheduledTransactionDetails,FinancialPaymentDetail.CurrencyTypeValue,FinancialPaymentDetail.CreditCardTypeValue") .Where(t => t.IsActive && t.FinancialPaymentDetail.ExpirationMonthEncrypted != null && (t.EndDate == null || t.EndDate > DateTime.Now)) .AsNoTracking(); // Get the current month and year DateTime now = DateTime.Now; int month = now.Month; int year = now.Year; int counter = 0; var errors = new List <string>(); foreach (var transaction in qry) { int?expirationMonthDecrypted = Encryption.DecryptString(transaction.FinancialPaymentDetail.ExpirationMonthEncrypted).AsIntegerOrNull(); int?expirationYearDecrypted = Encryption.DecryptString(transaction.FinancialPaymentDetail.ExpirationYearEncrypted).AsIntegerOrNull(); if (expirationMonthDecrypted.HasValue && expirationMonthDecrypted.HasValue) { string acctNum = string.Empty; if (!string.IsNullOrEmpty(transaction.FinancialPaymentDetail.AccountNumberMasked) && transaction.FinancialPaymentDetail.AccountNumberMasked.Length >= 4) { acctNum = transaction.FinancialPaymentDetail.AccountNumberMasked.Substring(transaction.FinancialPaymentDetail.AccountNumberMasked.Length - 4); } int warningYear = expirationYearDecrypted.Value; int warningMonth = expirationMonthDecrypted.Value - 1; if (warningMonth == 0) { warningYear -= 1; warningMonth = 12; } string warningDate = warningMonth.ToString() + warningYear.ToString(); string currentMonthString = month.ToString() + year.ToString(); if (warningDate == currentMonthString) { // as per ISO7813 https://en.wikipedia.org/wiki/ISO/IEC_7813 var expirationDate = string.Format("{0:D2}/{1:D2}", expirationMonthDecrypted, expirationYearDecrypted); var recipients = new List <RecipientData>(); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); var person = transaction.AuthorizedPersonAlias.Person; if (!person.IsEmailActive || person.Email.IsNullOrWhiteSpace() || person.EmailPreference == EmailPreference.DoNotEmail) { continue; } mergeFields.Add("Person", person); mergeFields.Add("Card", acctNum); mergeFields.Add("Expiring", expirationDate); recipients.Add(new RecipientData(person.Email, mergeFields)); var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); var emailErrors = new List <string>(); emailMessage.Send(out emailErrors); errors.AddRange(emailErrors); // Start workflow for this person if (workflowType != null) { Dictionary <string, string> attributes = new Dictionary <string, string>(); attributes.Add("Person", transaction.AuthorizedPersonAlias.Guid.ToString()); attributes.Add("Card", acctNum); attributes.Add("Expiring", expirationDate); StartWorkflow(workflowService, workflowType, attributes, string.Format("{0} (scheduled transaction Id: {1})", person.FullName, transaction.Id)); } counter++; } } } context.Result = string.Format("{0} scheduled credit card transactions were examined with {1} notice(s) sent.", qry.Count(), counter); if (errors.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append(string.Format("{0} Errors: ", errors.Count())); errors.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errorMessage = sb.ToString(); context.Result += errorMessage; var exception = new Exception(errorMessage); HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(exception, context2); throw exception; } }
/// <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> public override void Send( SystemEmail template, List<RecipientData> recipients, string appRoot, string themeRoot ) { Send( template, recipients, appRoot, themeRoot, true ); }
/// <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> public override void Send( SystemEmail template, List<RecipientData> recipients, string appRoot, string themeRoot ) { 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 globalConfigValues = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields( null ); from = from.ResolveMergeFields( globalConfigValues ); fromName = fromName.ResolveMergeFields( globalConfigValues ); 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.CC.Add( new MailAddress( ccRecipient ) ); } } message.IsBodyHtml = true; message.Priority = MailPriority.Normal; var smtpClient = GetSmtpClient(); foreach ( var recipientData in recipients ) { foreach( var g in globalConfigValues ) { if (recipientData.MergeFields.ContainsKey( g.Key )) { recipientData.MergeFields[g.Key] = g.Value; } } List<string> sendTo = SplitRecipient( template.To ); sendTo.Add( recipientData.To ); foreach ( string to in sendTo ) { message.To.Clear(); message.To.Add( to ); 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( @" href=""/", @" href=""" + appRoot ); } message.Subject = subject; message.Body = body; smtpClient.Send( message ); } } } }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); SystemEmailService emailTemplateService = new SystemEmailService( rockContext ); SystemEmail emailTemplate; int emailTemplateId = int.Parse(hfEmailTemplateId.Value); if ( emailTemplateId == 0 ) { emailTemplate = new SystemEmail(); emailTemplateService.Add( emailTemplate ); } else { emailTemplate = emailTemplateService.Get( emailTemplateId ); } emailTemplate.Category = tbCategory.Text; emailTemplate.Title = tbTitle.Text; emailTemplate.FromName = tbFromName.Text; emailTemplate.From = tbFrom.Text; emailTemplate.To = tbTo.Text; emailTemplate.Cc = tbCc.Text; emailTemplate.Bcc = tbBcc.Text; emailTemplate.Subject = tbSubject.Text; emailTemplate.Body = tbBody.Text; if ( !emailTemplate.IsValid ) { // Controls will render the error messages return; } rockContext.SaveChanges(); NavigateToParentPage(); }
/// <summary> /// Private method called by Execute() to process the job. /// </summary> private void ProcessJob(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; int notificationsSent = 0; int errorsEncountered = 0; int absentMembersCount = 0; int sendFailed = 0; // get groups set to sync RockContext rockContext = new RockContext(); Guid?groupTypeGuid = dataMap.GetString(AttributeKey.GroupType).AsGuidOrNull(); Guid?systemEmailGuid = dataMap.GetString(AttributeKey.NotificationEmail).AsGuidOrNull(); Guid?groupRoleFilterGuid = dataMap.GetString(AttributeKey.GroupRoleFilter).AsGuidOrNull(); int minimumAbsences = dataMap.GetString(AttributeKey.MinimumAbsences).AsInteger(); // get system email SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (!systemEmailGuid.HasValue || systemEmailGuid == Guid.Empty) { context.Result = "Job failed. Unable to find System Email"; throw new Exception("No system email found."); } if (minimumAbsences == default(int)) { context.Result = "Job failed. The is no minimum absense count entered."; throw new Exception("No minimum absense count found."); } systemEmail = emailService.Get(systemEmailGuid.Value); // get group members if (!groupTypeGuid.HasValue || groupTypeGuid == Guid.Empty) { context.Result = "Job failed. Unable to find group type"; throw new Exception("No group type found."); } var groupMemberQry = new GroupMemberService(rockContext).Queryable("Group, Group.Members.GroupRole") .Where(m => m.Group.GroupType.Guid == groupTypeGuid.Value); if (groupRoleFilterGuid.HasValue) { groupMemberQry = groupMemberQry.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } var groupMembers = groupMemberQry.GroupBy(m => m.Group); var errorList = new List <string>(); foreach (var groupGroupMember in groupMembers) { var group = groupGroupMember.Key; var filteredPersons = groupGroupMember.Select(a => a.PersonId); // get list of leaders var groupLeaders = group.Members.Where(m => m.GroupRole.IsLeader == true && m.Person != null && m.Person.Email != null && m.Person.Email != string.Empty); if (!groupLeaders.Any()) { errorList.Add("Unable to send emails to members in group " + group.Name + " because there is no group leader"); continue; } // Get all the occurrences for this group var occurrences = new AttendanceOccurrenceService(rockContext) .Queryable("Attendees.PersonAlias.Person") .Where(a => a.DidNotOccur.HasValue && !a.DidNotOccur.Value && a.GroupId == group.Id) .OrderByDescending(a => a.OccurrenceDate) .Take(minimumAbsences) .ToList(); if (occurrences.Count == minimumAbsences) { var absentPersons = occurrences .SelectMany(a => a.Attendees) .Where(a => a.DidAttend.HasValue && !a.DidAttend.Value && filteredPersons.Contains(a.PersonAlias.PersonId)) .GroupBy(a => a.PersonAlias.Person) .Where(a => a.Count() == minimumAbsences) .Select(a => a.Key) .ToList(); if (absentPersons.Count > 0) { var recipients = new List <RockEmailMessageRecipient>(); foreach (var leader in groupLeaders) { // create merge object var mergeFields = new Dictionary <string, object>(); mergeFields.Add("AbsentMembers", absentPersons); mergeFields.Add("Group", group); mergeFields.Add("Person", leader.Person); recipients.Add(new RockEmailMessageRecipient(leader.Person, mergeFields)); } var errorMessages = new List <string>(); var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); var sendSuccess = emailMessage.Send(out errorMessages); if (!sendSuccess) { sendFailed++; } errorsEncountered += errorMessages.Count; errorList.AddRange(errorMessages); // be conservative: only mark as notified if we are sure the email didn't fail if (errorMessages.Any()) { continue; } absentMembersCount += absentPersons.Count; notificationsSent += recipients.Count(); } } } context.Result = string.Format("Sent {0} emails to leaders for {1} absent members. {2} errors encountered. {3} times Send reported a fail.", notificationsSent, absentMembersCount, errorsEncountered, sendFailed); if (errorList.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append("Errors in GroupLeaderAbsenceNotifications: "); errorList.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errors = sb.ToString(); context.Result += errors; throw new Exception(errors); } }
/// <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); } } } } } }
/// <summary> /// Sends the specified template. /// </summary> /// <param name="template">The template.</param> /// <param name="recipients">The recipients.</param> /// <param name="appRoot"></param> /// <param name="themeRoot"></param> public override void Send( SystemEmail template, Dictionary<string, Dictionary<string, object>> recipients, string appRoot, string themeRoot ) { 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 ) ) { MailMessage message = new MailMessage(); if (string.IsNullOrWhiteSpace(fromName)) { message.From = new MailAddress( from ); } else { message.From = new MailAddress( from, fromName ); } 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.CC.Add( new MailAddress( ccRecipient ) ); } } message.IsBodyHtml = true; message.Priority = MailPriority.Normal; var smtpClient = GetSmtpClient(); var globalConfigValues = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields( null ); foreach ( KeyValuePair<string, Dictionary<string, object>> recipient in recipients ) { var mergeObjects = recipient.Value; globalConfigValues.ToList().ForEach( g => mergeObjects[g.Key] = g.Value ); List<string> sendTo = SplitRecipient( template.To ); sendTo.Add( recipient.Key ); foreach ( string to in sendTo ) { message.To.Clear(); message.To.Add( to ); string subject = template.Subject.ResolveMergeFields( mergeObjects ); string body = Regex.Replace( template.Body.ResolveMergeFields( mergeObjects ), @"\[\[\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( @" href=""/", @" href=""" + appRoot ); } message.Subject = subject; message.Body = body; smtpClient.Send( message ); } } } }
/// <summary> /// Sends the specified template. /// </summary> /// <param name="template">The template.</param> /// <param name="recipients">The recipients.</param> /// <param name="appRoot"></param> /// <param name="themeRoot"></param> /// <exception cref="System.NotImplementedException"></exception> public override void Send( SystemEmail template, Dictionary<string, Dictionary<string, object>> recipients, string appRoot, string themeRoot ) { throw new NotImplementedException(); }
/// <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 ); } } } } } }
/// <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> public abstract void Send( SystemEmail template, List<RecipientData> recipients, string appRoot, string themeRoot );
public RockEmailMessage(SystemEmail systemEmail) : this() { InitEmailMessage(systemEmail); }
public override void Send(SystemEmail template, List <RecipientData> recipients, string appRoot, string themeRoot) { Send(template, recipients, appRoot, themeRoot, false); }
/// <summary> /// Job that will sync groups. /// /// Called by the <see cref="IScheduler" /> when a /// <see cref="ITrigger" /> fires that is associated with /// the <see cref="IJob" />. /// </summary> public virtual void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; try { int notificationsSent = 0; int pendingMembersCount = 0; // get groups set to sync RockContext rockContext = new RockContext(); Guid?groupTypeGuid = dataMap.GetString("GroupType").AsGuidOrNull(); Guid?systemEmailGuid = dataMap.GetString("NotificationEmail").AsGuidOrNull(); Guid?groupRoleFilterGuid = dataMap.GetString("GroupRoleFilter").AsGuidOrNull(); int? pendingAge = dataMap.GetString("PendingAge").AsIntegerOrNull(); bool includePreviouslyNotificed = dataMap.GetString("IncludePreviouslyNotified").AsBoolean(); // get system email SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (systemEmailGuid.HasValue) { systemEmail = emailService.Get(systemEmailGuid.Value); } if (systemEmail == null) { // no email specified, so nothing to do return; } // get group members if (groupTypeGuid.HasValue && groupTypeGuid != Guid.Empty) { var qry = new GroupMemberService(rockContext).Queryable("Person, Group, Group.Members.GroupRole") .Where(m => m.Group.GroupType.Guid == groupTypeGuid.Value && m.GroupMemberStatus == GroupMemberStatus.Pending); if (!includePreviouslyNotificed) { qry = qry.Where(m => m.IsNotified == false); } if (groupRoleFilterGuid.HasValue) { qry = qry.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } if (pendingAge.HasValue && pendingAge.Value > 0) { var ageDate = RockDateTime.Now.AddDays(pendingAge.Value * -1); qry = qry.Where(m => m.ModifiedDateTime > ageDate); } var pendingGroupMembers = qry.ToList(); var groups = pendingGroupMembers.GroupBy(m => m.Group); foreach (var groupKey in groups) { var group = groupKey.Key; // get list of pending people var qryPendingIndividuals = group.Members.Where(m => m.GroupMemberStatus == GroupMemberStatus.Pending); if (!includePreviouslyNotificed) { qryPendingIndividuals = qryPendingIndividuals.Where(m => m.IsNotified == false); } if (groupRoleFilterGuid.HasValue) { qryPendingIndividuals = qryPendingIndividuals.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } var pendingIndividuals = qryPendingIndividuals.Select(m => m.Person).ToList(); // get list of leaders var groupLeaders = group.Members.Where(m => m.GroupRole.IsLeader == true); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read(rockContext).GetValue("PublicApplicationRoot"); var recipients = new List <RecipientData>(); foreach (var leader in groupLeaders.Where(l => l.Person != null && l.Person.Email != "")) { // create merge object var mergeFields = new Dictionary <string, object>(); mergeFields.Add("PendingIndividuals", pendingIndividuals); mergeFields.Add("Group", group); mergeFields.Add("ParentGroup", group.ParentGroup); mergeFields.Add("Person", leader.Person); recipients.Add(new RecipientData(leader.Person.Email, mergeFields)); } if (pendingIndividuals.Count() > 0) { var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); emailMessage.Send(); notificationsSent += recipients.Count(); } // mark pending members as notified as we go in case the job fails var notifiedPersonIds = pendingIndividuals.Select(p => p.Id); foreach (var pendingGroupMember in pendingGroupMembers.Where(m => m.IsNotified == false && notifiedPersonIds.Contains(m.PersonId))) { pendingGroupMember.IsNotified = true; } rockContext.SaveChanges(); } } context.Result = string.Format("Sent {0} emails to leaders for {1} pending individuals", notificationsSent, pendingMembersCount); } catch (System.Exception ex) { HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(ex, context2); throw; } }
public override void Send(SystemEmail template, List <RecipientData> recipients, string appRoot, string themeRoot) { throw new NotImplementedException(); }
/// <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> /// <exception cref="System.NotImplementedException"></exception> public override void Send( SystemEmail template, List<RecipientData> recipients, string appRoot, string themeRoot ) { throw new NotImplementedException(); }
/// <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 globalConfigValues = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields( null ); from = from.ResolveMergeFields( globalConfigValues ); fromName = fromName.ResolveMergeFields( globalConfigValues ); 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() ) { using ( var rockContext = new RockContext() ) { int? senderPersonAliasId = null; if ( createCommunicationHistory ) { var sender = new PersonService( rockContext ) .Queryable().AsNoTracking() .Where( p => p.Email == from ) .FirstOrDefault(); senderPersonAliasId = sender != null ? sender.PrimaryAliasId : (int?)null; } var communicationService = new CommunicationService( rockContext ); foreach ( var recipientData in recipients ) { foreach ( var g in globalConfigValues ) { 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 ); 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( @" href=""/", @" href=""" + appRoot ); } message.Subject = subject; message.Body = body; smtpClient.Send( message ); if ( createCommunicationHistory ) { communicationService.CreateEmailCommunication( new List<string> { to }, fromName, from, from, subject, body, string.Empty, false, CommunicationRecipientStatus.Delivered, senderPersonAliasId ); } } } if ( createCommunicationHistory ) { rockContext.SaveChanges(); } } } } }
public void Persist(SystemEmail _systemEmail) { SystemEmailDAO dao = new SystemEmailDAO(MongoDB); dao.Persist(_systemEmail); }