Tuesday, 7 July, 2020 UTC


Summary

As a solutions architect at Twilio, I have the opportunity to speak with customers on a daily basis. Each customer has unique requirements and in many cases, a customer is trying to enable SMS notifications for legacy systems that only support email. These customers quickly realize that sending an email to <phone number>@<wireless carrier>.com doesn’t scale.
Even though creating an application to handle email-to-SMS is very straightforward, the pushback I receive from customers is that they don’t want to maintain a server to host it. In this post, I’ll show you how to create a serverless Email to SMS gateway using a combination of Twilio SendGrid and AWS Lambda.
How does this SMS gateway work?
SendGrid accepts the inbound email and triggers a HTTP POST to our AWS API gateway. The payload of the POST request is then processed by Lambda. Using the Twilio helper library, an outbound SMS is generated.
What you will need:
  • Sample code
  • Twilio account
  • SendGrid account
  • AWS account
  • Twilio phone number

Step 1: Gather your Twilio account information

If you haven’t already set up a Twilio account and purchased a phone number, do that first. Details on our free trial can be found here.
You will also need the following information in this next step:
  • Account SID: Located on the console home screen
  • Auth Token: Also on the console home screen
  • Twilio Phone Number: This is the phone number SMS messages will come from

Step 2: Download the sample code

AWS Lambda doesn’t allow you to install npm packages through its online interface. Because of this limitation, we'll be packaging up the code and packages offline.
In this section, we'll download the code and packages and add them to a zip file, which we'll later upload to AWS.
  1. Download/clone this repo to your desktop: https://github.com/bdm1981/emailtosms-gateway
  2. cd into the directory and run npm install
  3. ZIP the entire directory
This will be uploaded to Lambda in the next step.
If you are curious, the core logic lives in the index.js file. Here is an excerpt of the code you can find in the above repo:
exports.handler = async (event) => {  let data = await parser.parse(event);   console.log("input data: ", data);   if (validateSender(data.from)) {  // parse the to number from the left-hand side of the email address   let regexp = /(^.\d+[^@])/g;   let to = data.to.match(regexp)[0];   let body = `Subject: ${data.subject}\nMessage: ${data.text}`;   let message = await client.messages.create({  body: body,   from: process.env.FROM,   to: to,  });   console.log("Message Output: ", message);   const response = {  statusCode: 200,   body: JSON.stringify({ input: data, output: message }),  };   return response;  } else {  const response = {  statusCode: 403,   body: "Unauthorized Sender",  };   return response;  } }; 
This code performs the following steps:
  • Parses out the from, to, body, and subject from the payload sent by SendGrid
  • The from address domain is checked against a list of allowed sending domains
  • The phone number is extracted from the to address
  • Finally a SMS message is created with the Twilio helper library
Now you have a function prepared to forward email to SMS. In the next section, we’ll upload the code, set the environment variables, and set up API Gateway.

Step 3: Setup the Lambda Function and API Gateway

In the last section, you prepared the code you'll need to forward emails to SMS. Now, we'll zip everything up, upload it to AWS, and then use API Gateway to provide a route.

Add a new Lambda Function

  1. From the AWS Console navigate to Lambda by searching "lambda" under Find Services
  2. Click on Create Function
  3. Select Author from scratch, provide a name for the function, Select Runtime Node.js 12.x
  4. Click Create Function

Upload a zip file

Now you’ve created a Function and can add the code we’ve prepared. At this point, you’ll need to upload the zip file with our assets.
Select Upload a .zip file in the Function code section.
Then pick the zip file we created earlier.

Add environment variables

In our code, we left some sections populated with variables. In Lambda, you enter environment variables in a secure screen.
In the Environment Variable Section, create 4 variables:
  • AUTH_TOKEN: Gathered in Step 1
  • ACCOUNT_SID: Gathered in Step 1
  • FROM: Phone Number Gathered in Step 1
  • DOMAINS: provide a comma-separated list of domains allowed to send email to this gateway.

Add a trigger and set up API Gateway

Now everything you need to set up with the code is finished. At this point, we only need a way to trigger the function – that’s where API Gateway comes into play.
From the Lambda Function Designer, click on Add trigger
Select API Gateway. Check REST API and add multipart/form-data to the Binary media types
After you filled out the form click Add. Finally copy the URL of the API endpoint
Now you have a new route which will trigger the Lambda function you uploaded. Next we’ll configure SendGrid to hit that route on an incoming email.

Step 4: SendGrid setup

With our forwarding function and route in place, we only need to trigger the setup when we receive an email. We’re going to use SendGrid’s Inbound Parse feature.
This article assumes a SendGrid account has already been set up and the DNS has been configured for your domain. If this hasn’t been completed, follow the instructions outlined here.
From the SendGrid console navigate to settings -> Inbound Parse.
Click on Add Host & URL
Any email sent to this host will now trigger a HTTP POST to the destination URL provided; for example, to [email protected]
Test time!
Now, try to send a test email – it should show up on your mobile device!
Email:
Resulting SMS:

Why didn’t I use Twilio Functions?

Twilio Functions would be a natural solution for this. Unfortunately, binary content types such as multipart/form-data is not supported with Twilio Functions along with many other cloud function solutions. AWS made some recent changes to API-Gateway that enable binary content types.
Want to add more Email to SMS features?
Congratulations – you now have a serverless solution to forward incoming emails to SMS using Twilio SendGrid, Programmable SMS, and AWS Lambda. If you’d like to continue to build this solution, here are some ideas:
  • Enhance the domain validation for specific senders
  • Handle responses to these SMS Messages: https://www.twilio.com/blog/using-twilio-studio-conversations-sms
  • Support predefined recipient groups
We can’t wait to see what you build!
Brad McAllister is a Solutions Architect at Twilio. He’s solving the world's problems one line of code at a time. He can be reached at bmcallister [at] twilio.com.