/// <summary> /// Merges the values. /// </summary> /// <param name="configValues">The config values.</param> /// <param name="recipient">The recipient.</param> /// <returns></returns> protected Dictionary<string, object> MergeValues( Dictionary<string, object> configValues, CommunicationRecipient recipient ) { Dictionary<string, object> mergeValues = new Dictionary<string, object>(); configValues.ToList().ForEach( v => mergeValues.Add( v.Key, v.Value ) ); if ( recipient != null ) { if ( recipient.Person != null ) { mergeValues.Add( "Person", recipient.Person ); } // Add any additional merge fields created through a report foreach ( var mergeField in recipient.AdditionalMergeValues ) { if ( !mergeValues.ContainsKey( mergeField.Key ) ) { mergeValues.Add( mergeField.Key, mergeField.Value ); } } } return mergeValues; }
/// <summary> /// Handles the Click event of the btnTest control and sends a test communication to the /// current person if they have an email address on their record. /// </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 btnTest_Click(object sender, EventArgs e) { if (Page.IsValid && CurrentPerson != null) { SetActionButtons(resetToSend: true); if (string.IsNullOrWhiteSpace(CurrentPerson.Email)) { nbError.Text = "A test email cannot be sent because you do not have an email address."; nbError.Visible = true; return; } // Get existing or new communication record var communication = GetCommunication(new RockContext(), null); if (communication != null && CurrentPersonAliasId.HasValue) { // Using a new context (so that changes in the UpdateCommunication() are not persisted ) var testCommunication = new Rock.Model.Communication(); testCommunication.SenderPersonAliasId = communication.SenderPersonAliasId; testCommunication.Subject = communication.Subject; testCommunication.IsBulkCommunication = communication.IsBulkCommunication; testCommunication.MediumEntityTypeId = communication.MediumEntityTypeId; testCommunication.MediumDataJson = communication.MediumDataJson; testCommunication.AdditionalMergeFieldsJson = communication.AdditionalMergeFieldsJson; testCommunication.FutureSendDateTime = null; testCommunication.Status = CommunicationStatus.Approved; testCommunication.ReviewedDateTime = RockDateTime.Now; testCommunication.ReviewerPersonAliasId = CurrentPersonAliasId.Value; var testRecipient = new CommunicationRecipient(); if (communication.Recipients.Any()) { var recipient = communication.Recipients.FirstOrDefault(); testRecipient.AdditionalMergeValuesJson = recipient.AdditionalMergeValuesJson; } testRecipient.Status = CommunicationRecipientStatus.Pending; testRecipient.PersonAliasId = CurrentPersonAliasId.Value; testCommunication.Recipients.Add(testRecipient); var rockContext = new RockContext(); var communicationService = new CommunicationService(rockContext); communicationService.Add(testCommunication); rockContext.SaveChanges(); var medium = testCommunication.Medium; if (medium != null) { medium.Send(testCommunication); } communicationService.Delete(testCommunication); rockContext.SaveChanges(); nbTestResult.Visible = true; } } }
private Dictionary <string, string> CreateCommunication(List <PersonAlias> personAliases, RockContext rockContext = null) { if (rockContext == null) { rockContext = new RockContext(); } var service = new CommunicationService(rockContext); var communication = new Rock.Model.Communication(); communication.IsBulkCommunication = false; communication.Status = CommunicationStatus.Transient; communication.SenderPersonAliasId = CurrentPersonAliasId; service.Add(communication); // Get the primary aliases foreach (var personAlias in personAliases) { var recipient = new CommunicationRecipient(); recipient.PersonAliasId = personAlias.Id; communication.Recipients.Add(recipient); } rockContext.SaveChanges(); var queryParameters = new Dictionary <string, string>(); queryParameters.Add("CommunicationId", communication.Id.ToString()); return(queryParameters); }
/// <summary> /// Validates the recipient. /// </summary> /// <param name="recipient">The recipient.</param> /// <param name="isBulkCommunication">if set to <c>true</c> [is bulk communication].</param> /// <returns></returns> public override bool ValidRecipient(CommunicationRecipient recipient, bool isBulkCommunication) { bool valid = base.ValidRecipient(recipient, isBulkCommunication); if (valid) { var person = recipient?.PersonAlias?.Person; if (person != null) { if (string.IsNullOrWhiteSpace(person.Email)) { recipient.Status = CommunicationRecipientStatus.Failed; recipient.StatusNote = "No Email Address"; valid = false; } else if (person.EmailPreference == Model.EmailPreference.DoNotEmail) { recipient.Status = CommunicationRecipientStatus.Failed; recipient.StatusNote = "Communication Preference of 'Do Not Send Communication'"; valid = false; } else if (person.EmailPreference == Model.EmailPreference.NoMassEmails && isBulkCommunication) { recipient.Status = CommunicationRecipientStatus.Failed; recipient.StatusNote = "Communication Preference of 'No Bulk Communication'"; valid = false; } } } return(valid); }
/// <summary> /// Handles the Click event of the btnTest control and sends a test communication to the /// current person if they have an email address on their record. /// </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 btnTest_Click(object sender, EventArgs e) { if (Page.IsValid && CurrentPerson != null) { SetActionButtons(resetToSend: true); if (string.IsNullOrWhiteSpace(CurrentPerson.Email)) { nbError.Text = "A test email cannot be sent because you do not have an email address."; nbError.Visible = true; return; } // Get existing or new communication record var communication = GetCommunication(new RockContext(), null); if (communication != null && CurrentPersonAliasId.HasValue) { using (var rockContext = new RockContext()) { // Using a new context (so that changes in the UpdateCommunication() are not persisted ) var testCommunication = communication.Clone(false); testCommunication.Id = 0; testCommunication.Guid = Guid.Empty; testCommunication.EnabledLavaCommands = GetAttributeValue("EnabledLavaCommands"); testCommunication.ForeignGuid = null; testCommunication.ForeignId = null; testCommunication.ForeignKey = null; testCommunication.FutureSendDateTime = null; testCommunication.Status = CommunicationStatus.Approved; testCommunication.ReviewedDateTime = RockDateTime.Now; testCommunication.ReviewerPersonAliasId = CurrentPersonAliasId.Value; var testRecipient = new CommunicationRecipient(); if (communication.Recipients.Any()) { var recipient = communication.Recipients.FirstOrDefault(); testRecipient.AdditionalMergeValuesJson = recipient.AdditionalMergeValuesJson; } testRecipient.Status = CommunicationRecipientStatus.Pending; testRecipient.PersonAliasId = CurrentPersonAliasId.Value; testRecipient.MediumEntityTypeId = EntityTypeCache.Get(Rock.SystemGuid.EntityType.COMMUNICATION_MEDIUM_EMAIL.AsGuid()).Id; testCommunication.Recipients.Add(testRecipient); var communicationService = new CommunicationService(rockContext); communicationService.Add(testCommunication); rockContext.SaveChanges(); Communication.Send(testCommunication); communicationService.Delete(testCommunication); rockContext.SaveChanges(); } nbTestResult.Visible = true; } } }
/// <summary> /// Adds any additional headers. /// </summary> /// <param name="message">The message.</param> /// <param name="recipient">The recipient.</param> public override void AddAdditionalHeaders(MailMessage message, CommunicationRecipient recipient) { // add headers message.Headers.Add("X-Mailgun-Track", "yes"); message.Headers.Add("X-Mailgun-Track-Clicks", "yes"); message.Headers.Add("X-Mailgun-Track-Opens", "yes"); message.Headers.Add("X-Mailgun-Variables", String.Format(@"{{ ""communication_recipient_guid"":""{0}"" }}", recipient.Guid.ToString())); }
/// <summary> /// Initializes a new instance of the <see cref="RecipientData"/> class. /// </summary> /// <param name="recipient">The recipient.</param> /// <param name="mergeFields">The merge fields.</param> public RecipientData(CommunicationRecipient recipient, Dictionary <string, object> mergeFields) { var person = recipient?.PersonAlias?.Person; To = person?.Email; Name = person?.FullName; MergeFields = mergeFields != null ? mergeFields : new Dictionary <string, object>(); }
/// <summary> /// Adds any additional headers. /// </summary> /// <param name="message">The message.</param> /// <param name="recipient"></param> public override void AddAdditionalHeaders(MailMessage message, CommunicationRecipient recipient) { bool inlineCss = GetAttributeValue("InlineCSS").AsBoolean(true); // add mandrill headers message.Headers.Add("X-MC-Track", "opens, clicks"); message.Headers.Add("X-MC-InlineCSS", inlineCss.ToString().ToLower()); message.Headers.Add("X-MC-Metadata", String.Format(@"{{ ""communication_recipient_guid"":""{0}"" }}", recipient.Guid.ToString())); }
/// <summary> /// Handles the Click event of the 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 btnSendTest_Click(object sender, EventArgs e) { var recipients = new List <RecipientData>(); var personDict = new Dictionary <string, object>(); personDict.Add("Person", CurrentPerson); recipients.Add(new RecipientData(CurrentPerson.Email, personDict)); if (GetAttributeValue("CommunicationType") == "System") { Email.Send(ddlEmail.SelectedValueAsGuid().Value, recipients); } else { var communication = GetCommunication(new RockContext(), null); var testCommunication = new Communication(); testCommunication.SenderPersonAliasId = communication.SenderPersonAliasId; testCommunication.Subject = communication.Subject; testCommunication.IsBulkCommunication = communication.IsBulkCommunication; testCommunication.MediumEntityTypeId = communication.MediumEntityTypeId; testCommunication.MediumDataJson = communication.MediumDataJson; testCommunication.AdditionalMergeFieldsJson = communication.AdditionalMergeFieldsJson; testCommunication.FutureSendDateTime = null; testCommunication.Status = CommunicationStatus.Approved; testCommunication.ReviewedDateTime = RockDateTime.Now; testCommunication.ReviewerPersonAliasId = CurrentPersonAliasId.Value; var testRecipient = new CommunicationRecipient(); if (communication.Recipients.Any()) { var recipient = communication.Recipients.FirstOrDefault(); testRecipient.AdditionalMergeValuesJson = recipient.AdditionalMergeValuesJson; } testRecipient.Status = CommunicationRecipientStatus.Pending; testRecipient.PersonAliasId = CurrentPersonAliasId.Value; testCommunication.Recipients.Add(testRecipient); var rockContext = new RockContext(); var communicationService = new CommunicationService(rockContext); communicationService.Add(testCommunication); rockContext.SaveChanges(); var medium = testCommunication.Medium; if (medium != null) { medium.Send(testCommunication); } communicationService.Delete(testCommunication); rockContext.SaveChanges(); } nbSuccess.Text = string.Format("Sent test at {0}", DateTime.Now); }
/// <summary> /// Adds any additional headers. /// </summary> /// <param name="message">The message.</param> /// <param name="recipient"></param> public override void AddAdditionalHeaders( MailMessage message, CommunicationRecipient recipient ) { bool inlineCss = GetAttributeValue( "InlineCSS" ).AsBoolean( true ); // add mandrill headers message.Headers.Add( "X-MC-Track", "opens, clicks" ); message.Headers.Add( "X-MC-InlineCSS", inlineCss.ToString() ); message.Headers.Add( "X-MC-Metadata", String.Format( @"{{ ""communication_recipient_guid"":""{0}"" }}", recipient.Guid.ToString() ) ); }
/// <summary> /// Resolves the text and adds it to the CommunicationRecipient.SentMessage object. /// Don't forget to call RockContext.SaveChanges() to persist to the DB. /// </summary> /// <param name="content">The content.</param> /// <param name="person">The person.</param> /// <param name="enabledLavaCommands">The enabled lava commands.</param> /// <param name="mergeFields">The merge fields.</param> /// <param name="communicationRecipient">The communication recipient.</param> /// <param name="appRoot">The application root.</param> /// <param name="themeRoot">The theme root.</param> /// <returns></returns> public virtual string ResolveText(string content, Person person, CommunicationRecipient communicationRecipient, string enabledLavaCommands, Dictionary <string, object> mergeFields, string appRoot = "", string themeRoot = "") { string value = ResolveText(content, person, enabledLavaCommands, mergeFields, appRoot, themeRoot); if (communicationRecipient != null) { communicationRecipient.SentMessage = value; } return(value); }
/// <summary> /// Gets the communication. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="peopleIds">The people ids.</param> /// <returns></returns> private Communication GetCommunication(RockContext rockContext, List <int> peopleIds) { var communicationService = new CommunicationService(rockContext); var recipientService = new CommunicationRecipientService(rockContext); var MediumData = GetTemplateData(); if (MediumData != null) { Communication communication = new Communication(); communication.Status = CommunicationStatus.Transient; communication.SenderPersonAliasId = CurrentPersonAliasId; communicationService.Add(communication); communication.IsBulkCommunication = true; communication.MediumEntityTypeId = EntityTypeCache.Read("Rock.Communication.Medium.Email").Id; communication.FutureSendDateTime = null; // add each person as a recipient to the communication if (peopleIds != null) { foreach (var personId in peopleIds) { if (!communication.Recipients.Any(r => r.PersonAlias.PersonId == personId)) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAlias = new PersonAliasService(rockContext).GetPrimaryAlias(personId); communication.Recipients.Add(communicationRecipient); } } } // add the MediumData to the communication communication.MediumData.Clear(); foreach (var keyVal in MediumData) { if (!string.IsNullOrEmpty(keyVal.Value)) { communication.MediumData.Add(keyVal.Key, keyVal.Value); } } if (communication.MediumData.ContainsKey("Subject")) { communication.Subject = communication.MediumData["Subject"]; communication.MediumData.Remove("Subject"); } return(communication); } return(null); }
protected void gInteractions_RowDataBound(object sender, GridViewRowEventArgs e) { Interaction interaction = e.Row.DataItem as Interaction; if (interaction != null) { Literal lActivityDetails = e.Row.FindControl("lActivityDetails") as Literal; if (lActivityDetails != null) { lActivityDetails.Text = CommunicationRecipient.GetInteractionDetails(interaction); } } }
/// <summary> /// Handles the Click event of the btnSubmit 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 btnTest_Click(object sender, EventArgs e) { if (Page.IsValid && CurrentPersonAliasId.HasValue) { // Get existing or new communication record var communication = UpdateCommunication(new RockContext()); if (communication != null) { // Using a new context (so that changes in the UpdateCommunication() are not persisted ) var testCommunication = new Rock.Model.Communication(); testCommunication.SenderPersonAliasId = communication.SenderPersonAliasId; testCommunication.Subject = communication.Subject; testCommunication.IsBulkCommunication = communication.IsBulkCommunication; testCommunication.MediumEntityTypeId = communication.MediumEntityTypeId; testCommunication.MediumDataJson = communication.MediumDataJson; testCommunication.AdditionalMergeFieldsJson = communication.AdditionalMergeFieldsJson; testCommunication.FutureSendDateTime = null; testCommunication.Status = CommunicationStatus.Approved; testCommunication.ReviewedDateTime = RockDateTime.Now; testCommunication.ReviewerPersonAliasId = CurrentPersonAliasId; var testRecipient = new CommunicationRecipient(); if (communication.Recipients.Any()) { var recipient = communication.Recipients.FirstOrDefault(); testRecipient.AdditionalMergeValuesJson = recipient.AdditionalMergeValuesJson; } testRecipient.Status = CommunicationRecipientStatus.Pending; testRecipient.PersonAliasId = CurrentPersonAliasId.Value; testCommunication.Recipients.Add(testRecipient); var rockContext = new RockContext(); var communicationService = new CommunicationService(rockContext); communicationService.Add(testCommunication); rockContext.SaveChanges(); var medium = testCommunication.Medium; if (medium != null) { medium.Send(testCommunication); } communicationService.Delete(testCommunication); rockContext.SaveChanges(); nbTestResult.Visible = true; } } }
/// <summary> /// Populates the communication with recipients from the personal device identifiers. /// </summary> /// <param name="communication">The communication.</param> /// <param name="personalDeviceIds">The personal device ids.</param> private void PopulateCommunicationRecipients(Rock.Model.Communication communication, IEnumerable <int> personalDeviceIds) { foreach (var personalDeviceId in personalDeviceIds) { var testRecipient = new CommunicationRecipient { Status = CommunicationRecipientStatus.Pending, PersonalDeviceId = personalDeviceId, MediumEntityTypeId = _pushMediumId }; communication.Recipients.Add(testRecipient); } }
/// <summary> /// Validates the recipient. /// </summary> /// <param name="recipient">The recipient.</param> /// <param name="isBulkCommunication">if set to <c>true</c> [is bulk communication].</param> /// <returns></returns> public virtual bool ValidRecipient(CommunicationRecipient recipient, bool isBulkCommunication) { bool valid = true; var person = recipient?.PersonAlias?.Person; if (person != null) { if (person.IsDeceased) { recipient.Status = CommunicationRecipientStatus.Failed; recipient.StatusNote = "Person is deceased"; valid = false; } else if (recipient.Communication.ListGroupId.HasValue) { // if this communication is being sent to a list, make sure the recipient is still an active member of the list GroupMemberStatus?groupMemberStatus = null; using (var rockContext = new Rock.Data.RockContext()) { groupMemberStatus = new GroupMemberService(rockContext).Queryable() .Where(a => a.PersonId == person.Id && a.GroupId == recipient.Communication.ListGroupId) .Select(a => a.GroupMemberStatus).FirstOrDefault(); } if (groupMemberStatus != null) { if (groupMemberStatus == GroupMemberStatus.Inactive) { recipient.Status = CommunicationRecipientStatus.Failed; recipient.StatusNote = "Person is not active member of communication list: " + recipient.Communication.ListGroup.Name; valid = false; } } else { recipient.Status = CommunicationRecipientStatus.Failed; recipient.StatusNote = "Person is not member of communication list: " + recipient.Communication.ListGroup.Name; valid = false; } } } return(valid); }
private void Actions_CommunicateClick(object sender, EventArgs e) { var rockPage = Page as RockPage; BindGrid(); var redirectUrl = rockPage.Response.Output.ToString(); if (redirectUrl != null) { Regex rgx = new Regex(".*/(\\d*)"); string result = rgx.Replace(redirectUrl, "$1"); var recipients = GetDuplicatePersonData(); if (recipients.Any()) { // Create communication var communicationRockContext = new RockContext(); var communicationService = new CommunicationService(communicationRockContext); var communicationRecipientService = new CommunicationRecipientService(communicationRockContext); var personAliasService = new PersonAliasService(communicationRockContext); var communication = communicationService.Queryable().Where(c => c.SenderPersonAliasId == rockPage.CurrentPersonAliasId).OrderByDescending(c => c.Id).FirstOrDefault(); communication.IsBulkCommunication = false; foreach (var recipient in recipients) { PersonAlias a = personAliasService.Queryable().Where(p => p.PersonId == p.AliasPersonId && p.PersonId == recipient.Key).FirstOrDefault(); var communicationRecipient = new CommunicationRecipient { CommunicationId = communication.Id, PersonAliasId = a.Id, AdditionalMergeValues = recipient.Value }; communicationRecipientService.Add(communicationRecipient); communicationRockContext.SaveChanges(); } } } }
/// <summary> /// Updates a communication model with the user-entered values /// </summary> /// <param name="service">The service.</param> /// <returns></returns> private Rock.Model.Communication UpdateCommunication(CommunicationService service) { Rock.Model.Communication communication = null; if (CommunicationId.HasValue) { communication = service.Get(CommunicationId.Value); } if (communication == null) { communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Transient; communication.SenderPersonId = CurrentPersonId; service.Add(communication, CurrentPersonId); } communication.ChannelEntityTypeId = ChannelEntityTypeId; foreach (var recipient in Recipients) { if (!communication.Recipients.Where(r => r.PersonId == recipient.PersonId).Any()) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.Person = new PersonService().Get(recipient.PersonId); communicationRecipient.Status = CommunicationRecipientStatus.Pending; communication.Recipients.Add(communicationRecipient); } } GetChannelData(); communication.ChannelData = ChannelData; if (communication.ChannelData.ContainsKey("Subject")) { communication.Subject = communication.ChannelData["Subject"]; communication.ChannelData.Remove("Subject"); } communication.FutureSendDateTime = dtpFutureSend.SelectedDateTime; return(communication); }
/// <summary> /// Gets the communication. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="peopleIds">The people ids.</param> /// <returns></returns> private Rock.Model.Communication GetCommunication(RockContext rockContext, List <int> peopleIds) { var communicationService = new CommunicationService(rockContext); var recipientService = new CommunicationRecipientService(rockContext); if (GetTemplateData()) { Rock.Model.Communication communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Transient; communication.SenderPersonAliasId = CurrentPersonAliasId; communicationService.Add(communication); communication.IsBulkCommunication = true; communication.CommunicationType = CommunicationType.Email; communication.FutureSendDateTime = null; // add each person as a recipient to the communication if (peopleIds != null) { var emailMediumTypeId = EntityTypeCache.Get(Rock.SystemGuid.EntityType.COMMUNICATION_MEDIUM_EMAIL.AsGuid()).Id; foreach (var personId in peopleIds) { if (!communication.Recipients.Any(r => r.PersonAlias.PersonId == personId)) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAlias = new PersonAliasService(rockContext).GetPrimaryAlias(personId); communicationRecipient.MediumEntityTypeId = emailMediumTypeId; communication.Recipients.Add(communicationRecipient); } } } CommunicationDetails.Copy(CommunicationData, communication); return(communication); } return(null); }
/// <summary> /// Writes the opened interaction. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="recipient">The recipient.</param> private void WriteInteraction(RockContext rockContext, CommunicationRecipient recipient) { var interactionService = new InteractionService(rockContext); InteractionComponent interactionComponent = new InteractionComponentService(rockContext) .GetComponentByEntityId(Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid(), recipient.Communication.Id, recipient.Communication.Subject); rockContext.SaveChanges(); var clientType = "None"; var clientOs = string.Empty; var ipAddress = RequestContext.ClientInformation.IpAddress; var site = MobileHelper.GetCurrentApplicationSite(false, rockContext); var siteName = site?.Name ?? "Unknown"; var now = RockDateTime.Now; // // Determine if this is a phone or tablet. // var deviceData = RequestContext.GetHeader("X-Rock-DeviceData") .FirstOrDefault() ?.FromJsonOrNull <DeviceData>(); if (deviceData != null) { clientType = deviceData.DeviceType == Common.Mobile.Enums.DeviceType.Phone ? "Mobile" : "Tablet"; clientOs = deviceData.DevicePlatform.ToString(); } recipient.Status = CommunicationRecipientStatus.Opened; recipient.OpenedDateTime = now; recipient.OpenedClient = $"{clientOs} {siteName} ({clientType})"; interactionService.AddInteraction(interactionComponent.Id, recipient.Id, "Opened", "", recipient.PersonAliasId, now, siteName, clientOs, clientType, string.Empty, ipAddress, null); rockContext.SaveChanges(); }
/// <summary> /// Sends the communication. /// </summary> private void SendCommunication() { // create communication if (CurrentPerson != null && _groupId != -1 && !string.IsNullOrWhiteSpace(GetAttributeValue("CommunicationPage"))) { var rockContext = new RockContext(); var service = new CommunicationService(rockContext); var communication = new Communication(); communication.IsBulkCommunication = false; communication.Status = CommunicationStatus.Transient; communication.SenderPersonAliasId = CurrentPersonAliasId; service.Add(communication); var personAliasIds = new GroupMemberService(rockContext).Queryable() .Where(m => m.GroupId == _groupId && m.GroupMemberStatus != GroupMemberStatus.Inactive) .ToList() .Select(m => m.Person.PrimaryAliasId) .ToList(); // Get the primary aliases foreach (int personAlias in personAliasIds) { var recipient = new CommunicationRecipient(); recipient.PersonAliasId = personAlias; communication.Recipients.Add(recipient); } rockContext.SaveChanges(); Dictionary <string, string> queryParameters = new Dictionary <string, string>(); queryParameters.Add("CommunicationId", communication.Id.ToString()); NavigateToLinkedPage("CommunicationPage", queryParameters); } }
/// <summary> /// Adds any additional headers. /// </summary> /// <param name="message">The message.</param> /// <param name="recipient">The recipient.</param> public virtual void AddAdditionalHeaders(MailMessage message, CommunicationRecipient recipient) { }
/// <summary> /// Handles the Click event of the 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 btnSendTest_Click(object sender, EventArgs e) { var recipients = new List <RecipientData>(); var personDict = new Dictionary <string, object>(); personDict.Add("Person", CurrentPerson); recipients.Add(new RecipientData(CurrentPerson.Email, personDict)); if (GetAttributeValue("CommunicationType") == "System") { var message = new RockEmailMessage(ddlEmail.SelectedValueAsGuid().Value); message.SetRecipients(recipients); message.Send(); } else { // Get existing or new communication record var communication = UpdateCommunication(new RockContext(), ddlEmail.SelectedValueAsGuid().Value); if (communication != null) { using (var rockContext = new RockContext()) { // Using a new context (so that changes in the UpdateCommunication() are not persisted ) var testCommunication = communication.Clone(false); testCommunication.Id = 0; testCommunication.Guid = Guid.NewGuid(); testCommunication.CreatedByPersonAliasId = this.CurrentPersonAliasId; testCommunication.CreatedByPersonAlias = new PersonAliasService(rockContext).Queryable().Where(a => a.Id == this.CurrentPersonAliasId.Value).Include(a => a.Person).FirstOrDefault(); testCommunication.ForeignGuid = null; testCommunication.ForeignId = null; testCommunication.ForeignKey = null; testCommunication.FutureSendDateTime = null; testCommunication.Status = CommunicationStatus.Approved; testCommunication.ReviewedDateTime = RockDateTime.Now; testCommunication.ReviewerPersonAliasId = CurrentPersonAliasId; foreach (var attachment in communication.Attachments) { var cloneAttachment = attachment.Clone(false); cloneAttachment.Id = 0; cloneAttachment.Guid = Guid.NewGuid(); cloneAttachment.ForeignGuid = null; cloneAttachment.ForeignId = null; cloneAttachment.ForeignKey = null; testCommunication.Attachments.Add(cloneAttachment); } var testRecipient = new CommunicationRecipient(); if (communication.GetRecipientCount(rockContext) > 0) { var recipient = communication.GetRecipientsQry(rockContext).FirstOrDefault(); testRecipient.AdditionalMergeValuesJson = recipient.AdditionalMergeValuesJson; } testRecipient.Status = CommunicationRecipientStatus.Pending; testRecipient.PersonAliasId = CurrentPersonAliasId.Value; testRecipient.MediumEntityTypeId = EntityTypeCache.Read("Rock.Communication.Medium.Email").Id; testCommunication.Recipients.Add(testRecipient); var communicationService = new CommunicationService(rockContext); communicationService.Add(testCommunication); rockContext.SaveChanges(); foreach (var medium in testCommunication.GetMediums()) { medium.Send(testCommunication); } testRecipient = new CommunicationRecipientService(rockContext) .Queryable().AsNoTracking() .Where(r => r.CommunicationId == testCommunication.Id) .FirstOrDefault(); communicationService.Delete(testCommunication); rockContext.SaveChanges(); } } } nbSuccess.Text = string.Format("Sent test at {0}", DateTime.Now); }
/// <summary> /// Updates a communication model with the user-entered values /// </summary> /// <param name="communicationService">The service.</param> /// <returns></returns> private Rock.Model.Communication UpdateCommunication(RockContext rockContext) { var communicationService = new CommunicationService(rockContext); var recipientService = new CommunicationRecipientService(rockContext); Rock.Model.Communication communication = null; if (CommunicationId.HasValue) { communication = communicationService.Get(CommunicationId.Value); // Remove any deleted recipients foreach (var recipient in recipientService.GetByCommunicationId(CommunicationId.Value)) { if (!Recipients.Any(r => recipient.PersonAlias != null && r.PersonId == recipient.PersonAlias.PersonId)) { recipientService.Delete(recipient); communication.Recipients.Remove(recipient); } } } if (communication == null) { communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Transient; communication.SenderPersonAliasId = CurrentPersonAliasId; communicationService.Add(communication); } // Add any new recipients foreach (var recipient in Recipients) { if (!communication.Recipients.Any(r => r.PersonAlias != null && r.PersonAlias.PersonId == recipient.PersonId)) { var person = new PersonService(rockContext).Get(recipient.PersonId); if (person != null) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAlias = person.PrimaryAlias; communication.Recipients.Add(communicationRecipient); } } } communication.IsBulkCommunication = cbBulk.Checked; communication.MediumEntityTypeId = MediumEntityTypeId; communication.MediumData.Clear(); GetMediumData(); foreach (var keyVal in MediumData) { if (!string.IsNullOrEmpty(keyVal.Value)) { communication.MediumData.Add(keyVal.Key, keyVal.Value); } } if (communication.MediumData.ContainsKey("Subject")) { communication.Subject = communication.MediumData["Subject"]; communication.MediumData.Remove("Subject"); } DateTime?futureSendDate = dtpFutureSend.SelectedDateTime; if (futureSendDate.HasValue && futureSendDate.Value.CompareTo(RockDateTime.Now) > 0) { communication.FutureSendDateTime = futureSendDate; } else { communication.FutureSendDateTime = null; } return(communication); }
/// <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 smsMessage = rockMessage as RockSMSMessage; if (smsMessage != null) { // Validate From Number if (smsMessage.FromNumber == null) { errorMessages.Add("A From Number was not provided."); return(false); } string accountSid = GetAttributeValue("SID"); string authToken = GetAttributeValue("Token"); TwilioClient.Init(accountSid, authToken); // Common Merge Field var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null, rockMessage.CurrentPerson); foreach (var mergeField in rockMessage.AdditionalMergeFields) { mergeFields.AddOrReplace(mergeField.Key, mergeField.Value); } int?throttlingWaitTimeMS = null; if (this.IsLongCodePhoneNumber(smsMessage.FromNumber.Value)) { throttlingWaitTimeMS = this.GetAttributeValue("Long-CodeThrottling").AsIntegerOrNull(); } List <Uri> attachmentMediaUrls = GetAttachmentMediaUrls(rockMessage.Attachments.AsQueryable()); foreach (var recipientData in rockMessage.GetRecipientData()) { try { foreach (var mergeField in mergeFields) { recipientData.MergeFields.AddOrIgnore(mergeField.Key, mergeField.Value); } CommunicationRecipient communicationRecipient = null; using (var rockContext = new RockContext()) { CommunicationRecipientService communicationRecipientService = new CommunicationRecipientService(rockContext); int?recipientId = recipientData.CommunicationRecipientId.AsIntegerOrNull(); if (recipientId != null) { communicationRecipient = communicationRecipientService.Get(recipientId.Value); } string message = ResolveText(smsMessage.Message, smsMessage.CurrentPerson, communicationRecipient, smsMessage.EnabledLavaCommands, recipientData.MergeFields, smsMessage.AppRoot, smsMessage.ThemeRoot); // Create the communication record and send using that. if (rockMessage.CreateCommunicationRecord) { Person recipientPerson = ( Person )recipientData.MergeFields.GetValueOrNull("Person"); var communicationService = new CommunicationService(rockContext); Rock.Model.Communication communication = communicationService.CreateSMSCommunication(smsMessage.CurrentPerson, recipientPerson?.PrimaryAliasId, message, smsMessage.FromNumber, string.Empty, smsMessage.communicationName); rockContext.SaveChanges(); Send(communication, mediumEntityTypeId, mediumAttributes); continue; } else { MessageResource response = SendToTwilio(smsMessage.FromNumber.Value, null, attachmentMediaUrls, message, recipientData.To); if (response.ErrorMessage.IsNotNullOrWhiteSpace()) { errorMessages.Add(response.ErrorMessage); } if (communicationRecipient != null) { rockContext.SaveChanges(); } } } } catch (Exception ex) { errorMessages.Add(ex.Message); ExceptionLogService.LogException(ex); } if (throttlingWaitTimeMS.HasValue) { System.Threading.Tasks.Task.Delay(throttlingWaitTimeMS.Value).Wait(); } } } return(!errorMessages.Any()); }
/// <summary> /// Handles the Click event of the btnTest control and sends a test communication to the /// current person if they have an email address on their record. /// </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 btnTest_Click( object sender, EventArgs e ) { if ( Page.IsValid && CurrentPerson != null ) { SetActionButtons( resetToSend: true ); if ( string.IsNullOrWhiteSpace( CurrentPerson.Email ) ) { nbError.Text = "A test email cannot be sent because you do not have an email address."; nbError.Visible = true; return; } // Get existing or new communication record var communication = GetCommunication( new RockContext(), null ); if ( communication != null && CurrentPersonAliasId.HasValue ) { // Using a new context (so that changes in the UpdateCommunication() are not persisted ) var testCommunication = new Rock.Model.Communication(); testCommunication.SenderPersonAliasId = communication.SenderPersonAliasId; testCommunication.Subject = communication.Subject; testCommunication.IsBulkCommunication = communication.IsBulkCommunication; testCommunication.MediumEntityTypeId = communication.MediumEntityTypeId; testCommunication.MediumDataJson = communication.MediumDataJson; testCommunication.AdditionalMergeFieldsJson = communication.AdditionalMergeFieldsJson; testCommunication.FutureSendDateTime = null; testCommunication.Status = CommunicationStatus.Approved; testCommunication.ReviewedDateTime = RockDateTime.Now; testCommunication.ReviewerPersonAliasId = CurrentPersonAliasId.Value; var testRecipient = new CommunicationRecipient(); if ( communication.Recipients.Any() ) { var recipient = communication.Recipients.FirstOrDefault(); testRecipient.AdditionalMergeValuesJson = recipient.AdditionalMergeValuesJson; } testRecipient.Status = CommunicationRecipientStatus.Pending; testRecipient.PersonAliasId = CurrentPersonAliasId.Value; testCommunication.Recipients.Add( testRecipient ); var rockContext = new RockContext(); var communicationService = new CommunicationService( rockContext ); communicationService.Add( testCommunication ); rockContext.SaveChanges(); var medium = testCommunication.Medium; if ( medium != null ) { medium.Send( testCommunication ); } communicationService.Delete( testCommunication ); rockContext.SaveChanges(); nbTestResult.Visible = true; } } }
private RockEmailMessage GetRecipientRockEmailMessage(RockEmailMessage emailMessage, Model.Communication communication, CommunicationRecipient communicationRecipient, Dictionary <string, object> mergeFields, string organizationEmail, Dictionary <string, string> mediumAttributes) { var recipientEmail = new RockEmailMessage(); recipientEmail.CurrentPerson = emailMessage.CurrentPerson; recipientEmail.EnabledLavaCommands = emailMessage.EnabledLavaCommands; recipientEmail.AppRoot = emailMessage.AppRoot; recipientEmail.CssInliningEnabled = emailMessage.CssInliningEnabled; // CC if (communication.CCEmails.IsNotNullOrWhiteSpace()) { string[] ccRecipients = communication .CCEmails .ResolveMergeFields(mergeFields, emailMessage.CurrentPerson) .Replace(";", ",") .Split(','); foreach (var ccRecipient in ccRecipients) { recipientEmail.CCEmails.Add(ccRecipient); } } // BCC if (communication.BCCEmails.IsNotNullOrWhiteSpace()) { string[] bccRecipients = communication .BCCEmails .ResolveMergeFields(mergeFields, emailMessage.CurrentPerson) .Replace(";", ",") .Split(','); foreach (var bccRecipient in bccRecipients) { recipientEmail.BCCEmails.Add(bccRecipient); } } // Attachments recipientEmail.Attachments = emailMessage.Attachments; // Communication record for tracking opens & clicks recipientEmail.MessageMetaData = new Dictionary <string, string>(emailMessage.MessageMetaData); // To var toEmailAddress = new RockEmailMessageRecipient(null, null) { To = communicationRecipient.PersonAlias.Person.Email, Name = communicationRecipient.PersonAlias.Person.FullName }; recipientEmail.SetRecipients(new List <RockEmailMessageRecipient> { toEmailAddress }); var fromMailAddress = new MailAddress(emailMessage.FromEmail, emailMessage.FromName); var checkResult = CheckSafeSender(new List <string> { toEmailAddress.EmailAddress }, fromMailAddress, organizationEmail); // Reply To recipientEmail.ReplyToEmail = GetRecipientReplyToAddress(emailMessage, mergeFields, checkResult); // From if (checkResult.IsUnsafeDomain && checkResult.SafeFromAddress != null) { recipientEmail.FromName = checkResult.SafeFromAddress.DisplayName; recipientEmail.FromEmail = checkResult.SafeFromAddress.Address; } else { recipientEmail.FromName = fromMailAddress.DisplayName; recipientEmail.FromEmail = fromMailAddress.Address; } // Subject var subject = ResolveText(communication.Subject, emailMessage.CurrentPerson, communication.EnabledLavaCommands, mergeFields, emailMessage.AppRoot); recipientEmail.Subject = subject; // Body Plain Text if (mediumAttributes.ContainsKey("DefaultPlainText")) { var plainText = ResolveText(mediumAttributes["DefaultPlainText"], emailMessage.CurrentPerson, communication.EnabledLavaCommands, mergeFields, emailMessage.AppRoot); if (!string.IsNullOrWhiteSpace(plainText)) { recipientEmail.PlainTextMessage = plainText; } } // Body (HTML) string htmlBody = communication.Message; // Get the unsubscribe content and add a merge field for it if (communication.IsBulkCommunication && mediumAttributes.ContainsKey("UnsubscribeHTML")) { string unsubscribeHtml = ResolveText(mediumAttributes["UnsubscribeHTML"], emailMessage.CurrentPerson, communication.EnabledLavaCommands, mergeFields, emailMessage.AppRoot); mergeFields.AddOrReplace("UnsubscribeOption", unsubscribeHtml); htmlBody = ResolveText(htmlBody, emailMessage.CurrentPerson, communication.EnabledLavaCommands, mergeFields, emailMessage.AppRoot); // Resolve special syntax needed if option was included in global attribute if (Regex.IsMatch(htmlBody, @"\[\[\s*UnsubscribeOption\s*\]\]")) { htmlBody = Regex.Replace(htmlBody, @"\[\[\s*UnsubscribeOption\s*\]\]", unsubscribeHtml); } // Add the unsubscribe option at end if it wasn't included in content if (!htmlBody.Contains(unsubscribeHtml)) { htmlBody += unsubscribeHtml; } } else { htmlBody = ResolveText(htmlBody, emailMessage.CurrentPerson, communication.EnabledLavaCommands, mergeFields, emailMessage.AppRoot); htmlBody = Regex.Replace(htmlBody, @"\[\[\s*UnsubscribeOption\s*\]\]", string.Empty); } if (!string.IsNullOrWhiteSpace(htmlBody)) { if (emailMessage.CssInliningEnabled) { // move styles inline to help it be compatible with more email clients htmlBody = htmlBody.ConvertHtmlStylesToInlineAttributes(); } // add the main Html content to the email recipientEmail.Message = htmlBody; } recipientEmail.MessageMetaData["communication_recipient_guid"] = communicationRecipient.Guid.ToString(); return(recipientEmail); }
/// <summary> /// Handles the Click event of the btnSubmit 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 btnTest_Click( object sender, EventArgs e ) { if ( Page.IsValid && CurrentPersonAliasId.HasValue ) { // Get existing or new communication record var rockContext = new RockContext(); var communication = UpdateCommunication( rockContext ); if ( communication != null ) { // Using a new context (so that changes in the UpdateCommunication() are not persisted ) var testCommunication = new Rock.Model.Communication(); testCommunication.SenderPersonAliasId = communication.SenderPersonAliasId; testCommunication.Subject = communication.Subject; testCommunication.IsBulkCommunication = communication.IsBulkCommunication; testCommunication.MediumEntityTypeId = communication.MediumEntityTypeId; testCommunication.MediumDataJson = communication.MediumDataJson; testCommunication.AdditionalMergeFieldsJson = communication.AdditionalMergeFieldsJson; testCommunication.FutureSendDateTime = null; testCommunication.Status = CommunicationStatus.Approved; testCommunication.ReviewedDateTime = RockDateTime.Now; testCommunication.ReviewerPersonAliasId = CurrentPersonAliasId; var testRecipient = new CommunicationRecipient(); if ( communication.GetRecipientCount( rockContext ) > 0 ) { var recipient = communication.GetRecipientsQry(rockContext).FirstOrDefault(); testRecipient.AdditionalMergeValuesJson = recipient.AdditionalMergeValuesJson; } testRecipient.Status = CommunicationRecipientStatus.Pending; testRecipient.PersonAliasId = CurrentPersonAliasId.Value; testCommunication.Recipients.Add( testRecipient ); var communicationService = new CommunicationService( rockContext ); communicationService.Add( testCommunication ); rockContext.SaveChanges(); var medium = testCommunication.Medium; if ( medium != null ) { medium.Send( testCommunication ); } communicationService.Delete( testCommunication ); rockContext.SaveChanges(); nbTestResult.Visible = true; } } }
/// <summary> /// Updates a communication model with the user-entered values /// </summary> /// <param name="communicationService">The service.</param> /// <returns></returns> private Rock.Model.Communication UpdateCommunication(RockContext rockContext) { var communicationService = new CommunicationService(rockContext); var recipientService = new CommunicationRecipientService(rockContext); Rock.Model.Communication communication = null; IQueryable<CommunicationRecipient> qryRecipients = null; if ( CommunicationId.HasValue ) { communication = communicationService.Get( CommunicationId.Value ); } if ( communication != null ) { // Remove any deleted recipients HashSet<int> personIdHash = new HashSet<int>( Recipients.Select( a => a.PersonId ) ); qryRecipients = communication.GetRecipientsQry( rockContext ); foreach ( var item in qryRecipients.Select( a => new { Id = a.Id, PersonId = a.PersonAlias.PersonId }) ) { if ( !personIdHash.Contains(item.PersonId) ) { var recipient = qryRecipients.Where( a => a.Id == item.Id ).FirstOrDefault(); recipientService.Delete( recipient ); communication.Recipients.Remove( recipient ); } } } if (communication == null) { communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Transient; communication.SenderPersonAliasId = CurrentPersonAliasId; communicationService.Add( communication ); } if (qryRecipients == null) { qryRecipients = communication.GetRecipientsQry( rockContext ); } // Add any new recipients HashSet<int> communicationPersonIdHash = new HashSet<int>( qryRecipients.Select( a => a.PersonAlias.PersonId ) ); foreach(var recipient in Recipients ) { if ( !communicationPersonIdHash.Contains( recipient.PersonId ) ) { var person = new PersonService( rockContext ).Get( recipient.PersonId ); if ( person != null ) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAlias = person.PrimaryAlias; communication.Recipients.Add( communicationRecipient ); } } } communication.IsBulkCommunication = cbBulk.Checked; communication.MediumEntityTypeId = MediumEntityTypeId; communication.MediumData.Clear(); GetMediumData(); foreach ( var keyVal in MediumData ) { if ( !string.IsNullOrEmpty( keyVal.Value ) ) { communication.MediumData.Add( keyVal.Key, keyVal.Value ); } } if ( communication.MediumData.ContainsKey( "Subject" ) ) { communication.Subject = communication.MediumData["Subject"]; communication.MediumData.Remove( "Subject" ); } DateTime? futureSendDate = dtpFutureSend.SelectedDateTime; if ( futureSendDate.HasValue && futureSendDate.Value.CompareTo( RockDateTime.Now ) > 0 ) { communication.FutureSendDateTime = futureSendDate; } else { communication.FutureSendDateTime = null; } return communication; }
/// <summary> /// Updates a communication model with the user-entered values /// </summary> /// <param name="communicationService">The service.</param> /// <returns></returns> private Rock.Model.Communication UpdateCommunication(RockContext rockContext) { var communicationService = new CommunicationService(rockContext); var recipientService = new CommunicationRecipientService(rockContext); Rock.Model.Communication communication = null; if ( CommunicationId.HasValue ) { communication = communicationService.Get( CommunicationId.Value ); // Remove any deleted recipients foreach(var recipient in recipientService.GetByCommunicationId( CommunicationId.Value ) ) { if (!Recipients.Any( r => recipient.PersonAlias != null && r.PersonId == recipient.PersonAlias.PersonId)) { recipientService.Delete(recipient); communication.Recipients.Remove( recipient ); } } } if (communication == null) { communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Transient; communication.SenderPersonAliasId = CurrentPersonAliasId; communicationService.Add( communication ); } // Add any new recipients foreach(var recipient in Recipients ) { if ( !communication.Recipients.Any( r => r.PersonAlias != null && r.PersonAlias.PersonId == recipient.PersonId ) ) { var person = new PersonService( rockContext ).Get( recipient.PersonId ); if ( person != null ) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAlias = person.PrimaryAlias; communication.Recipients.Add( communicationRecipient ); } } } communication.IsBulkCommunication = cbBulk.Checked; communication.MediumEntityTypeId = MediumEntityTypeId; communication.MediumData.Clear(); GetMediumData(); foreach ( var keyVal in MediumData ) { if ( !string.IsNullOrEmpty( keyVal.Value ) ) { communication.MediumData.Add( keyVal.Key, keyVal.Value ); } } if ( communication.MediumData.ContainsKey( "Subject" ) ) { communication.Subject = communication.MediumData["Subject"]; communication.MediumData.Remove( "Subject" ); } DateTime? futureSendDate = dtpFutureSend.SelectedDateTime; if ( futureSendDate.HasValue && futureSendDate.Value.CompareTo( RockDateTime.Now ) > 0 ) { communication.FutureSendDateTime = futureSendDate; } else { communication.FutureSendDateTime = null; } return communication; }
private async Task SendToCommunicationRecipient(Model.Communication communication, string fromPhone, Dictionary <string, object> mergeFields, Person currentPerson, List <Uri> attachmentMediaUrls, int personEntityTypeId, int communicationCategoryId, int communicationEntityTypeId, string publicAppRoot, string callbackUrl, CommunicationRecipient recipient) { using (var rockContext = new RockContext()) { try { recipient = new CommunicationRecipientService(rockContext).Get(recipient.Id); var twilioNumber = recipient.PersonAlias.Person.PhoneNumbers.GetFirstSmsNumber(); if (!string.IsNullOrWhiteSpace(twilioNumber)) { // Create merge field dictionary var mergeObjects = recipient.CommunicationMergeValues(mergeFields); string message = ResolveText(communication.SMSMessage, currentPerson, recipient, communication.EnabledLavaCommands, mergeObjects, publicAppRoot); var response = await SendToTwilioAsync(fromPhone, callbackUrl, attachmentMediaUrls, message, twilioNumber).ConfigureAwait(false); recipient.Status = CommunicationRecipientStatus.Delivered; recipient.SendDateTime = RockDateTime.Now; recipient.TransportEntityTypeName = this.GetType().FullName; recipient.UniqueMessageId = response.Sid; try { var historyService = new HistoryService(rockContext); historyService.Add(new History { CreatedByPersonAliasId = communication.SenderPersonAliasId, EntityTypeId = personEntityTypeId, CategoryId = communicationCategoryId, EntityId = recipient.PersonAlias.PersonId, Verb = History.HistoryVerb.Sent.ConvertToString().ToUpper(), ChangeType = History.HistoryChangeType.Record.ToString(), ValueName = "SMS message", Caption = message.Truncate(200), RelatedEntityTypeId = communicationEntityTypeId, RelatedEntityId = communication.Id }); } catch (Exception ex) { ExceptionLogService.LogException(ex, null); } } else { recipient.Status = CommunicationRecipientStatus.Failed; recipient.StatusNote = "No Phone Number with Messaging Enabled"; } } catch (Exception ex) { recipient.Status = CommunicationRecipientStatus.Failed; recipient.StatusNote = "Twilio Exception: " + ex.Message; } rockContext.SaveChanges(); } }
private async Task <SendMessageResult> SendToRecipientAsync(RockMessageRecipient recipient, Dictionary <string, object> mergeFields, RockSMSMessage smsMessage, List <Uri> attachmentMediaUrls, int mediumEntityTypeId, Dictionary <string, string> mediumAttributes) { var sendMessageResult = new SendMessageResult(); try { foreach (var mergeField in mergeFields) { recipient.MergeFields.AddOrIgnore(mergeField.Key, mergeField.Value); } CommunicationRecipient communicationRecipient = null; using (var rockContext = new RockContext()) { CommunicationRecipientService communicationRecipientService = new CommunicationRecipientService(rockContext); int?recipientId = recipient.CommunicationRecipientId; if (recipientId != null) { communicationRecipient = communicationRecipientService.Get(recipientId.Value); } string message = ResolveText(smsMessage.Message, smsMessage.CurrentPerson, communicationRecipient, smsMessage.EnabledLavaCommands, recipient.MergeFields, smsMessage.AppRoot, smsMessage.ThemeRoot); Person recipientPerson = ( Person )recipient.MergeFields.GetValueOrNull("Person"); // Create the communication record and send using that if we have a person since a communication record requires a valid person. Otherwise just send without creating a communication record. if (smsMessage.CreateCommunicationRecord && recipientPerson != null) { var communicationService = new CommunicationService(rockContext); var createSMSCommunicationArgs = new CommunicationService.CreateSMSCommunicationArgs { FromPerson = smsMessage.CurrentPerson, ToPersonAliasId = recipientPerson?.PrimaryAliasId, Message = message, FromPhone = smsMessage.FromNumber, CommunicationName = smsMessage.CommunicationName, ResponseCode = string.Empty, SystemCommunicationId = smsMessage.SystemCommunicationId }; Rock.Model.Communication communication = communicationService.CreateSMSCommunication(createSMSCommunicationArgs); if (smsMessage?.CurrentPerson != null) { communication.CreatedByPersonAliasId = smsMessage.CurrentPerson.PrimaryAliasId; communication.ModifiedByPersonAliasId = smsMessage.CurrentPerson.PrimaryAliasId; } // Since we just created a new communication record, we need to move any attachments from the rockMessage // to the communication's attachments since the Send method below will be handling the delivery. if (attachmentMediaUrls.Any()) { foreach (var attachment in smsMessage.Attachments.AsQueryable()) { communication.AddAttachment(new CommunicationAttachment { BinaryFileId = attachment.Id }, CommunicationType.SMS); } } rockContext.SaveChanges(); await SendAsync(communication, mediumEntityTypeId, mediumAttributes).ConfigureAwait(false); communication.SendDateTime = RockDateTime.Now; rockContext.SaveChanges(); sendMessageResult.MessagesSent += 1; } else { MessageResource response = await SendToTwilioAsync(smsMessage.FromNumber.Value, null, attachmentMediaUrls, message, recipient.To).ConfigureAwait(false); if (response.ErrorMessage.IsNotNullOrWhiteSpace()) { sendMessageResult.Errors.Add(response.ErrorMessage); } else { sendMessageResult.MessagesSent += 1; } if (communicationRecipient != null) { rockContext.SaveChanges(); } } } } catch (Exception ex) { sendMessageResult.Errors.Add(ex.Message); ExceptionLogService.LogException(ex); } return(sendMessageResult); }
/// <summary> /// Job that will send scheduled group SMS messages. /// /// 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) { var dataMap = context.JobDetail.JobDataMap; int?commandTimeout = dataMap.GetString("CommandTimeout").AsIntegerOrNull(); int?lastRunBuffer = dataMap.GetString("LastRunBuffer").AsIntegerOrNull(); var enabledLavaCommands = dataMap.GetString("EnabledLavaCommands"); var JobStartDateTime = RockDateTime.Now; var dateAttributes = new List <AttributeValue>(); var dAttributeMatrixItemAndGroupIds = new Dictionary <int, int>(); // Key: AttributeMatrixItemId Value: GroupId int communicationsSent = 0; var smsMediumType = EntityTypeCache.Get("Rock.Communication.Medium.Sms"); var dateAttributeId = Rock.Web.Cache.AttributeCache.Get(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_SEND_DATE.AsGuid()).Id; var recurrenceAttributeId = Rock.Web.Cache.AttributeCache.Get(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_SEND_RECURRENCE.AsGuid()).Id; var fromNumberAttributeId = Rock.Web.Cache.AttributeCache.Get(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_FROM_NUMBER.AsGuid()).Id; var messageAttributeId = Rock.Web.Cache.AttributeCache.Get(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_MESSAGE.AsGuid()).Id; try { using (var rockContext = new RockContext()) { // get the last run date or yesterday DateTime?lastStartDateTime = null; // get job type id int jobId = context.JobDetail.Description.AsInteger(); // load job var job = new ServiceJobService(rockContext) .GetNoTracking(jobId); if (job != null && job.Guid != Rock.SystemGuid.ServiceJob.JOB_PULSE.AsGuid()) { lastStartDateTime = job.LastRunDateTime?.AddSeconds(0.0d - ( double )(job.LastRunDurationSeconds + lastRunBuffer)); } var beginDateTime = lastStartDateTime ?? JobStartDateTime.AddDays(-1); // get the date attributes dateAttributes = new AttributeValueService(rockContext) .Queryable().AsNoTracking() .Where(d => d.AttributeId == dateAttributeId && d.EntityId.HasValue && d.ValueAsDateTime >= beginDateTime && d.ValueAsDateTime <= JobStartDateTime) .ToList(); } foreach (var d in dateAttributes) { // Use a new context to limit the amount of change-tracking required using (var rockContext = new RockContext()) { var attributeMatrixId = new AttributeMatrixItemService(rockContext) .GetNoTracking(d.EntityId.Value) .AttributeMatrixId; var attributeMatrixGuid = new AttributeMatrixService(rockContext) .GetNoTracking(attributeMatrixId) .Guid .ToString(); var attributeValue = new AttributeValueService(rockContext) .Queryable().AsNoTracking() .FirstOrDefault(a => a.Value.Equals(attributeMatrixGuid, StringComparison.CurrentCultureIgnoreCase)); if (attributeValue != null && attributeValue.EntityId.HasValue) { dAttributeMatrixItemAndGroupIds.Add(d.EntityId.Value, attributeValue.EntityId.Value); } } } foreach (var attributeMatrixItemAndGroupId in dAttributeMatrixItemAndGroupIds) { // Use a new context to limit the amount of change-tracking required using (var rockContext = new RockContext()) { rockContext.Database.CommandTimeout = commandTimeout; var fromNumberGuid = new AttributeValueService(rockContext) .GetByAttributeIdAndEntityId(fromNumberAttributeId, attributeMatrixItemAndGroupId.Key) .Value; var fromNumber = DefinedValueCache.Get(fromNumberGuid.AsGuid()); var message = new AttributeValueService(rockContext) .GetByAttributeIdAndEntityId(messageAttributeId, attributeMatrixItemAndGroupId.Key) .Value; var attachments = new List <BinaryFile>(); var group = new GroupService(rockContext) .GetNoTracking(attributeMatrixItemAndGroupId.Value); if (!message.IsNullOrWhiteSpace() && smsMediumType != null) { var recipients = new GroupMemberService(rockContext) .GetByGroupId(attributeMatrixItemAndGroupId.Value).AsNoTracking() .Where(m => m.GroupMemberStatus == GroupMemberStatus.Active) .ToList(); if (recipients.Any()) { var communicationService = new CommunicationService(rockContext); var communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Transient; communication.ReviewedDateTime = JobStartDateTime; communication.ReviewerPersonAliasId = group.ModifiedByPersonAliasId; communication.SenderPersonAliasId = group.ModifiedByPersonAliasId; communication.CreatedByPersonAliasId = group.ModifiedByPersonAliasId; communicationService.Add(communication); communication.EnabledLavaCommands = enabledLavaCommands; var personIdHash = new HashSet <int>(); foreach (var groupMember in recipients) { // Use a new context to limit the amount of change-tracking required using (var groupMemberContext = new RockContext()) { if (!personIdHash.Contains(groupMember.PersonId)) { var person = new PersonService(groupMemberContext) .GetNoTracking(groupMember.PersonId); if (person != null && person.PrimaryAliasId.HasValue) { personIdHash.Add(groupMember.PersonId); var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAliasId = person.PrimaryAliasId; communicationRecipient.AdditionalMergeValues = new Dictionary <string, object>(); communicationRecipient.AdditionalMergeValues.Add("GroupMember", groupMember); //communicationRecipient.AdditionalMergeValues.Add( "Group", group ); communication.Recipients.Add(communicationRecipient); } } } } communication.IsBulkCommunication = false; communication.CommunicationType = CommunicationType.SMS; communication.CommunicationTemplateId = null; foreach (var recipient in communication.Recipients) { recipient.MediumEntityTypeId = smsMediumType.Id; } communication.SMSMessage = message; communication.SMSFromDefinedValueId = fromNumber.Id; communication.Subject = string.Empty; communication.Status = CommunicationStatus.Approved; rockContext.SaveChanges(); Rock.Model.Communication.Send(communication); communicationsSent = communicationsSent + personIdHash.Count; var recurrence = new AttributeValueService(rockContext) .GetByAttributeIdAndEntityId(recurrenceAttributeId, attributeMatrixItemAndGroupId.Key); if (recurrence != null && !string.IsNullOrWhiteSpace(recurrence.Value)) { var sendDate = new AttributeValueService(rockContext) .GetByAttributeIdAndEntityId(dateAttributeId, attributeMatrixItemAndGroupId.Key); switch (recurrence.Value) { case "1": sendDate.Value = sendDate.ValueAsDateTime.Value.AddDays(7).ToString(); break; case "2": sendDate.Value = sendDate.ValueAsDateTime.Value.AddDays(14).ToString(); break; case "3": sendDate.Value = sendDate.ValueAsDateTime.Value.AddMonths(1).ToString(); break; case "4": sendDate.Value = sendDate.ValueAsDateTime.Value.AddDays(1).ToString(); break; default: break; } rockContext.SaveChanges(); } } } } } if (communicationsSent > 0) { context.Result = string.Format("Sent {0} {1}", communicationsSent, "communication".PluralizeIf(communicationsSent > 1)); } else { context.Result = "No communications to send"; } } catch (System.Exception ex) { HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(ex, context2); throw; } }
/// <summary> /// Gets the push notification data to be sent to FCM. /// </summary> /// <param name="openAction">The open action.</param> /// <param name="pushData">The push data.</param> /// <param name="recipient">The recipient.</param> /// <returns>The data to be included in the <see cref="FCM.Net.Message.Data"/> property.</returns> private static Dictionary <string, string> GetPushNotificationData(PushOpenAction?openAction, PushData pushData, CommunicationRecipient recipient) { var notificationData = new Dictionary <string, string>(); if (recipient != null) { notificationData.Add(PushKeys.CommunicationId, recipient.CommunicationId.ToString()); notificationData.Add(PushKeys.RecipientId, recipient.Id.ToString()); } ; if (!openAction.HasValue || pushData == null) { return(notificationData); } if (openAction == PushOpenAction.ShowDetails && pushData.MobileApplicationId.HasValue && recipient != null) { var site = SiteCache.Get(pushData.MobileApplicationId.Value); var additionalSettings = site?.AdditionalSettings.FromJsonOrNull <AdditionalSiteSettings>(); if (additionalSettings?.CommunicationViewPageId != null) { var page = PageCache.Get(additionalSettings.CommunicationViewPageId.Value); if (page != null) { notificationData.Add(PushKeys.PageGuid, page.Guid.ToString()); notificationData.Add(PushKeys.QueryString, $"CommunicationRecipientGuid={recipient.Guid}"); } } } else if (openAction == PushOpenAction.LinkToMobilePage && pushData.MobilePageId.HasValue) { var page = PageCache.Get(pushData.MobilePageId.Value); if (page != null) { notificationData.Add(PushKeys.PageGuid, page.Guid.ToString()); notificationData.Add(PushKeys.QueryString, UrlEncode(pushData.MobilePageQueryString)); } } return(notificationData); }
private void AddRecipients(Communication communication, bool sendParents, int mediumEntityTypeId) { //List to keep from sending multiple messages List <int> addedIds = new List <int>(); if (!string.IsNullOrWhiteSpace(hfCommunication.Value)) { //For adding a single person from the roster var member = memberData.Where(m => m.Id == hfCommunication.Value.AsIntegerOrNull()).FirstOrDefault(); if (member != null) { if (member.IsParent || !sendParents) { if (!addedIds.Contains(member.Id)) { //Add person to Communication var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAliasId = member.PersonAliasId; communicationRecipient.MediumEntityTypeId = mediumEntityTypeId; communication.Recipients.Add(communicationRecipient); addedIds.Add(member.Id); } } else { //Add parents to communication foreach (Person parent in member.Parents) { if (!addedIds.Contains(parent.Id)) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAliasId = parent.PrimaryAliasId ?? parent.Id; communicationRecipient.MediumEntityTypeId = mediumEntityTypeId; communication.Recipients.Add(communicationRecipient); addedIds.Add(parent.Id); } } } } //clear the value we are done hfCommunication.Value = ""; } else { var keys = gMembers.SelectedKeys; List <GroupMemberData> members = new List <GroupMemberData>(); foreach (int key in keys) { members.Add(memberData.Where(md => md.Id == key).FirstOrDefault()); } if (!members.Any()) { FilterData(); members = memberData; } //For adding the communication recipients from the membership list foreach (var member in members) { member.LoadParents(); if (member.IsParent || !sendParents) { if (!addedIds.Contains(member.Id)) { //Add person to Communication var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAliasId = member.PersonAliasId; communicationRecipient.MediumEntityTypeId = mediumEntityTypeId; communication.Recipients.Add(communicationRecipient); addedIds.Add(member.Id); } } else { //Add parents to communication foreach (Person parent in member.Parents) { if (!addedIds.Contains(parent.Id)) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAliasId = parent.PrimaryAliasId ?? parent.Id; communicationRecipient.MediumEntityTypeId = mediumEntityTypeId; communication.Recipients.Add(communicationRecipient); addedIds.Add(parent.Id); } } } } } }
/// <summary> /// Merges the values. /// </summary> /// <param name="configValues">The config values.</param> /// <param name="recipient">The recipient.</param> /// <returns></returns> protected Dictionary <string, object> MergeValues(Dictionary <string, object> configValues, CommunicationRecipient recipient) { Dictionary <string, object> mergeValues = new Dictionary <string, object>(); configValues.ToList().ForEach(v => mergeValues.Add(v.Key, v.Value)); if (recipient != null) { if (recipient.Person != null) { mergeValues.Add("Person", recipient.Person); } // Add any additional merge fields created through a report foreach (var mergeField in recipient.AdditionalMergeValues) { if (!mergeValues.ContainsKey(mergeField.Key)) { mergeValues.Add(mergeField.Key, mergeField.Value); } } } return(mergeValues); }
/// <summary> /// Gets the communication. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="peopleIds">The people ids.</param> /// <returns></returns> private Rock.Model.Communication GetCommunication( RockContext rockContext, List<int> peopleIds ) { var communicationService = new CommunicationService(rockContext); var recipientService = new CommunicationRecipientService(rockContext); GetTemplateData(); Rock.Model.Communication communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Transient; communication.SenderPersonAliasId = CurrentPersonAliasId; communicationService.Add( communication ); communication.IsBulkCommunication = true; communication.MediumEntityTypeId = EntityTypeCache.Read( "Rock.Communication.Medium.Email" ).Id; communication.FutureSendDateTime = null; // add each person as a recipient to the communication if ( peopleIds != null ) { foreach ( var personId in peopleIds ) { if ( !communication.Recipients.Any( r => r.PersonAlias.PersonId == personId ) ) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAlias = new PersonAliasService( rockContext ).GetPrimaryAlias( personId ); communication.Recipients.Add( communicationRecipient ); } } } // add the MediumData to the communication communication.MediumData.Clear(); foreach ( var keyVal in MediumData ) { if ( !string.IsNullOrEmpty( keyVal.Value ) ) { communication.MediumData.Add( keyVal.Key, keyVal.Value ); } } if ( communication.MediumData.ContainsKey( "Subject" ) ) { communication.Subject = communication.MediumData["Subject"]; communication.MediumData.Remove( "Subject" ); } return communication; }
/// <summary> /// Creates the email communication. /// </summary> /// <param name="recipientEmails">The recipient emails.</param> /// <param name="fromName">From name.</param> /// <param name="fromAddress">From address.</param> /// <param name="replyTo">The reply to.</param> /// <param name="subject">The subject.</param> /// <param name="htmlMessage">The HTML message.</param> /// <param name="textMessage">The text message.</param> /// <param name="bulkCommunication">if set to <c>true</c> [bulk communication].</param> /// <param name="recipientStatus">The recipient status.</param> /// <param name="senderPersonAliasId">The sender person alias identifier.</param> /// <returns></returns> public Communication CreateEmailCommunication( List<string> recipientEmails, string fromName, string fromAddress, string replyTo, string subject, string htmlMessage, string textMessage, bool bulkCommunication, CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered, int? senderPersonAliasId = null ) { var recipients = new PersonService( (RockContext)this.Context ) .Queryable() .Where( p => recipientEmails.Contains( p.Email ) ) .ToList(); if ( recipients.Any() ) { Rock.Model.Communication communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Approved; communication.SenderPersonAliasId = senderPersonAliasId; communication.Subject = subject; Add( communication ); communication.IsBulkCommunication = bulkCommunication; communication.MediumEntityTypeId = EntityTypeCache.Read( "Rock.Communication.Medium.Email" ).Id; communication.FutureSendDateTime = null; // add each person as a recipient to the communication foreach ( var person in recipients ) { int? personAliasId = person.PrimaryAliasId; if ( personAliasId.HasValue ) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.PersonAliasId = personAliasId.Value; communicationRecipient.Status = recipientStatus; communication.Recipients.Add( communicationRecipient ); } } // add the MediumData to the communication communication.MediumData.Clear(); communication.MediumData.Add( "FromName", fromName ); communication.MediumData.Add( "FromAddress", fromAddress ); communication.MediumData.Add( "ReplyTo", replyTo ); communication.MediumData.Add( "Subject", subject ); communication.MediumData.Add( "HtmlMessage", htmlMessage ); communication.MediumData.Add( "TextMessage", textMessage ); return communication; } return null; }
/// <summary> /// Adds any additional headers. /// </summary> /// <param name="message">The message.</param> /// <param name="recipient">The recipient.</param> public virtual void AddAdditionalHeaders( MailMessage message, CommunicationRecipient recipient ) { }
/// <summary> /// Updates a communication model with the user-entered values /// </summary> /// <param name="service">The service.</param> /// <returns></returns> private Rock.Model.Communication UpdateCommunication(CommunicationService service) { Rock.Model.Communication communication = null; if ( CommunicationId.HasValue ) { communication = service.Get( CommunicationId.Value ); } if (communication == null) { communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Transient; communication.SenderPersonId = CurrentPersonId; service.Add( communication, CurrentPersonId ); } communication.ChannelEntityTypeId = ChannelEntityTypeId; foreach(var recipient in Recipients) { if ( !communication.Recipients.Where( r => r.PersonId == recipient.PersonId ).Any() ) { var communicationRecipient = new CommunicationRecipient(); communicationRecipient.Person = new PersonService().Get( recipient.PersonId ); communicationRecipient.Status = CommunicationRecipientStatus.Pending; communication.Recipients.Add( communicationRecipient ); } } GetChannelData(); communication.ChannelData = ChannelData; if ( communication.ChannelData.ContainsKey( "Subject" ) ) { communication.Subject = communication.ChannelData["Subject"]; communication.ChannelData.Remove( "Subject" ); } communication.FutureSendDateTime = dtpFutureSend.SelectedDateTime; return communication; }