private static void SendNotificationMessage(JobExecutionException jobException, ServiceJob job) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, null, new Lava.CommonMergeFieldsOptions { GetLegacyGlobalMergeFields = false }); mergeFields.Add("Job", job); try { if (jobException != null) { mergeFields.Add("Exception", Hash.FromAnonymousObject(jobException)); } } catch { // ignore } var notificationEmailAddresses = job.NotificationEmails.ResolveMergeFields(mergeFields).SplitDelimitedValues().ToList(); var emailMessage = new RockEmailMessage(Rock.SystemGuid.SystemCommunication.CONFIG_JOB_NOTIFICATION.AsGuid()); emailMessage.AdditionalMergeFields = mergeFields; // NOTE: the EmailTemplate may also have TO: defined, so even if there are no notificationEmailAddress defined for this specific job, we still should send the mail foreach (var notificationEmailAddress in notificationEmailAddresses) { emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(notificationEmailAddress, null)); } emailMessage.Send(); }
public void HttpSendRockMessage() { var errorMessages = new List <string>(); var binaryFileService = new BinaryFileService(new RockContext()); var rockEmailMessage = new RockEmailMessage { FromName = "Spark Info", FromEmail = "*****@*****.**", ReplyToEmail = "*****@*****.**", CCEmails = new List <string>() { "*****@*****.**" }, //BCCEmails = new List<string>() { "*****@*****.**" }, Subject = "Mailgun HTTP Tests", Message = "This is a test of the mailgun HTTP API", //MessageMetaData = new Dictionary<string, string>() { { "", "" }, { "", "" } }, Attachments = new List <BinaryFile>() { binaryFileService.Get(10) } }; rockEmailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous("*****@*****.**", null)); var mailgunHttp = new MailgunHttp(); mailgunHttp.Send(rockEmailMessage, 0, null, out errorMessages); Assert.True(!errorMessages.Any()); Assert.Equal(System.Net.HttpStatusCode.OK, mailgunHttp.Response.StatusCode); }
private void SendEmail(List <Person> emailrecipients, Dictionary <string, object> mergeFields) { var message = new RockEmailMessage(); message.EnabledLavaCommands = GetAttributeValue("EnabledLavaCommands"); foreach (var person in emailrecipients) { if (person.Id > 0) { message.AddRecipient(new RockEmailMessageRecipient(person, mergeFields)); } else { message.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(person.Email, mergeFields)); } } message.FromEmail = tbEmail.Text; message.FromName = tbFirstName.Text + " " + tbLastName.Text; message.Subject = GetAttributeValue("Subject"); message.Message = GetAttributeValue("MessageBody"); message.AppRoot = ResolveRockUrl("~/"); message.ThemeRoot = ResolveRockUrl("~~/"); message.CreateCommunicationRecord = GetAttributeValue("SaveCommunicationHistory").AsBoolean(); message.Send(); }
/// <summary> /// Checks the integrity of the database /// </summary> /// <param name="commandTimeout">The command timeout.</param> /// <param name="alertEmail">The alert email.</param> /// <returns></returns> private bool IntegrityCheck(int commandTimeout, string alertEmail) { string databaseName = new RockContext().Database.Connection.Database; string integrityQuery = $"DBCC CHECKDB('{ databaseName }',NOINDEX) WITH PHYSICAL_ONLY, NO_INFOMSGS"; bool checkPassed = true; Stopwatch stopwatch = Stopwatch.StartNew(); // DBCC CHECKDB will return a count of how many issues there were int integrityErrorCount = DbService.ExecuteCommand(integrityQuery, System.Data.CommandType.Text, null, commandTimeout); stopwatch.Stop(); var databaseMaintenanceTaskResult = new DatabaseMaintenanceTaskResult { Title = "Integrity Check", Elapsed = stopwatch.Elapsed }; _databaseMaintenanceTaskResults.Add(databaseMaintenanceTaskResult); if (integrityErrorCount > 0) { // oh no... checkPassed = false; string errorMessage = $"Some errors were reported when running a database integrity check on your Rock database. We'd recommend running the command below under 'Admin Tools > Power Tools > SQL Command' to get further details. <p>DBCC CHECKDB ('{ databaseName }') WITH NO_INFOMSGS, ALL_ERRORMSGS</p>"; var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null, null); mergeFields.Add("ErrorMessage", errorMessage); mergeFields.Add("Errors", integrityErrorCount); databaseMaintenanceTaskResult.Exception = new Exception(errorMessage); if (alertEmail.IsNotNullOrWhiteSpace()) { var globalAttributes = GlobalAttributesCache.Get(); string emailHeader = globalAttributes.GetValue("EmailHeader"); string emailFooter = globalAttributes.GetValue("EmailFooter"); string messageBody = $"{emailHeader} {errorMessage} <p><small>This message was generated from the Rock Database Maintenance Job</small></p>{emailFooter}"; var emailMessage = new RockEmailMessage(); var alertEmailList = alertEmail.Split(',').ToList(); var recipients = alertEmailList.Select(a => RockEmailMessageRecipient.CreateAnonymous(a, mergeFields)).ToList(); emailMessage.Subject = "Rock: Database Integrity Check Error"; emailMessage.Message = messageBody; emailMessage.Send(); } } return(checkPassed); }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public virtual void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; int alertPeriod = dataMap.GetInt("AlertPeriod"); Guid? systemEmailGuid = dataMap.GetString("AlertEmail").AsGuidOrNull(); List <string> recipientEmails = dataMap.GetString("AlertRecipients").SplitDelimitedValues().ToList(); if (systemEmailGuid.HasValue && recipientEmails.Any()) { var rockContext = new RockContext(); int expirationDays = GetJobAttributeValue("ExpirationPeriod", 3, rockContext); var beginWindow = RockDateTime.Now.AddDays(0 - expirationDays); var cutoffTime = RockDateTime.Now.AddMinutes(0 - alertPeriod); var communications = new CommunicationService(rockContext) .GetQueued(expirationDays, alertPeriod, false, false) .NotRecentlyApproved(cutoffTime) .IfScheduledAreInWindow(beginWindow, cutoffTime) .OrderBy(c => c.Id) .ToList(); if (communications.Any()) { var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("Communications", communications); var emailMessage = new RockEmailMessage(systemEmailGuid.Value); foreach (var email in recipientEmails) { emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(email, mergeFields)); } var errors = new List <string>(); emailMessage.Send(out errors); context.Result = string.Format("Notified about {0} queued communications. {1} errors encountered.", communications.Count, errors.Count); if (errors.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append("Errors: "); errors.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errorMessage = sb.ToString(); context.Result += errorMessage; throw new Exception(errorMessage); } } } }
/// <summary> /// Gets the contact recipient as either an email to the person that registered, or as an anonymous email to the specified contact email if it is different than the person's email. /// </summary> /// <param name="mergeObjects">The merge objects.</param> /// <returns></returns> public RockMessageRecipient GetContactRecipient(Dictionary <string, object> mergeObjects) { var person = this.ContactPersonAlias?.Person; string personEmail = person?.Email; var contactEmail = this.ContactEmail; if (personEmail == contactEmail) { return(new RockEmailMessageRecipient(person, mergeObjects)); } else { return(RockEmailMessageRecipient.CreateAnonymous(contactEmail, mergeObjects)); } }
private void SendEmailToMember(GroupMember member, Group group, KeyValuePair <int, List <DateTime> > occGroup) { var email = staffEmail; if (member.IsNotNull()) { email = member.Person.Email; } if (email.IsNotNullOrWhiteSpace()) { groupsNotified.Add(group.Id); var mergeObjects = Rock.Lava.LavaHelper.GetCommonMergeFields(null, member.IsNotNull() ? member.Person : null); mergeObjects.Add("Person", member.IsNotNull() ? member.Person : null); mergeObjects.Add("Group", group); mergeObjects.Add("Occurrence", occGroup.Value.Max()); var recipients = new List <RockEmailMessageRecipient>(); recipients.Add(RockEmailMessageRecipient.CreateAnonymous(email, mergeObjects)); var emailMessage = new RockEmailMessage(systemEmailGuid); emailMessage.SetRecipients(recipients); var errors = new List <string>(); emailMessage.Send(out errors); if (errors.Any()) { errorCount += errors.Count; errorMessages.AddRange(errors); } else { attendanceRemindersSent++; } } else { errorCount += 1; errorMessages.Add(string.Format("No email specified for group {0} and no fallback email provided.", group.Id)); } }
/// <summary> /// Sends the specified recipient emails. /// </summary> /// <param name="recipientEmails">The recipient emails.</param> /// <param name="fromEmail">From email.</param> /// <param name="fromName">From name.</param> /// <param name="subject">The subject.</param> /// <param name="body">The body.</param> /// <param name="mergeFields">The merge fields.</param> /// <param name="createCommunicationRecord">if set to <c>true</c> [create communication record].</param> /// <param name="metaData">The meta data.</param> private void Send(string recipientEmails, string fromEmail, string fromName, string subject, string body, Dictionary <string, object> mergeFields, bool createCommunicationRecord, Dictionary <string, string> metaData) { var recipients = recipientEmails.ResolveMergeFields(mergeFields).SplitDelimitedValues().Select(e => RockEmailMessageRecipient.CreateAnonymous(e, mergeFields)).ToList(); Send(recipients, fromEmail, fromName, subject, body, createCommunicationRecord, metaData); }
/// <summary> /// Handles the Click event of the btnSend 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 btnSend_Click(object sender, EventArgs e) { var url = LinkedPageUrl(AttributeKey.ConfirmationPage); if (string.IsNullOrWhiteSpace(url)) { url = ResolveRockUrl("~/ConfirmAccount"); } var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson); mergeFields.Add("ConfirmAccountUrl", RootPath + url.TrimStart(new char[] { '/' })); var results = new List <IDictionary <string, object> >(); var rockContext = new RockContext(); var personService = new PersonService(rockContext); var userLoginService = new UserLoginService(rockContext); bool hasAccountWithPasswordResetAbility = false; List <string> accountTypes = new List <string>(); foreach (Person person in personService.GetByEmail(tbEmail.Text) .Where(p => p.Users.Any())) { var users = new List <UserLogin>(); List <string> supportsChangePassword = new List <string>(); foreach (UserLogin user in userLoginService.GetByPersonId(person.Id)) { if (user.EntityType != null) { var component = AuthenticationContainer.GetComponent(user.EntityType.Name); if (component != null && !component.RequiresRemoteAuthentication) { if (component.SupportsChangePassword) { supportsChangePassword.Add(user.UserName); } users.Add(user); hasAccountWithPasswordResetAbility = true; } accountTypes.Add(user.EntityType.FriendlyName); } } var resultsDictionary = new Dictionary <string, object>(); resultsDictionary.Add("Person", person); resultsDictionary.Add("Users", users); resultsDictionary.Add("SupportsChangePassword", supportsChangePassword); results.Add(resultsDictionary); } if (results.Count > 0 && hasAccountWithPasswordResetAbility) { mergeFields.Add("Results", results.ToArray()); var emailMessage = new RockEmailMessage(GetAttributeValue(AttributeKey.EmailTemplate).AsGuid()); emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(tbEmail.Text, mergeFields)); emailMessage.AppRoot = ResolveRockUrlIncludeRoot("~/"); emailMessage.ThemeRoot = ResolveRockUrlIncludeRoot("~~/"); emailMessage.CreateCommunicationRecord = GetAttributeValue(AttributeKey.CreateCommunicationRecord).AsBoolean(); emailMessage.Send(); pnlEntry.Visible = false; pnlSuccess.Visible = true; } else if (results.Count > 0) { // The person has user accounts but none of them are allowed to have their passwords reset (Facebook/Google/etc). lWarning.Text = string.Format( @"<p>We were able to find the following accounts for this email, but none of them are able to be reset from this website.</p> <p>Accounts:<br /> {0}</p> <p>To create a new account with a username and password please see our <a href='{1}'>New Account</a> page.</p>", string.Join(",", accountTypes), ResolveRockUrl("~/NewAccount")); pnlWarning.Visible = true; } else { pnlWarning.Visible = true; } }
/// <summary> /// Sends the notification. /// </summary> /// <param name="ex">The ex.</param> private void SendNotification(Exception ex) { int?pageId = (Context.Items["Rock:PageId"] ?? string.Empty).ToString().AsIntegerOrNull(); int?siteId = (Context.Items["Rock:SiteId"] ?? string.Empty).ToString().AsIntegerOrNull(); PersonAlias personAlias = null; Person person = null; try { var user = UserLoginService.GetCurrentUser(); if (user != null && user.Person != null) { person = user.Person; personAlias = user.Person.PrimaryAlias; } } catch { // ignore exception } try { ExceptionLogService.LogException(ex, Context, pageId, siteId, personAlias); } catch { // ignore exception } try { bool sendNotification = true; var globalAttributesCache = GlobalAttributesCache.Get(); string filterSettings = globalAttributesCache.GetValue("EmailExceptionsFilter"); if (!string.IsNullOrWhiteSpace(filterSettings)) { // Get the current request's list of server variables var serverVarList = Context.Request.ServerVariables; string[] nameValues = filterSettings.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (string nameValue in nameValues) { string[] nameAndValue = nameValue.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries); { if (nameAndValue.Length == 2) { switch (nameAndValue[0].ToLower()) { case "type": { if (ex.GetType().Name.ToLower().Contains(nameAndValue[1].ToLower())) { sendNotification = false; } break; } case "source": { if (ex.Source.ToLower().Contains(nameAndValue[1].ToLower())) { sendNotification = false; } break; } case "message": { if (ex.Message.ToLower().Contains(nameAndValue[1].ToLower())) { sendNotification = false; } break; } case "stacktrace": { if (ex.StackTrace.ToLower().Contains(nameAndValue[1].ToLower())) { sendNotification = false; } break; } default: { var serverValue = serverVarList[nameAndValue[0]]; if (serverValue != null && serverValue.ToUpper().Contains(nameAndValue[1].ToUpper().Trim())) { sendNotification = false; } break; } } } } if (!sendNotification) { break; } } } if (!sendNotification) { return; } // get email addresses to send to string emailAddressesList = globalAttributesCache.GetValue("EmailExceptionsList"); if (!string.IsNullOrWhiteSpace(emailAddressesList)) { string[] emailAddresses = emailAddressesList.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (emailAddresses.Length > 0) { string siteName = "Rock"; if (siteId.HasValue) { var site = SiteCache.Get(siteId.Value); if (site != null) { siteName = site.Name; } } var exceptionDetails = string.Format( "An error occurred{0} on the {1} site on page: <br>{2}<p>{3}</p>", person != null ? " for " + person.FullName : string.Empty, siteName, Context.Request.UrlProxySafe().OriginalString, FormatException(ex, string.Empty)); // setup merge codes for email var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("ExceptionDetails", exceptionDetails); try { mergeFields.Add("Exception", ex); } catch { // ignore } mergeFields.Add("Person", person); var recipients = new List <RockEmailMessageRecipient>(); foreach (string emailAddress in emailAddresses) { recipients.Add(RockEmailMessageRecipient.CreateAnonymous(emailAddress, mergeFields)); } if (recipients.Any()) { var message = new RockEmailMessage(Rock.SystemGuid.SystemCommunication.CONFIG_EXCEPTION_NOTIFICATION.AsGuid()); message.SetRecipients(recipients); message.Send(); } } } } catch { // ignore exception } }
/// <summary> /// Job that will run quick SQL queries on a schedule. /// /// 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; // get job parms bool runIntegrityCheck = dataMap.GetBoolean("RunIntegrityCheck"); bool runIndexRebuild = dataMap.GetBoolean("RunIndexRebuild"); bool runStatisticsUpdate = dataMap.GetBoolean("RunStatisticsUpdate"); int commandTimeout = dataMap.GetString("CommandTimeout").AsInteger(); int minimumIndexPageCount = dataMap.GetString("MinimumIndexPageCount").AsInteger(); int minimunFragmentationPercentage = dataMap.GetString("MinimumFragmentationPercentage").AsInteger(); int rebuildThresholdPercentage = dataMap.GetString("RebuildThresholdPercentage").AsInteger(); bool useONLINEIndexRebuild = dataMap.GetString("UseONLINEIndexRebuild").AsBoolean(); string alertEmail = dataMap.GetString("AlertEmail"); StringBuilder resultsMessage = new StringBuilder(); Stopwatch stopwatch; bool errorsFound = false; // run integrity check if (runIntegrityCheck) { string databaseName = new RockContext().Database.Connection.Database; string integrityQuery = $"DBCC CHECKDB('{ databaseName }',NOINDEX) WITH PHYSICAL_ONLY, NO_INFOMSGS"; stopwatch = Stopwatch.StartNew(); int errors = DbService.ExecuteCommand(integrityQuery, System.Data.CommandType.Text, null, commandTimeout); stopwatch.Stop(); resultsMessage.Append($"Integrity Check took {( stopwatch.ElapsedMilliseconds / 1000 )}s"); if (errors > 0) { // oh no... errorsFound = true; string errorMessage = $"Some errors were reported when running a database integrity check on your Rock database. We'd recommend running the command below under 'Admin Tools > Power Tools > SQL Command' to get further details. <p>DBCC CHECKDB ('{ databaseName }') WITH NO_INFOMSGS, ALL_ERRORMSGS</p>"; var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null, null); mergeFields.Add("ErrorMessage", errorMessage); mergeFields.Add("Errors", errors); resultsMessage.Append(errorMessage); if (alertEmail.IsNotNullOrWhiteSpace()) { var globalAttributes = GlobalAttributesCache.Get(); string emailHeader = globalAttributes.GetValue("EmailHeader"); string emailFooter = globalAttributes.GetValue("EmailFooter"); string messageBody = $"{emailHeader} {errorMessage} <p><small>This message was generated from the Rock Database Maintenance Job</small></p>{emailFooter}"; var emailMessage = new RockEmailMessage(); var alertEmailList = alertEmail.Split(',').ToList(); var recipients = alertEmailList.Select(a => RockEmailMessageRecipient.CreateAnonymous(a, mergeFields)).ToList(); emailMessage.Subject = "Rock: Database Integrity Check Error"; emailMessage.Message = messageBody; emailMessage.Send(); } } } if (!errorsFound) { // rebuild fragmented indexes if (runIndexRebuild) { Dictionary <string, object> parms = new Dictionary <string, object>(); parms.Add("@PageCountLimit", minimumIndexPageCount); parms.Add("@MinFragmentation", minimunFragmentationPercentage); parms.Add("@MinFragmentationRebuild", rebuildThresholdPercentage); parms.Add("@UseONLINEIndexRebuild", useONLINEIndexRebuild); stopwatch = Stopwatch.StartNew(); DbService.ExecuteCommand("spDbaRebuildIndexes", System.Data.CommandType.StoredProcedure, parms, commandTimeout); stopwatch.Stop(); resultsMessage.Append($", Index Rebuild took {( stopwatch.ElapsedMilliseconds / 1000 )}s"); } // update statistics if (runStatisticsUpdate) { // derived from http://www.sqlservercentral.com/scripts/Indexing/31823/ // NOTE: Can't use sp_MSForEachtable because it isn't supported on AZURE (and it is undocumented) // NOTE: Can't use sp_updatestats because it requires membership in the sysadmin fixed server role, or ownership of the database (dbo) string statisticsQuery = @" DECLARE updatestats CURSOR FOR SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME OPEN updatestats DECLARE @tablename NVARCHAR(max) DECLARE @Statement NVARCHAR(max) FETCH NEXT FROM updatestats INTO @tablename WHILE (@@FETCH_STATUS = 0) BEGIN PRINT N'UPDATING STATISTICS [' + @tablename + ']' SET @Statement = 'UPDATE STATISTICS [' + @tablename + ']' EXEC sp_executesql @Statement FETCH NEXT FROM updatestats INTO @tablename END CLOSE updatestats DEALLOCATE updatestats "; stopwatch = Stopwatch.StartNew(); DbService.ExecuteCommand(statisticsQuery, System.Data.CommandType.Text, null, commandTimeout); stopwatch.Stop(); resultsMessage.Append($", Statistics Update took {( stopwatch.ElapsedMilliseconds / 1000 )}s"); } } context.Result = resultsMessage.ToString().TrimStart(','); }
/// <summary> /// Called by the <see cref="IScheduler"/> after a <see cref="IJobDetail"/> /// has been executed, and before the associated <see cref="Quartz.Spi.IOperableTrigger"/>'s /// <see cref="Quartz.Spi.IOperableTrigger.Triggered"/> method has been called. /// </summary> /// <param name="context"></param> /// <param name="jobException"></param> public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException) { bool sendMessage = false; // get job id int jobId = context.GetJobId(); // load job var rockContext = new RockContext(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job == null) { // if job was deleted or wasn't found, just exit return; } // if notification status is all set flag to send message if (job.NotificationStatus == JobNotificationStatus.All) { sendMessage = true; } // set last run date job.LastRunDateTime = RockDateTime.Now; // context.FireTimeUtc.Value.DateTime.ToLocalTime(); // set run time job.LastRunDurationSeconds = Convert.ToInt32(context.JobRunTime.TotalSeconds); // set the scheduler name job.LastRunSchedulerName = context.Scheduler.SchedulerName; // determine if an error occurred if (jobException == null) { job.LastSuccessfulRunDateTime = job.LastRunDateTime; job.LastStatus = "Success"; if (context.Result is string) { job.LastStatusMessage = context.Result as string; } else { job.LastStatusMessage = string.Empty; } // determine if message should be sent if (job.NotificationStatus == JobNotificationStatus.Success) { sendMessage = true; } } else { Exception exceptionToLog = jobException; // drill down to the interesting exception while (exceptionToLog is Quartz.SchedulerException && exceptionToLog.InnerException != null) { exceptionToLog = exceptionToLog.InnerException; } // log the exception to the database ExceptionLogService.LogException(exceptionToLog, null); var summaryException = exceptionToLog; // put the exception into the status job.LastStatus = "Exception"; AggregateException aggregateException = summaryException as AggregateException; if (aggregateException != null && aggregateException.InnerExceptions != null && aggregateException.InnerExceptions.Count == 1) { // if it's an aggregate, but there is only one, convert it to a single exception summaryException = aggregateException.InnerExceptions[0]; aggregateException = null; } if (aggregateException != null) { var firstException = aggregateException.InnerExceptions.First(); job.LastStatusMessage = "One or more exceptions occurred. First Exception: " + firstException.Message; summaryException = firstException; } else { job.LastStatusMessage = summaryException.Message; } if (job.NotificationStatus == JobNotificationStatus.Error) { sendMessage = true; } } rockContext.SaveChanges(); // Add job history AddServiceJobHistory(job, rockContext); // send notification if (sendMessage) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, null, new Lava.CommonMergeFieldsOptions { GetLegacyGlobalMergeFields = false }); mergeFields.Add("Job", job); try { if (jobException != null) { mergeFields.Add("Exception", Hash.FromAnonymousObject(jobException)); } } catch { // ignore } var notificationEmailAddresses = job.NotificationEmails.ResolveMergeFields(mergeFields).SplitDelimitedValues().ToList(); var emailMessage = new RockEmailMessage(Rock.SystemGuid.SystemEmail.CONFIG_JOB_NOTIFICATION.AsGuid()); emailMessage.AdditionalMergeFields = mergeFields; // NOTE: the EmailTemplate may also have TO: defined, so even if there are no notificationEmailAddress defined for this specific job, we still should send the mail foreach (var notificationEmailAddress in notificationEmailAddresses) { emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(notificationEmailAddress, null)); } emailMessage.Send(); } }
/// <summary> /// Sends the specified recipient emails. /// </summary> /// <param name="recipientEmails">The recipient emails.</param> /// <param name="fromEmail">From email.</param> /// <param name="fromName">From name.</param> /// <param name="subject">The subject.</param> /// <param name="body">The body.</param> /// <param name="ccEmails">The CC emails.</param> /// <param name="bccEmails">The BCC emails.</param> /// <param name="mergeFields">The merge fields.</param> /// <param name="createCommunicationRecord">if set to <c>true</c> [create communication record].</param> /// <param name="attachments">The attachments.</param> /// <param name="errorMessages">The error messages.</param> private void Send(string recipientEmails, string fromEmail, string fromName, string subject, string body, List <string> ccEmails, List <string> bccEmails, Dictionary <string, object> mergeFields, bool createCommunicationRecord, BinaryFile[] attachments, out List <string> errorMessages) { var recipients = recipientEmails.ResolveMergeFields(mergeFields).SplitDelimitedValues().Select(e => RockEmailMessageRecipient.CreateAnonymous(e, mergeFields)).ToList(); Send(recipients, fromEmail, fromName, subject, body, ccEmails, bccEmails, createCommunicationRecord, attachments, out errorMessages); }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages) { errorMessages = new List <string>(); var mergeFields = GetMergeFields(action); var recipients = new List <RockMessageRecipient>(); string to = GetAttributeValue(action, "Recipient"); Guid?guid = to.AsGuidOrNull(); if (guid.HasValue) { var attribute = AttributeCache.Get(guid.Value, rockContext); if (attribute != null) { string toValue = action.GetWorkflowAttributeValue(guid.Value); if (!string.IsNullOrWhiteSpace(toValue)) { switch (attribute.FieldType.Class) { case "Rock.Field.Types.TextFieldType": case "Rock.Field.Types.EmailFieldType": { var recipientList = toValue.SplitDelimitedValues().ToList(); foreach (string recipient in recipientList) { recipients.Add(RockEmailMessageRecipient.CreateAnonymous(recipient, mergeFields)); } break; } case "Rock.Field.Types.PersonFieldType": { Guid personAliasGuid = toValue.AsGuid(); if (!personAliasGuid.IsEmpty()) { var person = new PersonAliasService(rockContext).Queryable() .Where(a => a.Guid.Equals(personAliasGuid)) .Select(a => a.Person) .FirstOrDefault(); if (person == null) { action.AddLogEntry("Invalid Recipient: Person not found", true); } else if (string.IsNullOrWhiteSpace(person.Email)) { action.AddLogEntry("Email was not sent: Recipient does not have an email address", true); } else if (!(person.IsEmailActive)) { action.AddLogEntry("Email was not sent: Recipient email is not active", true); } else if (person.EmailPreference == EmailPreference.DoNotEmail) { action.AddLogEntry("Email was not sent: Recipient has requested 'Do Not Email'", true); } else { var personDict = new Dictionary <string, object>(mergeFields); personDict.Add("Person", person); recipients.Add(new RockEmailMessageRecipient(person, personDict)); } } break; } case "Rock.Field.Types.GroupFieldType": case "Rock.Field.Types.SecurityRoleFieldType": { int? groupId = toValue.AsIntegerOrNull(); Guid?groupGuid = toValue.AsGuidOrNull(); IQueryable <GroupMember> qry = null; // Handle situations where the attribute value is the ID if (groupId.HasValue) { qry = new GroupMemberService(rockContext).GetByGroupId(groupId.Value); } // Handle situations where the attribute value stored is the Guid else if (groupGuid.HasValue) { qry = new GroupMemberService(rockContext).GetByGroupGuid(groupGuid.Value); } else { action.AddLogEntry("Invalid Recipient: No valid group id or Guid", true); } if (qry != null) { foreach (var person in qry .Where(m => m.GroupMemberStatus == GroupMemberStatus.Active) .Select(m => m.Person)) { if (person.IsEmailActive && person.EmailPreference != EmailPreference.DoNotEmail && !string.IsNullOrWhiteSpace(person.Email)) { var personDict = new Dictionary <string, object>(mergeFields); personDict.Add("Person", person); recipients.Add(new RockEmailMessageRecipient(person, personDict)); } } } break; } } } } } else { var recipientList = to.ResolveMergeFields(mergeFields).SplitDelimitedValues().ToList(); foreach (string recipient in recipientList) { recipients.Add(RockEmailMessageRecipient.CreateAnonymous(recipient, mergeFields)); } } if (recipients.Any()) { var emailMessage = new RockEmailMessage(GetAttributeValue(action, "SystemEmail").AsGuid()); emailMessage.SetRecipients(recipients); emailMessage.CreateCommunicationRecord = GetAttributeValue(action, "SaveCommunicationHistory").AsBoolean(); emailMessage.Send(); } return(true); }
/// <summary> /// Starts the refund process. /// </summary> private void StartRefunds() { long totalMilliseconds = 0; var importTask = new Task(() => { // wait a little so the browser can render and start listening to events System.Threading.Thread.Sleep(1000); _hubContext.Clients.All.showButtons(this.SignalRNotificationKey, false); Stopwatch stopwatch = Stopwatch.StartNew(); List <int> registrationTemplateIds = rtpRegistrationTemplate.ItemIds.AsIntegerList(); registrationTemplateIds.RemoveAll(i => i.Equals(0)); RockContext rockContext = new RockContext(); SystemCommunicationService systemCommunicationService = new SystemCommunicationService(rockContext); if (pnlRegistration.Visible && registrationTemplateIds.Count > 0) { List <int> registrationInstanceIds = new List <int>(); if (ddlRegistrationInstance.SelectedValueAsId().HasValue&& ddlRegistrationInstance.SelectedValueAsId() > 0) { registrationInstanceIds.Add(ddlRegistrationInstance.SelectedValueAsId().Value); } else { RegistrationTemplateService registrationTemplateService = new RegistrationTemplateService(rockContext); var templates = registrationTemplateService.GetByIds(rtpRegistrationTemplate.ItemIds.AsIntegerList()); int registrationCount = templates.SelectMany(t => t.Instances).SelectMany(i => i.Registrations).Count(); registrationInstanceIds.AddRange(templates.SelectMany(t => t.Instances).OrderBy(i => i.Name).Select(i => i.Id)); } RegistrationInstanceService registrationInstanceService = new RegistrationInstanceService(rockContext); // Load the registration instance and then iterate through all registrations. var registrations = registrationInstanceService.Queryable().Where(ri => registrationInstanceIds.Contains(ri.Id)).SelectMany(ri => ri.Registrations); int j = 1; foreach (Registration registration in registrations) { bool issuedRefund = false; OnProgress("Processing registration refund " + j + " of " + registrations.Count()); foreach (var payment in registration.GetPayments(rockContext)) { issuedRefund = issueRefund(payment.Transaction, "Registration", registration.FirstName + " " + registration.LastName); } j++; // Send an email if applicable if (issuedRefund && !string.IsNullOrWhiteSpace(registration.ConfirmationEmail) && ddlSystemCommunication.SelectedValueAsInt().HasValue&& ddlSystemCommunication.SelectedValueAsInt() > 0) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage); mergeFields.Add("Registration", registration); SystemCommunication systemCommunication = systemCommunicationService.Get(ddlSystemCommunication.SelectedValueAsInt().Value); var emailMessage = new RockEmailMessage(systemCommunication); emailMessage.AdditionalMergeFields = mergeFields; emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(registration.ConfirmationEmail, mergeFields)); emailMessage.CreateCommunicationRecord = true; emailMessage.Send(); } } } if (pnlTransactionCodes.Visible && tbTransactionCodes.Text.Length > 0) { var codes = tbTransactionCodes.Text.SplitDelimitedValues(); FinancialTransactionService financialTransactionService = new FinancialTransactionService(rockContext); var transactions = financialTransactionService.Queryable().Where(ft => codes.Contains(ft.TransactionCode)); int j = 0; foreach (var transaction in transactions) { OnProgress("Processing transaction refund " + j + " of " + transactions.Count()); var issuedRefund = issueRefund(transaction, "Transaction", transaction.AuthorizedPersonAlias != null ? transaction.AuthorizedPersonAlias.Person.FullName : "Unknown"); // Send an email if applicable if (issuedRefund && transaction.AuthorizedPersonAlias != null && !string.IsNullOrWhiteSpace(transaction.AuthorizedPersonAlias.Person.Email) && ddlSystemCommunication.SelectedValueAsInt().HasValue&& ddlSystemCommunication.SelectedValueAsInt() > 0) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage); mergeFields.Add("Transaction", transaction); SystemCommunication systemCommunication = systemCommunicationService.Get(ddlSystemCommunication.SelectedValueAsInt().Value); var emailMessage = new RockEmailMessage(systemCommunication); emailMessage.AdditionalMergeFields = mergeFields; emailMessage.FromEmail = ebEmail.Text; emailMessage.AddRecipient(new RockEmailMessageRecipient(transaction.AuthorizedPersonAlias.Person, mergeFields)); emailMessage.CreateCommunicationRecord = true; emailMessage.Send(); } } } stopwatch.Stop(); totalMilliseconds = stopwatch.ElapsedMilliseconds; _hubContext.Clients.All.showButtons(this.SignalRNotificationKey, true); }); importTask.ContinueWith((t) => { if (t.IsFaulted) { foreach (var exception in t.Exception.InnerExceptions) { LogException(exception); } OnProgress("ERROR: " + t.Exception.Message); } else { OnProgress(string.Format("{0} Complete: [{1}ms]", "All refunds have been issued.", totalMilliseconds)); } }); importTask.Start(); }
/// <summary> /// Sends the email. /// </summary> private void SendEmail() { // ensure this is not from a bot string[] bots = GlobalAttributesCache.Value("EmailExceptionsFilter").Split('|'); string test = GlobalAttributesCache.Value("EmailExceptionsFilter"); var serverVarList = Context.Request.ServerVariables; bool isBot = false; foreach (var bot in bots) { string[] botParms = bot.Split('^'); if (botParms.Length == 2) { var serverValue = serverVarList[botParms[0]]; if (serverValue != null && serverValue.ToUpper().Contains(botParms[1].ToUpper().Trim())) { isBot = true; } } } if (!isBot) { var message = new RockEmailMessage(); message.EnabledLavaCommands = GetAttributeValue("EnabledLavaCommands"); // create merge objects var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson); // create merge object for fields Regex rgxRockControls = new Regex(@"^ctl\d*\$.*"); var formFields = new Dictionary <string, object>(); for (int i = 0; i < Request.Form.Count; i++) { string formFieldKey = Request.Form.GetKey(i); if (formFieldKey != null && formFieldKey.Substring(0, 1) != "_" && formFieldKey != "searchField_hSearchFilter" && formFieldKey != "send" && !rgxRockControls.IsMatch(formFieldKey)) { formFields.Add(formFieldKey, Request.Form[formFieldKey]); } } mergeFields.Add("FormFields", formFields); // get attachments var rockContext = new RockContext(); var binaryFileService = new BinaryFileService(rockContext); var binaryFileType = new BinaryFileTypeService(rockContext).Get(Rock.SystemGuid.BinaryFiletype.DEFAULT.AsGuid()); for (int i = 0; i < Request.Files.Count; i++) { var uploadedFile = Request.Files[i]; if (uploadedFile.ContentLength > 0 && uploadedFile.FileName.IsNotNullOrWhiteSpace()) { var binaryFile = new BinaryFile(); binaryFileService.Add(binaryFile); binaryFile.BinaryFileTypeId = binaryFileType.Id; binaryFile.IsTemporary = false; binaryFile.MimeType = uploadedFile.ContentType; binaryFile.FileSize = uploadedFile.ContentLength; binaryFile.FileName = Path.GetFileName(uploadedFile.FileName); binaryFile.ContentStream = uploadedFile.InputStream; rockContext.SaveChanges(); message.Attachments.Add(binaryFileService.Get(binaryFile.Id)); } } mergeFields.Add("AttachmentCount", message.Attachments.Count); // send email foreach (string recipient in GetAttributeValue("RecipientEmail").Split(',').ToList()) { message.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(recipient, mergeFields)); } message.CCEmails = GetAttributeValue("CCEmail").ResolveMergeFields(mergeFields, GetAttributeValue("EnabledLavaCommands")).Split(',').ToList(); message.BCCEmails = GetAttributeValue("BCCEmail").ResolveMergeFields(mergeFields, GetAttributeValue("EnabledLavaCommands")).Split(',').ToList(); message.FromEmail = GetAttributeValue("FromEmail").ResolveMergeFields(mergeFields, GetAttributeValue("EnabledLavaCommands")); message.FromName = GetAttributeValue("FromName").ResolveMergeFields(mergeFields, GetAttributeValue("EnabledLavaCommands")); message.Subject = GetAttributeValue("Subject"); message.Message = GetAttributeValue("MessageBody"); message.AppRoot = ResolveRockUrl("~/"); message.ThemeRoot = ResolveRockUrl("~~/"); message.CreateCommunicationRecord = GetAttributeValue("SaveCommunicationHistory").AsBoolean(); message.Send(); // set response if (!string.IsNullOrWhiteSpace(GetAttributeValue("ResponsePage"))) { NavigateToLinkedPage("ResponsePage"); } // display response message lResponse.Visible = true; lEmailForm.Visible = false; lResponse.Text = GetAttributeValue("ResponseMessage").ResolveMergeFields(mergeFields, GetAttributeValue("EnabledLavaCommands")); // show debug info if (GetAttributeValue("EnableDebug").AsBoolean() && IsUserAuthorized(Authorization.EDIT)) { lDebug.Visible = true; lDebug.Text = mergeFields.lavaDebugInfo(); } } else { lResponse.Visible = true; lEmailForm.Visible = false; lResponse.Text = "You appear to be a computer. Check the global attribute 'Email Exceptions Filter' if you are getting this in error."; } }
public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; var rockContext = new RockContext(); var jobService = new ServiceJobService(rockContext); GroupService groupService = new GroupService(rockContext); CategoryService categoryService = new CategoryService(rockContext); MetricService metricService = new MetricService(rockContext); var metricCategories = MetricCategoriesFieldAttribute.GetValueAsGuidPairs(dataMap.GetString("Metrics")); DateRange dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(dataMap.GetString("DateRange")); var systemEmail = dataMap.GetString("Email").AsGuidOrNull(); if (!systemEmail.HasValue) { throw new Exception("System Email is required!"); } // get job type id int jobId = Convert.ToInt16(context.JobDetail.Description); var job = jobService.Get(jobId); DateTime _midnightToday = RockDateTime.Today.AddDays(1); var currentDateTime = RockDateTime.Now; int recipients = 0; Group notificationGroup = groupService.Get(dataMap.GetString("NotificationGroup").AsGuid()); List <MetricCount> metricCounts = CampusCache.All().Select(c => new MetricCount() { Campus = c, TotalEntered = 0, TotalMetrics = 0 }).ToList(); List <Metric> metrics = new List <Metric>(); // If we have some reasonable data, go ahead and run the job if (notificationGroup != null && metricCategories.Count > 0 && dateRange.Start.HasValue && dateRange.End.HasValue) { foreach (MetricCategoryPair metricCategoryPair in metricCategories) { Metric metric = metricService.Get(metricCategoryPair.MetricGuid); metrics.Add(metric); // Split this by campus partition if (metric.MetricPartitions.Any(mp => mp.EntityType.Name.Contains("Campus"))) { foreach (CampusCache campus in CampusCache.All()) { // Check to see if we also have a schedule partition if (metric.MetricPartitions.Any(mp => mp.EntityType.Name.Contains("Schedule"))) { var services = GetServices(campus, dataMap, dateRange); metricCounts.Where(mc => mc.Campus == campus).FirstOrDefault().TotalMetrics += services.Count; foreach (var service in services) { var hasValues = metric.MetricValues.Where(mv => mv.MetricValuePartitions.Any(mvp => mvp.MetricPartition.EntityType.Name.Contains("Campus") && mvp.EntityId == campus.Id) && mv.MetricValuePartitions.Any(mvp => mvp.MetricPartition.EntityType.Name.Contains("Schedule") && mvp.EntityId == service.Id) && mv.MetricValueDateTime >= dateRange.Start.Value && mv.MetricValueDateTime <= dateRange.End.Value).Any(); if (hasValues) { metricCounts.Where(mc => mc.Campus == campus).FirstOrDefault().TotalEntered++; } } } else { // Add totals for metrics and, if values are entered, metrics entered. metricCounts.Where(mc => mc.Campus == campus).FirstOrDefault().TotalMetrics++; var hasValues = metric.MetricValues.Where(mv => mv.MetricValuePartitions.Any(mvp => mvp.MetricPartition.EntityType.Name.Contains("Campus") && mvp.EntityId == campus.Id) && mv.MetricValueDateTime >= dateRange.Start.Value && mv.MetricValueDateTime <= dateRange.End.Value).Any(); if (hasValues) { metricCounts.Where(mc => mc.Campus == campus).FirstOrDefault().TotalEntered++; } } } } } // Create the merge fields var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("MetricCounts", metricCounts); mergeFields.Add("Metrics", metrics); mergeFields.Add("DateRange", dateRange.ToString()); mergeFields.Add("LastRunDate", job.LastSuccessfulRunDateTime); // Setup the email and send it out! RockEmailMessage message = new RockEmailMessage(systemEmail.Value); message.AdditionalMergeFields = mergeFields; foreach (GroupMember member in notificationGroup.Members) { message.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(member.Person.Email, mergeFields)); recipients++; } message.SendSeperatelyToEachRecipient = true; message.Send(); } context.Result = string.Format("Sent " + recipients + " metric entry digest emails."); }
public HttpResponseMessage ForgotPassword([FromBody] string email) { OAuthContext oAuthContext = new OAuthContext(); ClientService clientService = new ClientService(oAuthContext); var clientId = HttpContext.Current.User.Identity.Name; Client oAuthClient = clientService.GetByApiKey(clientId.AsGuid()); if (oAuthClient.Active) { var response = new StandardResponse(); var rockContext = new Rock.Data.RockContext(); PersonService personService = new PersonService(rockContext); UserLoginService userLoginService = new UserLoginService(rockContext); bool hasAccountWithPasswordResetAbility = false; var results = new List <IDictionary <string, object> >(); // Check to make sure we have accounts matching the email address given foreach (Person person in personService.GetByEmail(email) .Where(p => p.Users.Any())) { var users = new List <UserLogin>(); foreach (UserLogin user in userLoginService.GetByPersonId(person.Id)) { if (user.EntityType != null) { var component = Rock.Security.AuthenticationContainer.GetComponent(user.EntityType.Name); if (component != null && !component.RequiresRemoteAuthentication) { users.Add(user); hasAccountWithPasswordResetAbility = true; } } } var resultsDictionary = new Dictionary <string, object>(); resultsDictionary.Add("Person", person); resultsDictionary.Add("Users", users); results.Add(resultsDictionary); } var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, null); // If we found matching accounts that have the ability to be reset, go ahead and send the email if (results.Count > 0 && hasAccountWithPasswordResetAbility) { mergeFields.Add("Results", results.ToArray()); var emailMessage = new RockEmailMessage(Rock.SystemGuid.SystemCommunication.SECURITY_FORGOT_USERNAME.AsGuid()); emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(email, mergeFields)); emailMessage.AppRoot = GlobalAttributesCache.Get().GetValue("PublicApplicationRoot").EnsureTrailingForwardslash(); emailMessage.CreateCommunicationRecord = false; emailMessage.Send(); response.Result = StandardResponse.ResultCode.Success; response.Message = "Forgot password email has been sent successfully."; } else { // the person either has no user accounts or none of them are allowed to have their passwords reset (Facebook/Google/SMS/etc) response.Result = StandardResponse.ResultCode.Error; response.Message = "No accounts associated with this email address are able to be reset via email."; } return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK, response)); } return(ControllerContext.Request.CreateResponse(HttpStatusCode.Forbidden)); }