Bulk Messaging through Custom Connections
FrontlineCloud supports Custom Connections, which allow the app to be connected to any http-based API for two-way messaging. This allows connectivity using aggregators that have not been merged in as officially supported connection types. Furthermore, the Custom Connection supports Bulk Messaging, a feature that allows much more efficient sending of identical messages to multiple recipients by grouping them into a single outbound API call.
What are Bulk Messages?
Bulk Messages (BulkTextMessage in our codebase) are interactions denoting a single message sent to multiple recipients. They have two defining characteristics that make them differ from our standard outbound SMS:
- A BulkTextMessage sent to multiple recipients is stored and displayed in the Inbox as a single interaction. Instead of the name/mobile of the recipient, the list view shows the number of recipients
- The message is sent to the aggregator in a single HTTP request, instead of one request per recipient. The aggregator then takes care of delivering separate SMS to each recipient. This form of messaging is not supported by all aggregators.
Aggregators that support bulk messaging typically report the individual SMS's success through a 'callback', i.e. a separate request made from the aggregator back to the calling app delivering the status of the message. FrontlineCloud does not support these callbacks. The statuses of all the component SMSs in a Bulk Message are therefore set to the same success or failure value, and this is based on the HTTP response given for the bulk message API request. This means it is possible to have individual Dispatches marked as successfully sent even when delivery to the mobile from the aggregator fails.
Setting up a Custom Connection for bulk sending
For details on setting up a standard Custom Connection, see the internal help file. The only difference between a standard Custom Connection and a Bulk-capable one is the presence of a "Bulk Messaging payload" in the config. This is a FLang expression that will be used to translate the text and list of recipients into the expected payload at the aggregator end. The variables available in the FLang binding are:
- destinations, a List of mobile numbers that can be iterated over
- text, the message text that will be sent to each recipient
The groovy Collection ".each", ".join" and ".collect" helpers will likely be used to convert destinations into the desired format. An example Bulk Message payload config is shown below:
{
"message": "${text}",
"recipients": [ ${destinations.collect { '' + it + '' } .join(',') } ] //note that '' is two single quotes
}
When invoked with text = "hello world" and destinations = 12345,67890, the payload sent to the endpoint would be as shown below:
{
"message": "hello world",
"recipients": [ "12345", "67890" ]
}
The related configuration for normal message delivery (POST vs GET and URLENCODED vs JSON) also apply to bulk message sending. Inbound message delivery is not affected by bulk sending config, and Bulk Sending connections do not also support bulk delivery of inbound messages.
Sending bulk messages from the sidebar
A Custom Connection is considered 'bulk capable' when the Bulk Message Payload field is non-empty. Once the system detects the existence of at least one enabled bulk-capable connection, the Send Message button is replaced with a dropdown, from which you can choose whether to send normal sms or Bulk messages. If sending using Bulk messaging, the UI is almost identical to the standard SMS sidebar, with two exceptions:
- The list of available connections is restricted to only bulk-enabled ones, and "use routing rules" is not available
- Flang expressions that depend on the "recipient" variable in the binding do not work (for instnace, "${recipient.nameOrMobile}")
When the Bulk message is submitted, it will be displayed in "SAVING" status in the inbox until the HTTP request to the defined endpoint is triggered. To view this, expand the new Bulk message in the inbox. The app will automatically update the message status in the UI when it is submitted to the endpoint.
The list of recipients the bulk message was sent to can be viewed in the single interaction "show" page. To get there, expand the bulk message in your inbox and click the "view full details" link.
Sending bulk messages in activities (for recipe builders)
The SendMessageAction has a checkbox for enabling bulk sending. When this is checked, Bulk SMS will be sent instead of a single sms per recipient. This imposes the same restrictions as above: only flang expressions that make no reference to "recipient" will be evaluated correctly, and the message will only be submitted on Bulk-capable connections.
If the recipe builder leaves the SendMessageAction's config on "use routing rules", the routing rules in the target workspace will be scanned, looking for the first bulk-capable connection in the list. If none is present in the list, or all are disabled, a FailedActionEvent will be raised, stating that no bulk-enabled connection was found. Note that the 'use last receiver' routing rules option is ignored in Bulk Messaging.
Successful bulk SMS result in a single Action Event, unlike standard SMS which create a single Action Event for each recipient.
Supported scale
In QA, this functionality was tested at the scale of a few hundred thousand recipients. The app should safely handle up to around 500,000 recipients per bulk message, and take 5-10 minutes to prepare message for outbound delivery at that scale.
Create a Bulk SMS connection with Twilio's Notify API.
With Twilio, we can send bulk SMS notifications with a single API request via Twilio Notify. The API can be used not just for SMS, but for all the other channels supported by Twilio Notify like iOS and Android push notifications, web push via FCM and APNS, and Facebook Messenger. You can even mix multiple channels in a single request. In the steps below I will demonstrate how to set this up just for SMS.
Limitations of Twilio Notify API.
The total size of the request entity should not exceed 1MB. This is typically sufficient for 10,000 phone numbers.
Create a Messaging Service.
Assuming already you have a Twilio Phone number go to Programmable SMS → SMS → Messaging Service in your Twilio console. If you don't have a Twilio phone number you will need to purchase one before creating a new Messaging service.
There are different use cases for what you will use the messaging service for. In the example, I will go with Mixed.
Add your Twilio Phone Number to the Messaging Service.
To receive inbound messages with your Messaging Service, configure your Inbound Request URL.
Set up Notify Service Instance.
In the console navigate to Notify → Services and create a Notify Service.
Now choose your new Messaging Service for this Notify Service Instance and click save.
Create a custom Connection.
Create a custom connection with following values:
endpoint
: https://notify.twilio.com/v1/Services/ServiceSID/Notifications
The ServiceSID is the service SID for the Notify Service Instance we created.- Set HTTP method to POST
- Set the Content Type to Other.
- The Connection requires 2 headers:
- Twilio API uses Basic authentication, you will use your Twilio account SID as the username and your auth token as the password for HTTP Basic authentication.
- The 2 header is the
Content-Type
with a value ofapplication/x-www-form-urlencoded
.
- In the Bulk Messaging Payload use the following Flang.
${def recipients = destinations.collect({ "&ToBinding=" + URLEncoder.encode(groovy.json.JsonOutput.toJson(["binding_type":"sms", "address": it])) }).join(); def message = 'Body='+URLEncoder.encode(text); message+recipients}
- If you are using the connection for single messaging SMS then you will need the following Flang for the Single Messaging Payload section
${
def message = 'Body='+URLEncoder.encode(text);def recipient='&ToBinding='+ URLEncoder.encode(groovy.json.JsonOutput.toJson(["binding_type":"sms", "address": destination])); message+recipient
}
0 Comments