If you have been sending emails to your users or customers, adding a new notification channel like SMS can help reach users in the ways they prefer as well as increase engagement with your site or application. At Courier, our focus is to make it simple to add new channels, but we also realize that sometimes a direct integration may be necessary. In this white paper, we share the strategies we have discovered through our work in building these types of direct integrations as we explain how to add SMS with Twilio to an existing SendGrid integration. We will help you think through the various questions involved and set up your infrastructure, with a focus on the following topics:
UX Guidelines: Best practices for adding SMS to your current routing logic for notifying your users or customers.
Templating: Using templates with your emails and SMS notifications to decouple formatting logic from API calls.
Routing Logic: How to send notifications to the right channel while always obeying user consent.
Verification: Recommended checks and fall-backs in the case of failures.
Analytics: Advice for consolidating metrics and tracking across your email and SMS channels.
To begin, consider where it will be useful to add SMS to your existing email notifications in order to create a better user experience and/or more likelihood for a conversion. It may be helpful to build a flowchart of the new notification experience so that your team can have one central point of reference for where your API logic will need to be updated.
If the user has opted in to receiving SMS messages, we recommend using SMS as the default notification channel for that user. Research shows that SMS has a 98% open rate compared to email’s 20%. However, users are also likely to feel that SMS is more invasive, and therefore it should be used more sparingly than email. You should have a high quality bar for your SMS notifications and use email for lower-priority content.
There are no hard rules for when to default to SMS vs. Email and your users should always have the option to select their preferred channel for each notification, but there are a few guidelines we recommend following. For notifications that involve some component to time, such as event reminders or ETAs, SMS is a generally accepted communication method. ETAs in particular are a category where most users expect SMS rather than Email.
Two categories where it may make sense to send both SMS and Email are financial transaction notifications, such as a deposit or transfer confirmation, and time-sensitive alerts where human action is required. There are many other great use cases for SMS, but these are some of the more common use cases we’ve come across.
While it may seem like more notifications means more chances to get the user’s attention, we strongly advise against sending both an SMS and an Email for the same event. This risks appearing spammy, and if you default to SMS, an additional email will have diminishing returns. There may be some exceptions, however; for example, you might want to let users opt in to both email and SMS confirmation about an important event on your platform (e.g. delivery of goods or services) where the risk of being perceived as spam is low.
While a user opt-in is required for most emails you will send, it is a hard requirement for all SMS notifications. Current UX best practices recommend a double opt-in for SMS, where the first SMS that the user receives is a request to confirm subscription to SMS notifications. Whatever your choices are in this area, we recommend that you seek guidance from your legal counsel to ensure that you are following all the necessary steps to ensure compliance with CAN-SPAM, CITA, and TCPA in the U.S., and any other rules that may apply in other countries or regions.
You most likely have at least 10–20 different email notifications that exist at various logical points in your codebase (a promotional notification, a notification when a purchase is made, etc.), each with its own template for customizing the email to the specific user or product it is targeting. To add SMS, you will need to build new templates.
One common anti-pattern is to combine templating logic with the code for making the API calls themselves. While this might be acceptable when you have only one channel, when you are integrating several channels at the same point in your code, the complexity tends to grow exponentially with each channel that you add. Therefore, as a best practice, we recommend creating flexible templates in order to make the integration cleaner.
If your existing email notifications use hard-coded templates, we recommend migrating to SendGrid’s Dynamic Templates. SendGrid provides HTML templates that you can customize entirely in code or with a WYSYWIG editor, with Handlebars syntax for dynamic personalization. Dynamic templates will simplify your notification logic immensely, which is a good first step if you plan to add more channels.
For SMS, there is no comparable tool for accessing and editing saved templates, so you will need to store hard-coded templates in your site’s backend. While you could use simple string concatenation or interpolation, we recommend using a text templating language like Handlebars, which makes your templates more human-readable and easier to adjust.
At this stage, you may also want to consider how you’ll support MMS elements like images. Twilio supports sending up to 10 media files (see the mediaUrl property here). There are size and type restrictions, and you can’t inline the images; they will appear either before or after the text, and that’s determined by Twilio.
Once your email templating is streamlined, you should be left with much simpler API calls. Next comes the logic for the integration itself, as you add an SMS message to places in your system where you currently send an email.
Based on the UX best practices, we do not recommend sending both an email and an SMS at the same time unless requested by a user. Instead, you will want to have some if/then logic that tries one channel first, and failing that, defaults to the other. So, for each of your existing email notifications, you will want to create some logic that says something along the lines of: “if we have the user’s phone number, send them an SMS via Twilio; if not, send them an email via SendGrid”—or vice-versa.
Each channel adds a new form of consent to be managed, so when integrating Twilio on top of SendGrid, you will probably want to take another look at how you are managing user consent internally. SendGrid’s Unsubscribe Groups are a great tool for this, but you will need to normalize the data if you want a single source of truth that can work across both email and SMS.
We recommend creating a database table that stores your users’ preferences for each notification and channel combination. While this can get combinatorially complex, you will want to make sure that users can manage the combinations independently. A user might want to opt in to SMS and email for order status updates, for example, while for marketing announcements they might want to turn SMS off and enable emails.
While revamping your settings and opt-in, don’t forget to consider your unsubscribe flow. You may want to build a webpage that lets users unsubscribe from certain categories of SMS messages, or to switch from SMS to email. Otherwise, their only option for unsubscribing will be to text STOP, meaning they will opt out of SMS notifications entirely.
To make sure your notifications successfully reach your users or customers, we recommend verifying that your messages are delivered and creating a fall-back plan if delivery fails.
You are probably already calling SendGrid’s Email Activity Feed API to verify that your messages have been delivered (the success code you receive when you first call their API only says that SendGrid has received your request). If you haven’t built this yet, we recommend building it as a background worker that can execute multiple times. We’ve seen delivery confirmation often take more than 10 minutes, and in some cases multiple hours. Therefore, you should consider setting a TTL and an appropriate retry delay. Also, be careful with throughput, as we’ve found it is much easier to get throttled on these calls than in the Mail Send calls. If your volume is higher than a few dozen messages per hour, consider setting up a webhook receiver from SendGrid instead of calling the API.
A common approach here is to reuse your background worker for SendGrid verification to perform the check with Twilio as well. You’ll want to add an if-statement to your worker which says to check either the Twilio Messages API or the SendGrid Email Activity Feed API depending on the message ID returned from the original Send call. If you sent the message over both email and SMS, then you’ll need to check both APIs separately. As with SendGrid, you also have the option of setting up a webhook receiver to track delivery status.
If delivery fails in one of these channels, it is important to consider how you want your system to behave. Do you want to attempt an email message if SMS delivery fails? Would it be appropriate to send an SMS if an email failed? The answers depend on your use case, but you can create the desired behavior by adding to your routing logic. It’s usually a good idea to send Email when an SMS fails in order to ensure the notification gets delivered, but it’s not always a good idea to send an SMS when Email fails, since you want to reserve SMS for more important use cases.
In general, we recommend that you normalize the deliverability results across your channels and perform a side-by-side comparison of delivery rates across all of your channels and all of your providers beyond just SendGrid and Twilio.
One of the most challenging aspects of integrating Twilio and SendGrid is understanding your engagement performance across channels. While SendGrid offers click-through tracking out-of-the-box, Twilio does not, so you will need to build some integration points between the two channels in order to surface cross-channel analytics.
We recommend using HTTP redirects to track the click-through performance of each of your email and SMS templates. You can create a specific URL to use for tracking each notification in each channel, and then log the source of the click while forwarding the user to the right page (usually, redirects happen so quickly that they are not noticeable).
When adding SMS notifications to your existing email pipeline, you will also want to think about the key you use to identify a user that has engaged with the content. The email address won’t be helpful for SMS, and vice-versa. Instead, you will want to create a unique per-user key that helps you aggregate metrics across channels for the same recipient. At Courier, we recommend that customers choose a recipient ID that won’t change; typically, the user ID values from your system work well as recipient IDs.
Adding SMS to existing Email infrastructure is a great way to start taking advantage of the multi-channel world we live in in order to increase user engagement, but many kinds of notifications are better served over other channels such as mobile and desktop push, Slack, Microsoft Teams, or other Direct Messaging platforms such as Facebook Messenger and Whatsapp. The unfortunate reality of working with these APIs is that many of the steps list above need to be replicated individually for each new channel. Every channel has its own unique formatting requirements for templates and its own API with different rules for failure. Moreover, every additional channel adds another layer of complexity to managing user preferences and to building analytics to get a complete picture of user engagement with notifications.
At scale, companies like LinkedIn, Airbnb, and Uber solve these challenges by employing teams of 20+ Full-Time software engineers dedicated to notification infrastructure. At Courier, we’re on a mission to build this as a service so that adding new channels does not introduce new complexity into your codebase, you can still take advantage of the unique features of each channel, and we build advanced functionality on top of basic notifications such as subscriber management and API-driven white-labeling.
If you’d like to learn more about how to use Courier, or just chat about notifications in general, we’d love to connect with you!