/// <summary> /// Creates the communication to the recipient's mobile device with attachments. /// </summary> /// <param name="fromPerson">From person.</param> /// <param name="toPersonAliasId">To person alias identifier.</param> /// <param name="message">The message.</param> /// <param name="fromPhone">From phone.</param> /// <param name="responseCode">The response code.</param> /// <param name="rockContext">The rock context.</param> /// <param name="attachments">The attachments.</param> public static void CreateCommunicationMobile(Person fromPerson, int?toPersonAliasId, string message, DefinedValueCache fromPhone, string responseCode, Rock.Data.RockContext rockContext, List <BinaryFile> attachments) { // NOTE: fromPerson should never be null since a Nameless Person record should have been created if a regular person record wasn't found string communicationName = fromPerson != null?string.Format("From: {0}", fromPerson.FullName) : "From: unknown person"; var communicationService = new CommunicationService(rockContext); var createSMSCommunicationArgs = new CommunicationService.CreateSMSCommunicationArgs { FromPerson = fromPerson, ToPersonAliasId = toPersonAliasId, Message = message, FromPhone = fromPhone, CommunicationName = communicationName, ResponseCode = responseCode, SystemCommunicationId = null, }; Rock.Model.Communication communication = communicationService.CreateSMSCommunication(createSMSCommunicationArgs); rockContext.SaveChanges(); // Now that we have a communication ID we can add the attachments if (attachments != null && attachments.Any()) { foreach (var attachment in attachments) { var communicationAttachment = new CommunicationAttachment { BinaryFileId = attachment.Id, CommunicationId = communication.Id, CommunicationType = CommunicationType.SMS }; communication.AddAttachment(communicationAttachment, CommunicationType.SMS); } rockContext.SaveChanges(); } // queue the sending var transaction = new ProcessSendCommunication.Message() { CommunicationId = communication.Id, }; transaction.Send(); }
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> /// 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 recipient in rockMessage.GetRecipients()) { 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 (rockMessage.CreateCommunicationRecord && recipientPerson != null) { var communicationService = new CommunicationService(rockContext); Rock.Model.Communication communication = communicationService.CreateSMSCommunication(smsMessage.CurrentPerson, recipientPerson?.PrimaryAliasId, message, smsMessage.FromNumber, string.Empty, smsMessage.communicationName); // 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 rockMessage.Attachments.AsQueryable()) { communication.AddAttachment(new CommunicationAttachment { BinaryFileId = attachment.Id }, CommunicationType.SMS); } } rockContext.SaveChanges(); Send(communication, mediumEntityTypeId, mediumAttributes); continue; } else { MessageResource response = SendToTwilio(smsMessage.FromNumber.Value, null, attachmentMediaUrls, message, recipient.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()); }