Forward incoming SMS messages to email with Node.js, SendGrid and Twilio Functions

July 18, 2017
Written by
Phil Nash
Twilion

message-to-mail.gif

Due to the changes that came with the release of Node version 18.x - This blog post is no longer valid.

If you wish to use this blog post as a reference, you will need to edit the source code to work with Node version 18 and above.

If you want to read incoming SMS messages sent to your Twilio number in your email then do I have a neat solution for you today. We’re going to use Twilio Functions and SendGrid to forward SMS messages directly to your email address.

Things you’ll need

Let’s get building

The entire operation of forwarding SMS messages to your email address will only take one function, so we’re going to build it using a Twilio Function. If you’ve not heard of Twilio Functions, they are a serverless environment that you can use to run Node.js code. This means we don’t need a development environment or somewhere to deploy to, we just write our code in Twilio and use it.

We do need to configure some variables though.

First up, config

In order to use the SendGrid API to send emails we need a SendGrid API key. Head to the API Keys area in the SendGrid dashboard and create yourself one.

Hit the 'Create API key' link on the API Keys dashboard page in the SendGrid admin

Open up your Twilio console and head to the Functions configure section. Add a new environment variable called SENDGRID_API_KEY and paste in your new API key.

We need to make two more environment variables too, one for the email you will use to receive your SMS messages and one to send them from. If you have a domain setup within SendGrid then I recommend you use that, but you can use any email address you want as the sender, even the one you are sending to.

Enter these email addresses in the environment variables section as TO_EMAIL_ADDRESS and FROM_EMAIL_ADDRESS.

You should have three new keys and values in the environment variables section

We’re done with the config, it’s time to write some code.

Let’s go write a Function

Head to the Functions management page and create yourself a new function. Since we’re dealing with incoming SMS messages, pick the “Hello SMS” template.

Normally with Node.js this would be the time to start a search for the SendGrid npm package, but Functions don’t currently allow you to install other packages. Thankfully there is one package available to us that will help us make HTTP requests easily: got.

Update: Functions stopped including got by default but allows you to install dependencies from npm. To continue with this post you now need to add got to your dependencies. Open your Functions configuration page and scroll down to dependencies. Add got and the version 8.3.1 then save.

At the top of your code require the got module, then delete everything within the function. You should have:

const got = require('got');

exports.handler = function(context, event, callback) {

};

We need to build up an API request that SendGrid will understand. There’s an example of the JSON we need to send on the documentation page for the v3 API that we’re going to use. Let’s create that as a JavaScript object with our own values, within the function:

exports.handler = function(context, event, callback) {
  const requestBody = {
    personalizations: [{ to: [{ email: context.TO_EMAIL_ADDRESS }] }],
    from: { email: context.FROM_EMAIL_ADDRESS },
    subject: `New SMS message from: ${event.From}`,
    content: [
      {
        type: 'text/plain',
        value: event.Body
      }
    ]
  };

Here we are using event.From to get the number that sent us the SMS message and event.Body to get the text of the incoming message. The event object contains all the parameters that are passed to the function as part of the request.

Now we need to send this object to the API to send the email. Use got.post to make a POST request to the API URL, https://api.sendgrid.com/v3/mail/send, and pass an object of options that describes the request headers and body.

If the request succeeds we will return an empty TwiML response and if it fails we’ll log that by calling the Function callback with the error.

  got.post('https://api.sendgrid.com/v3/mail/send', {
    headers: {
      Authorization: `Bearer ${context.SENDGRID_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(requestBody)
  })
    .then(response => {
      let twiml = new Twilio.twiml.MessagingResponse();
      callback(null, twiml);
    })
    .catch(err => {
      callback(err);
    });
};

And that’s all the code!

Give your Function a name that makes it easy to remember and a path and save it.

Add a name to your function in the 'Function name' field, a path in the 'Path' field and save it with the button at the bottom of the page.

Hooking up your Twilio number

All that is left to do is hook up your Twilio number to your Function. Go to the numbers section of the Twilio console and edit the number you want to use. In the messaging section, where it says “A message comes in” choose Function, then select your Function from the drop down.

On the phone number edit screen, configure the messaging section with 'Webhooks, TwiML Bins or Functions', choose 'Function' for when a message comes in and then pick your function from the resulting drop down.

Hit the save button and you’re done!

Testing

Time to test your new Function. Send a text message to your Twilio number and open up your email.

An image of the message I sent myself in my email client. It worked!

Note: if you do not have a domain set up with SendGrid check your spam folder for the email. If you’re using gmail, like I am, you can add an exception for the email address to never send it to spam and always receive your incoming messages.

Twilio Functions make the plumbing easy

With a Twilio Function and 31 lines of Node.js we set up forwarding SMS messages to email using the SendGrid API and we didn’t even need our own server. Twilio Functions are really useful for bits of plumbing like this for Twilio numbers.

I got excited about this and started a repo of useful Twilio Functions, including the one that we built in this post, that are tested and ready for you to use. There’s only a few available so far but since it’s an open repo you can either request new Functions in the issues or submit your own via pull request.

I’ll be adding to the repo and I’d love to see your contributions too!

Got any questions about using Twilio Functions or built anything cool with them? Drop me a note in the comments below or hit me up on Twitter.