DEV Community

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

Posted on • Updated on • Originally published at twilio.com

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

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) {

};
Enter fullscreen mode Exit fullscreen mode

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
      }
    ]
  };
Enter fullscreen mode Exit fullscreen mode

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);
    });
};
Enter fullscreen mode Exit fullscreen mode

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.

Oldest comments (9)

Collapse
 
peter profile image
Peter Kim Frank

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!

Collapse
 
andy profile image
Andy Zhao (he/him)

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!

Collapse
 
dsazama profile image
Dave Sazama

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

Collapse
 
philnash profile image
Phil Nash

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.

Collapse
 
dsazama profile image
Dave Sazama

That was it! Thanks!

Thread Thread
 
philnash profile image
Phil Nash

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

Some comments may only be visible to logged-in visitors. Sign in to view all comments.