loading...
Cover image for Forward incoming SMS messages to email with Node.js, SendGrid and Twilio Functions
Twilio

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

philnash profile image Phil Nash Updated on ・5 min read

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.

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.


Forward incoming SMS messages to email with Node.js, SendGrid and Twilio Functions was originally published on the Twilio blog on July 18, 2017.

Posted on by:

philnash profile

Phil Nash

@philnash

Developer evangelist for Twilio and Authy. I write JavaScript and Ruby. Probably listening to ska punk right now. console.log('🍻');

Twilio

We ❤️developers. Unlock the magic of communications to improve human experience. Twilio has democratized channels like voice, text, chat, and video through APIs.

Discussion

markdown guide
 

Love the simplicity of this solution, but I am not able to get it to work. Could something have changed since you published this article? With everything set I am getting a 11200 - HTTP retrieval failure error every time I send an SMS to my twilio number. Any changes needed to your original post? If it still works for you, what would you need to help point me in the right direction? I am not sure if something changed on Twilio or on Sendgrid. I have quadruple checked the code and don't see any differences from yours.

I appreciate any help you can offer in addition to your very helpful original post!

Dave

 

Oh, this might be because the got module doesn't come installed by default any more. Try going to the config section and adding got to the npm module dependency.

 

Oh good! I’m out at a conference right now, but I will update this when I get the chance.

 

Yes! Another cover image gif! Or just cover gif?

Twilio Functions looks great. I think it'll work for one of my little ideas I had, where my phone sends an automated message if the battery is dead and the message hasn't been delivered. Thanks for the post!

 

Hey Phil, awesome post! This is a great write-up, and really captures the magic of Twilio's platform. For such a long time, SMS felt like it's own black box, but with the API and new Twilio Functions it seems like it's becoming increasingly accessible to leverage that protocol in new and interesting ways.

The metaphor of Twilio Functions as "plumbing" definitely lands -- it's like a more-technical but more-powerful version of Zapier for messaging.

I think that two additional ideas for future example Twilio Functions (and just valuable to use) would be:

  • respond to those same messages from the gMail thread
  • read/respond from Slack (since their mobile app is so solid)

Thanks as always for sharing!

 

I also get the HTTP retrieval error bur I have the got NPM setup (8.3.1)
HTTPError: Response code 401 (Unauthorized)

Great idea though to forward messages.

 

Got it working. I changed the version of got to 6.7.1 and it worked. Thanks.