How to Add Custom Attributes to Twilio SMS Campaigns

June 01, 2022
Written by

KG - How to Add Custom Attributes to Twilio SMS.png

This post covers how to add custom attributes (AKA metadata) to an SMS message. This allows your team to receive data on SMS campaigns sent to your customers, log activity, and more! The examples below are written using Twilio’s Node.js helper library.

Custom attributes provide a system to categorize various digital marketing and feature campaigns. If you want to get fancy with personalization, metadata can also track variants within a single test. Even with the absence of a formal metadata parameter on the programmable SMS endpoint, we can still add attributes for campaign managers to track customer analytics. And, really, someone’s boss asked for a consumer trends report for the third time.

Basically, tech experts want to learn what features work and what features flop. If you run digital campaigns through SMS or Voice (or were the lucky recipient of the Jira task to add this feature), you’re going to want to read this.

Prerequisites

Solution

To demonstrate how and why to add custom attributes to an SMS message, let’s walk through an example scenario. A cafe named Night Owl Caffeine runs general promotions for their brand throughout the year, but they want to track the performance of a single seasonal campaign. In October they will send an SMS blast to the customers in the loyalty program for 25% off pumpkin spice coffee (wow, what a savings). Their platform is built on Twilio programmable messaging, and they plan to distinguish between each promotional SMS campaign by using a campaign ID. This maps customers by phone number to the received SMS promotions in their data warehouse or CRM.

At this time, there is no custom attribute or metadata field available on the Twilio Programmable SMS send endpoint to track campaign IDs. However, we can append a query string with the campaign ID to the optional status callback parameter in the create message post request.

Here is some sample code written with the Twilio Node.js helper library to achieve this. Assume the dynamicCampaignVariable is pulled from a data source instead of being assigned as a static variable. The Twilio client is used to create an SMS message with the standard to, from, and message body parameters. The fourth parameter statusCallback is optional but necessary for our campaign tracking use case. The campaign ID is appended to the status callback URL as a query string.

// Assume the campaign variable is coming from
// a dynamic source, such as a CRM or database
let dynamicCampaignVariable = 22;

// Twilio's node helper library to sends an SMS message
// we can add the campaign variable to the statusCallback
twilioClient.messages.create({
 to: process.env.MY_PHONE_NUMBER,
 from: process.env.TWILIO_PHONE_NUMBER,
 body: 'Stop by your local Night Owl Caffeine cafe today for 25% off a pumpkin spice latte!',
 statusCallback: `https://${process.env.NGROK_HTTPS_URL}/sms-status-callback?campaign_id=${dynamicCampaignVariable}`,
})
.then(message => {
 console.log('Message sent: ', message);
})
.catch(err => {
 console.log('Message failed to send: ', err);
});

The statusCallback POST endpoint is written with node and express. This endpoint is hit every time an SMS is sent with the above Twilio client (and every time Twilio receives an SMS status receipt from the carrier). The dynamicCampaignVariable is attached to the query string in the request.

// StatusCallback endpoint
app.post('/sms-status-callback', (req, res) => {
 const smsStatus = req.body.SmsStatus.toLowerCase();
 console.log('SMS statusCallback endpoint hit. Status: ', smsStatus);

 // If the status is 'delivered' log the data, log the data
 if (smsStatus === 'delivered') {
   // Get metadata from the query string
   // Send it to a database, do whatever you gotta do!
   console.log('Metadata from delivered SMS: ', req.query);
 }
});

Within this endpoint, all information about the SMS is available including the campaign ID. Twilio will hit this endpoint every time the SMS status is updated from our Supernetwork, which hooks directly to a carrier’s delivery receipts. We recommend checking for the ‘Delivered’ status before logging this to your database or CRM to avoid adding duplicate records or failed messages. Recording campaigns directly in the Twilio code that sends the SMS and provides a delivery status receipt is much simpler than building a custom tracker.

Adding a campaign ID is only one example of adding metadata to an SMS message! Custom attributes of all sorts can be added: audience buckets a customer has been added to, friendly names for a campaign such as “pumpkin_spice_coupon_takeover” - it’s up to you.

Disclaimer for sensitive information: We advise you to never put sensitive information in a query string. No passwords, no PII, no PHI. Campaign IDs, general attributes for tagging and logging, and favorite soups are fine.

Tutorial

Alright, this is a simple guide to get the above code examples running on your own machine. This is where the prerequisites become requisites.

Step 1 - Create a Twilio Account & Buy a Phone Number

Step 2 - Install and run ngrok

Go to the ngrok website; download and install ngrok. This is a free program that creates a safe HTTPS connection.

Next, run ngrok on port 8080 to get a secure HTTPS connection. Twilio products will only work with secure connections, so we use ngrok to create a tunnel to our localhost port and securely expose it to the Internet. This is needed when testing in a development environment (such as your own computer), but in a product deployment you would use your own domain and an SSL certificate. Run the following command in your terminal:

$ ngrok http 8080

Step 3 - Get the Repo

Leave ngrok running. In a new terminal window, clone this Github repository. This app contains the Twilio Node helper library template to send an SMS from the Twilio number to your phone number, and an express server for the status callback POST endpoint. The command to clone and set up this repository are shown below:

$ git clone git@github.com:kristajg/twilio-custom-attributes.git
$ cd twilio-custom-attributes
$ npm i

Follow the README directions in the application. Add your Twilio account credentials, Twilio phone number, and your phone number in E.164 format to the .env file. Add the ngrok HTTPS URL to the status callback endpoint in index.js.

Step 4 - Run the Clone Repo and Marvel at the Metadata

Run the app with the following command:

$ npm run dev

Now observe the campaign ID appear from the console log after you receive a super cool text on your phone number, sent from your Twilio phone number. The statusCallback endpoint will be hit twice assuming all is well and the carrier does in fact send status receipts: once for the initial send (sent) and once for a completed delivery (delivered). On the delivered status, we grab the metadata and can log this in our database or CRM. Neat!

Conclusion & Bonus Solutions for Voice

Now you know how to track campaigns with metadata within an SMS campaign. But why stop at SMS? You can do the same with calls placed through the Programmable Voice API by using the same statusCallback technique. TwiML and SIP can pass custom information as well. Metadata for all!

 

Krista Goralczyk is a Solutions Engineer at Twilio. She enjoys finding ways to ease the minds of developers everywhere, one code example at a time. She can be reached at kgoralczyk [at] twilio.com.