Пример #1
0
        /// <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 pushMessage = rockMessage as RockPushMessage;

            if (pushMessage != null)
            {
                // Get server key
                string serverKey = GetAttributeValue("ServerKey");
                var    sender    = new Sender(serverKey);

                // Common Merge Field
                var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null, rockMessage.CurrentPerson);
                foreach (var mergeField in rockMessage.AdditionalMergeFields)
                {
                    mergeFields.AddOrReplace(mergeField.Key, mergeField.Value);
                }

                var recipients = rockMessage.GetRecipientData();

                if (pushMessage.SendSeperatelyToEachRecipient)
                {
                    foreach (var recipient in recipients)
                    {
                        try
                        {
                            foreach (var mergeField in mergeFields)
                            {
                                recipient.MergeFields.AddOrIgnore(mergeField.Key, mergeField.Value);
                            }

                            PushMessage(sender, new List <string> {
                                recipient.To
                            }, pushMessage, recipient.MergeFields);
                        }
                        catch (Exception ex)
                        {
                            errorMessages.Add(ex.Message);
                            ExceptionLogService.LogException(ex, null);
                        }
                    }
                }
                else
                {
                    try
                    {
                        PushMessage(sender, recipients.Select(r => r.To).ToList(), pushMessage, mergeFields);
                    }
                    catch (Exception ex)
                    {
                        errorMessages.Add(ex.Message);
                        ExceptionLogService.LogException(ex, null);
                    }
                }
            }

            return(!errorMessages.Any());
        }
Пример #2
0
        /// <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 sendMessageResult = AsyncHelper.RunSync(() => SendAsync(rockMessage, mediumEntityTypeId, mediumAttributes));

            errorMessages.AddRange(sendMessageResult.Errors);

            return(!errorMessages.Any());
        }
Пример #3
0
        /// <summary>
        /// Consumes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        public override void Consume(TMessage message)
        {
            var logString    = RockMessage.GetLogString(message);
            var consumerName = GetType().FullName;

            var expiration = ConsumeContext.ExpirationTime.HasValue ?
                             ConsumeContext.ExpirationTime.Value.ToLocalTime().ToString() :
                             "None";

            Debug.WriteLine($"==================\nConsumer: {consumerName}\nExpiration: {expiration}\n{logString}");
        }
Пример #4
0
        /// <summary>
        /// Called after the message has been dispatched to all consumers - note that in the case of an exception
        /// this method is not called, and the DispatchFaulted method is called instead
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task PostConsume <T>(ConsumeContext <T> context) where T : class
        {
            // Log for the bus as a whole
            RockMessageBus.StatLog?.LogConsume();

            // Log for the specific queue
            var queue = RockMessage.GetQueue(typeof(T));

            queue?.StatLog?.LogConsume();

            return(RockMessageBus.GetCompletedTask());
        }
Пример #5
0
        /// <inheritdoc cref="SendAsync{TQueue, TMessage}(TMessage)"/>
        public static Task SendAsync <TQueue>(ICommandMessage <TQueue> message, Type messageType)
            where TQueue : ISendCommandQueue, new()
        {
            RockLogger.Log.Debug(RockLogDomains.Core, "Send Message Async: {@message} Message Type: {1}", message, messageType);

            if (!IsReady())
            {
                ExceptionLogService.LogException($"A message was sent before the message bus was ready: {RockMessage.GetLogString( message )}");
                return(Task.CompletedTask);
            }

            var queue    = RockQueue.Get <TQueue>();
            var endpoint = _transportComponent.GetSendEndpoint(_bus, queue.NameForConfiguration);

            message.SenderNodeName = NodeName;

            // NOTE: Use Task.Run to wrap an async instead of directly using async, otherwise async will get an exception if it isn't done before the HttpContext is disposed.
            return(Task.Run(async() =>
            {
                await endpoint.Send(message, messageType, context =>
                {
                    context.TimeToLive = RockQueue.GetTimeToLive(queue);
                });
            }));
        }
Пример #6
0
        /// <inheritdoc cref="PublishAsync{TQueue, TMessage}(TMessage)"/>
        public static Task PublishAsync <TQueue>(IEventMessage <TQueue> message, Type messageType)
            where TQueue : IPublishEventQueue, new()
        {
            if (!IsReady())
            {
                ExceptionLogService.LogException(new BusException($"A message was published before the message bus was ready: {RockMessage.GetLogString( message )}"));
                return(Task.CompletedTask);
            }

            message.SenderNodeName = NodeName;

            // NOTE: Use Task.Run to wrap an async instead of directly using async, otherwise async will get an exception if it isn't done before the HttpContext is disposed.
            return(Task.Run(async() =>
            {
                await _bus.Publish(message, messageType, context =>
                {
                    context.TimeToLive = RockQueue.GetTimeToLive <TQueue>();
                });
            }));
        }
Пример #7
0
        /// <summary>
        /// Sends the specified rock message.
        /// </summary>
        /// <param name="rockMessage">The rock message.</param>
        /// <param name="mediumEntityTypeId">The medium entity type identifier.</param>
        /// <param name="mediumAttributes">The medium attributes.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Send(RockMessage rockMessage, int mediumEntityTypeId, Dictionary <string, string> mediumAttributes, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            var emailMessage = rockMessage as RockEmailMessage;

            if (emailMessage != null)
            {
                // Common Merge Field
                var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null, rockMessage.CurrentPerson);
                foreach (var mergeField in rockMessage.AdditionalMergeFields)
                {
                    mergeFields.AddOrReplace(mergeField.Key, mergeField.Value);
                }

                string fromAddress = emailMessage.FromEmail;
                string fromName    = emailMessage.FromName;

                // Resolve any possible merge fields in the from address
                fromAddress = fromAddress.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands);
                fromName    = fromName.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands);

                // From - if none is set, use the one in the Organization's GlobalAttributes.
                var globalAttributes = GlobalAttributesCache.Get();
                if (string.IsNullOrWhiteSpace(fromAddress))
                {
                    fromAddress = globalAttributes.GetValue("OrganizationEmail");
                }

                if (string.IsNullOrWhiteSpace(fromName))
                {
                    fromName = globalAttributes.GetValue("OrganizationName");
                }

                if (fromAddress.IsNullOrWhiteSpace())
                {
                    errorMessages.Add("A From address was not provided and no Organization email address is configured.");
                    return(false);
                }

                MailMessage message = new MailMessage();

                // Reply To
                try
                {
                    if (emailMessage.ReplyToEmail.IsNotNullOrWhiteSpace())
                    {
                        // Resolve any possible merge fields in the replyTo address
                        message.ReplyToList.Add(new MailAddress(emailMessage.ReplyToEmail.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands)));
                    }
                }
                catch { }

                message.IsBodyHtml = true;
                message.Priority   = MailPriority.Normal;

                using (var smtpClient = GetSmtpClient())
                {
                    foreach (var messageRecipient in rockMessage.GetRecipients())
                    {
                        try
                        {
                            foreach (var mergeField in mergeFields)
                            {
                                messageRecipient.MergeFields.AddOrIgnore(mergeField.Key, mergeField.Value);
                            }

                            message.To.Clear();
                            message.CC.Clear();
                            message.Bcc.Clear();
                            message.Headers.Clear();

                            // Set From/To and check safe sender
                            message.From = new MailAddress(fromAddress, fromName);
                            message.To.Add(new MailAddress(
                                               messageRecipient.To.ResolveMergeFields(messageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands),
                                               messageRecipient.Name.ResolveMergeFields(messageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands)));
                            CheckSafeSender(message, globalAttributes);

                            // cc
                            foreach (string cc in emailMessage.CCEmails.Where(e => e != ""))
                            {
                                // Resolve any possible merge fields in the cc address
                                string ccRecipient = cc.ResolveMergeFields(messageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands);
                                message.CC.Add(new MailAddress(ccRecipient));
                            }

                            // bcc
                            foreach (string bcc in emailMessage.BCCEmails.Where(e => e != ""))
                            {
                                // Resolve any possible merge fields in the cc address
                                string bccRecipient = bcc.ResolveMergeFields(messageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands);
                                message.Bcc.Add(new MailAddress(bccRecipient));
                            }

                            // Subject
                            string subject = ResolveText(emailMessage.Subject, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands, messageRecipient.MergeFields, emailMessage.AppRoot, emailMessage.ThemeRoot);

                            // Body
                            string body = ResolveText(emailMessage.Message, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands, messageRecipient.MergeFields, emailMessage.AppRoot, emailMessage.ThemeRoot);
                            body = Regex.Replace(body, @"\[\[\s*UnsubscribeOption\s*\]\]", string.Empty);

                            message.Subject = subject.Left(998);
                            message.Body    = body;

                            var metaData = new Dictionary <string, string>(emailMessage.MessageMetaData);

                            // If a communication is going to get created, create a guid for tracking the opens/clicks
                            Guid?recipientGuid = null;
                            if (emailMessage.CreateCommunicationRecord)
                            {
                                recipientGuid = Guid.NewGuid();
                                metaData.Add("communication_recipient_guid", recipientGuid.Value.ToString());
                            }

                            using (var rockContext = new RockContext())
                            {
                                // Recreate the attachments
                                message.Attachments.Clear();
                                if (emailMessage.Attachments.Any())
                                {
                                    var binaryFileService = new BinaryFileService(rockContext);
                                    foreach (var binaryFileId in emailMessage.Attachments.Where(a => a != null).Select(a => a.Id))
                                    {
                                        var attachment = binaryFileService.Get(binaryFileId);
                                        if (attachment != null)
                                        {
                                            message.Attachments.Add(new Attachment(attachment.ContentStream, attachment.FileName));
                                        }
                                    }
                                }

                                AddAdditionalHeaders(message, metaData);

                                smtpClient.Send(message);
                            }

                            if (emailMessage.CreateCommunicationRecord)
                            {
                                var transaction = new SaveCommunicationTransaction(messageRecipient, emailMessage.FromName, emailMessage.FromEmail, subject, body);
                                transaction.RecipientGuid = recipientGuid;
                                RockQueue.TransactionQueue.Enqueue(transaction);
                            }
                        }
                        catch (Exception ex)
                        {
                            errorMessages.Add(ex.Message);
                            ExceptionLogService.LogException(ex);
                        }
                    }
                }
            }

            return(!errorMessages.Any());
        }
Пример #8
0
        /// <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());
        }
Пример #9
0
        /// <summary>
        /// Sends the specified rock message.
        /// </summary>
        /// <param name="rockMessage">The rock message.</param>
        /// <param name="mediumEntityTypeId">The medium entity type identifier. Not used.</param>
        /// <param name="mediumAttributes">The medium attributes. Not used.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Send(RockMessage rockMessage, int mediumEntityTypeId, Dictionary <string, string> mediumAttributes, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            var emailMessage = rockMessage as RockEmailMessage;

            if (emailMessage == null)
            {
                return(!errorMessages.Any());
            }

            var globalAttributes = GlobalAttributesCache.Get();

            // Common Merge Field
            var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null, rockMessage.CurrentPerson);

            foreach (var mergeField in rockMessage.AdditionalMergeFields)
            {
                mergeFields.AddOrReplace(mergeField.Key, mergeField.Value);
            }

            // Resolve any possible merge fields in the from address
            string fromAddress = emailMessage.FromEmail.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands);
            string fromName    = emailMessage.FromName.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands);

            // Replace blank values with organizational defaults
            fromAddress = fromAddress.IsNullOrWhiteSpace() ? globalAttributes.GetValue("OrganizationEmail") : fromAddress;
            fromName    = fromName.IsNullOrWhiteSpace() ? globalAttributes.GetValue("OrganizationName") : fromName;

            if (!fromAddress.IsValidEmail())
            {
                errorMessages.Add("A From address was not provided.");
                return(false);
            }

            RestRequest restRequest = null;

            foreach (var rockMessageRecipient in rockMessage.GetRecipients())
            {
                try
                {
                    restRequest = new RestRequest(GetAttributeValue("Resource"), Method.POST);
                    restRequest.AddParameter("domian", GetAttributeValue("Domain"), ParameterType.UrlSegment);

                    // Reply To
                    if (emailMessage.ReplyToEmail.IsNotNullOrWhiteSpace())
                    {
                        // Resolve any possible merge fields in the replyTo address
                        restRequest.AddParameter("h:Reply-To", emailMessage.ReplyToEmail.ResolveMergeFields(mergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands));
                    }

                    foreach (var mergeField in mergeFields)
                    {
                        rockMessageRecipient.MergeFields.AddOrIgnore(mergeField.Key, mergeField.Value);
                    }

                    // From
                    restRequest.AddParameter("from", new MailAddress(fromAddress, fromName).ToString());

                    // To
                    restRequest.AddParameter(
                        "to",
                        new MailAddress(
                            rockMessageRecipient.To.ResolveMergeFields(rockMessageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands),
                            rockMessageRecipient.Name.ResolveMergeFields(rockMessageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands)));

                    // Safe Sender checks
                    CheckSafeSender(restRequest, fromAddress, globalAttributes.GetValue("OrganizationEmail"));

                    // CC
                    foreach (string cc in emailMessage.CCEmails.Where(e => e != string.Empty))
                    {
                        string ccRecipient = cc.ResolveMergeFields(rockMessageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands);
                        restRequest.AddParameter("cc", ccRecipient);
                    }

                    // BCC
                    foreach (string bcc in emailMessage.BCCEmails.Where(e => e != string.Empty))
                    {
                        string bccRecipient = bcc.ResolveMergeFields(rockMessageRecipient.MergeFields, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands);
                        restRequest.AddParameter("bcc", bccRecipient);
                    }

                    // Subject
                    string subject = ResolveText(emailMessage.Subject, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands, rockMessageRecipient.MergeFields, emailMessage.AppRoot, emailMessage.ThemeRoot).Left(998);
                    restRequest.AddParameter("subject", subject);

                    // Body (html)
                    string body = ResolveText(emailMessage.Message, emailMessage.CurrentPerson, emailMessage.EnabledLavaCommands, rockMessageRecipient.MergeFields, emailMessage.AppRoot, emailMessage.ThemeRoot);
                    body = Regex.Replace(body, @"\[\[\s*UnsubscribeOption\s*\]\]", string.Empty);
                    restRequest.AddParameter("html", body);

                    // Communication record for tracking opens & clicks
                    var  metaData      = new Dictionary <string, string>(emailMessage.MessageMetaData);
                    Guid?recipientGuid = null;

                    if (emailMessage.CreateCommunicationRecord)
                    {
                        recipientGuid = Guid.NewGuid();
                        metaData.Add("communication_recipient_guid", recipientGuid.Value.ToString());
                    }

                    // Additional headers
                    AddAdditionalHeaders(restRequest, metaData);

                    // Attachments
                    if (emailMessage.Attachments.Any())
                    {
                        using (var rockContext = new RockContext())
                        {
                            var binaryFileService = new BinaryFileService(rockContext);
                            foreach (var binaryFileId in emailMessage.Attachments.Where(a => a != null).Select(a => a.Id))
                            {
                                var attachment = binaryFileService.Get(binaryFileId);
                                if (attachment != null)
                                {
                                    MemoryStream ms = new MemoryStream();
                                    attachment.ContentStream.CopyTo(ms);
                                    restRequest.AddFile("attachment", ms.ToArray(), attachment.FileName);
                                }
                            }
                        }
                    }

                    // Send it
                    RestClient restClient = new RestClient
                    {
                        BaseUrl       = new Uri(GetAttributeValue("BaseURL")),
                        Authenticator = new HttpBasicAuthenticator("api", GetAttributeValue("APIKey"))
                    };

                    // Call the API and get the response
                    Response = restClient.Execute(restRequest);

                    // Create the communication record
                    if (emailMessage.CreateCommunicationRecord)
                    {
                        var transaction = new SaveCommunicationTransaction(rockMessageRecipient, emailMessage.FromName, emailMessage.FromEmail, subject, body);
                        transaction.RecipientGuid = recipientGuid;
                        RockQueue.TransactionQueue.Enqueue(transaction);
                    }
                }
                catch (Exception ex)
                {
                    errorMessages.Add(ex.Message);
                    ExceptionLogService.LogException(ex);
                }
            }

            return(!errorMessages.Any());
        }
Пример #10
0
        /// <summary>
        /// Sends the asynchronous.
        /// </summary>
        /// <param name="rockMessage">The rock message.</param>
        /// <param name="mediumEntityTypeId">The medium entity type identifier.</param>
        /// <param name="mediumAttributes">The medium attributes.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public async Task <SendMessageResult> SendAsync(RockMessage rockMessage, int mediumEntityTypeId, Dictionary <string, string> mediumAttributes)
        {
            var sendMessageResult = new SendMessageResult();

            var smsMessage = rockMessage as RockSMSMessage;

            if (smsMessage != null)
            {
                // Validate From Number
                if (smsMessage.FromNumber == null)
                {
                    sendMessageResult.Errors.Add("A From Number was not provided.");
                    return(sendMessageResult);
                }

                string accountSid = GetAttributeValue(TwilioAttributeKey.Sid);
                string authToken  = GetAttributeValue(TwilioAttributeKey.AuthToken);
                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(TwilioAttributeKey.LongCodeThrottling).AsIntegerOrNull();
                }

                List <Uri> attachmentMediaUrls = GetAttachmentMediaUrls(rockMessage.Attachments.AsQueryable());

                if (throttlingWaitTimeMS.HasValue)
                {
                    foreach (var recipient in rockMessage.GetRecipients())
                    {
                        var result = await SendToRecipientAsync(recipient, mergeFields, smsMessage, attachmentMediaUrls, mediumEntityTypeId, mediumAttributes).ConfigureAwait(false);

                        sendMessageResult.Errors.AddRange(result.Errors);
                        sendMessageResult.Errors.AddRange(result.Warnings);
                        sendMessageResult.MessagesSent += result.MessagesSent;

                        await Task.Delay(throttlingWaitTimeMS.Value).ConfigureAwait(false);
                    }
                }
                else
                {
                    var sendingTask = new List <Task <SendMessageResult> >();

                    using (var mutex = new SemaphoreSlim(MaxParallelization))
                    {
                        foreach (var recipient in rockMessage.GetRecipients())
                        {
                            var startMutexWait = System.Diagnostics.Stopwatch.StartNew();
                            await mutex.WaitAsync().ConfigureAwait(false);

                            sendingTask.Add(ThrottleHelper.ThrottledExecute(() => SendToRecipientAsync(recipient, mergeFields, smsMessage, attachmentMediaUrls, mediumEntityTypeId, mediumAttributes), mutex));
                        }

                        /*
                         * Now that we have fired off all of the task, we need to wait for them to complete, get their results,
                         * and then process that result. Once all of the task have been completed we can continue.
                         */
                        while (sendingTask.Count > 0)
                        {
                            var completedTask = await Task.WhenAny(sendingTask).ConfigureAwait(false);

                            sendingTask.Remove(completedTask);

                            var result = await completedTask.ConfigureAwait(false);

                            sendMessageResult.Errors.AddRange(result.Errors);
                            sendMessageResult.Errors.AddRange(result.Warnings);
                            sendMessageResult.MessagesSent += result.MessagesSent;
                        }
                    }
                }
            }

            return(sendMessageResult);
        }
Пример #11
0
        /// <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);
                        }

                        string message = ResolveText(smsMessage.Message, smsMessage.CurrentPerson, smsMessage.EnabledLavaCommands, recipientData.MergeFields, smsMessage.AppRoot, smsMessage.ThemeRoot);

                        MessageResource response = SendToTwilio(smsMessage.FromNumber.Value, null, attachmentMediaUrls, message, recipientData.To);

                        if (response.ErrorMessage.IsNotNullOrWhitespace())
                        {
                            errorMessages.Add(response.ErrorMessage);
                        }
                    }
                    catch (Exception ex)
                    {
                        errorMessages.Add(ex.Message);
                        ExceptionLogService.LogException(ex);
                    }

                    if (throttlingWaitTimeMS.HasValue)
                    {
                        System.Threading.Thread.Sleep(throttlingWaitTimeMS.Value);
                    }
                }
            }

            return(!errorMessages.Any());
        }
Пример #12
0
        /// <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 pushMessage = rockMessage as RockPushMessage;

            if (pushMessage != null)
            {
                // Common Merge Field
                var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null, rockMessage.CurrentPerson);
                foreach (var mergeField in rockMessage.AdditionalMergeFields)
                {
                    mergeFields.AddOrReplace(mergeField.Key, mergeField.Value);
                }

                var         recipients  = rockMessage.GetRecipients();
                RockContext rockContext = new RockContext();

                if (pushMessage.SendSeperatelyToEachRecipient)
                {
                    foreach (var recipient in recipients)
                    {
                        try
                        {
                            foreach (var mergeField in mergeFields)
                            {
                                recipient.MergeFields.AddOrIgnore(mergeField.Key, mergeField.Value);
                            }
                            Person recipientPerson = ( Person )recipient.MergeFields.GetValueOrNull("Person");
                            string personAliasId   = recipientPerson.Aliases.FirstOrDefault().Id.ToString();
                            PushMessage(new List <string> {
                                personAliasId
                            }, pushMessage, recipient.MergeFields);
                        }
                        catch (Exception ex)
                        {
                            errorMessages.Add(ex.Message);
                            ExceptionLogService.LogException(ex, null);
                        }
                    }
                }
                else
                {
                    try
                    {
                        foreach (var recipient in recipients)
                        {
                            Person recipientPerson = (Person)mergeFields.GetValueOrNull("Person");
                            string personAliasId   = recipientPerson.Aliases.FirstOrDefault().Id.ToString();
                            recipient.MergeFields.Add("PersonAliasId", personAliasId);
                        }
                        PushMessage(recipients.Select(r => r.MergeFields.GetValueOrNull("PersonAliasId").ToString()).ToList(), pushMessage, mergeFields);
                    }
                    catch (Exception ex)
                    {
                        errorMessages.Add(ex.Message);
                        ExceptionLogService.LogException(ex, null);
                    }
                }
            }

            return(!errorMessages.Any());
        }
Пример #13
0
        /// <summary>
        /// Sends the command message.
        /// </summary>
        /// <typeparam name="TQueue">The type of the queue.</typeparam>
        /// <param name="message">The message.</param>
        /// <param name="messageType">Type of the message.</param>
        public static async Task SendAsync <TQueue>(ICommandMessage <TQueue> message, Type messageType)
            where TQueue : ISendCommandQueue, new()
        {
            RockLogger.Log.Debug(RockLogDomains.Core, "Send Message Async: {@message} Message Type: {1}", message, messageType);

            if (!IsReady())
            {
                ExceptionLogService.LogException($"A message was sent before the message bus was ready: {RockMessage.GetLogString( message )}");
                return;
            }

            var queue    = RockQueue.Get <TQueue>();
            var endpoint = _transportComponent.GetSendEndpoint(_bus, queue.NameForConfiguration);

            message.SenderNodeName = NodeName;

            await endpoint.Send(message, messageType, context =>
            {
                context.TimeToLive = RockQueue.GetTimeToLive(queue);
            });
        }
Пример #14
0
        /// <summary>
        /// Publishes the message.
        /// </summary>
        /// <typeparam name="TQueue">The type of the queue.</typeparam>
        /// <param name="message">The message.</param>
        /// <param name="messageType">Type of the message.</param>
        public static async Task PublishAsync <TQueue>(IEventMessage <TQueue> message, Type messageType)
            where TQueue : IPublishEventQueue, new()
        {
            if (!IsReady())
            {
                ExceptionLogService.LogException(new BusException($"A message was published before the message bus was ready: {RockMessage.GetLogString( message )}"));
                return;
            }

            message.SenderNodeName = NodeName;

            await _bus.Publish(message, messageType, context =>
            {
                context.TimeToLive = RockQueue.GetTimeToLive <TQueue>();
            });
        }