Send Daily SMS Reminders Using Firebase, Node.js and Twilio

September 29, 2014
Written by

empire-state

No need to tie a string around your finger. Using Node.js, Firebase and Twilio you can build your own daily SMS reminder application.

List of Ingredients

We’ll be using a few tools to build this app. You’ll want to have these set up before you continue on:

  • Twilio: To send and receive SMS messages. Don’t have a Twilio account? Sign up for Free.
  • Firebase: A realtime database API. We’ll be using it to store the users who have subscribed to our service.
  • Node.js: A platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications.

Scheduling SMS Messages with Cron

To get started we’ll need to install a couple npm packages. We’ll be using the twilio package to send text messages and we’ll be using the cron package to schedule the time we want to send the text messages. You can install them by running the following commands:

npm install twilio
npm install cron

Create a new file called app.js and require the twilio and cron packages:

var twilio = require('twilio'),
var client = new twilio('ACCOUNTSID', 'AUTHTOKEN'),
cronJob = require('cron').CronJob;

Let’s write some code that sends a text message at 6pm every day:

var textJob = new cronJob( '0 18 * * *', function(){
  client.messages.create( { to:'YOURPHONENUMBER', from:'YOURTWILIONUMBER', body:'Hello! Hope you’re having a good day!' }, function( err, data ) {});
},  null, true);

Wait, you’re probably wondering what the string we’re passing as the first argument to our cronJob is. That is a format specific to cron that let’s us define the time and frequency of when we want this job to fire. In this case, at 0 minutes 18 hours every day. This article does a nice job of breaking down cron format.

In the callback to our cronJob, we use the Twilio client library to send a message. We pass the to and from numbers and the body of the message we want to send.

Run this code and wait in anticipation for your text message. If it’s 10am, you probably don’t want to have to wait 8 hours to see if your code works. Just update the Cron format to send at an earlier time. Here’s a hint, to send at 10:13am you’d use this format: “13 10 * * *”.

You now have a basic version of this app, but you most likely don’t want to just send a message to yourself everyday. If you do then congrats! You’re all done! For the rest of us, we can make a couple small code changes to have this send to multiple phone numbers.

First, let’s add a new variable called numbers that contains the phone numbers we want to send messages to:

var numbers = ['YOURPHONENUMBER', 'YOURFRIENDSPHONENUMBER'];

Then let’s update the code in our textJob to loop over these phone numbers and send a message to them:

for( var i = 0; i < numbers.length; i++ ) {
  client.messages.create( { to:numbers[i], from:'YOURTWILIONUMBER', body:'Hello! Hope you’re having a good day.'}, function( err, data ) {
    console.log( data.body );
  });
}

Receiving SMS Messages

Now that we’re sending an SMS message to different numbers at our desired time, let’s update this code to know when a users send a text message to our app. Twilio uses webhooks to let your server know when an incoming message or phone call comes into our app. We need to set up an endpoint that we can tell Twilio to use for the messaging webhook.

We’ll be using the Express framework to set up our node web server to receive the POST request from Twilio so we’ll need to install the express package. We’ll also be using the body-parser module so we’ll going to install that as well:

npm install express
npm install body-parser

At the beginning of our app.js file we’ll need to require express and initialize it into a variable called app. We’re also going to use the bodyParser middleware to make it easy to use the data we’ll get getting in our POST request.

var express = require('express');
bodyParser = require('body-parser');
var MessagingResponse = require('twilio').twiml.MessagingResponse;
app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

We’re going to add a route for /message that responds with some TwiML. TwiML is a basic set of instructions you can use to tell Twilio what to do when you receive an incoming call or SMS message. Our code will look like this:

app.post('/message', function (req, res) {
  var resp = new MessagingResponse();
  resp.message('Thanks for subscribing!');
  res.writeHead(200, {
    'Content-Type':'text/xml'
  });
  res.end(resp.toString());
});

We use the Twilio node library to initialize a new TwimlResponse. We then use the Message verb to set what we want to respond to the message with. In this case we’ll just say “Thanks for subscribing!”. Then we’ll set the content-type of our response to text/xml and send the string representation of the TwimlResponse we built.

Finally, let’s set our server to listen on port 3000.

var server = app.listen(3000, function() {
  console.log('Listening on port %d', server.address().port);
});

Now let’s fire up our app:

node app.js

If you’re running this locally, you’ll want to make sure you’ve got ngrok running before you go to the next step. If you haven’t used ngrok before, my good buddy Kevin has put together a great tutorial to help you get started.

Now that we have our server running, we need to tell twilio to use this messaging url as a our Message Request URL:

Send an SMS message to your Twilio number and you should get a response back. If you don’t, take a look at the Twilio App Monitor to help determine what went wrong.

Saving Users in Firebase

We’ve setup a script that sends out a text message at the same time every day and we’ve given users the ability to send a text message into our app. There’s just one last thing left to do. We need to save our users’ information when they send a text to our app. We’ll be using Firebase as our datastore so we need to install the firebase node module:

npm install firebase

Now that we’ve installed the Firebase module let’s require and initialize it at the top of our app.js file:

var Firebase = require('firebase'),
usersRef = new Firebase('{FIREBASEURL}/Users/');

When you sign for a Firebase account they provide a url for your datastore, make sure you update this code to replace {FIREBASEURL} with this url.

Since we’ll be pulling the phone numbers from Firebase we’ll want to update our numbers variable to be an empty array and then fill it with info from the database. Firebase is a realtime database and built around the premise of subscribing to events as opposed to reading on demand. We’re going to subscribe to an update event whenever a new user is added:

var numbers = [];
usersRef.on('child_added', function(snapshot) {
numbers.push( snapshot.val() );
  console.log( 'Added number ' + snapshot.val() );
});

Now we need to add users to our database when they text in subscribe. Let’s revisit our message route to make this update:

app.post('/message', function (req, res) {
  var resp = new MessagingResponse();
  if( req.body.Body.trim().toLowerCase() === 'subscribe' ) {
    var fromNum = req.body.From;
    if(numbers.indexOf(fromNum) !== -1) {
      resp.message('You already subscribed!');
    } else {
      resp.message('Thank you, you are now subscribed. Reply "STOP" to stop receiving updates.');
      usersRef.push(fromNum);
    }
  } else {
    resp.message('Welcome to Daily Updates. Text "Subscribe" receive updates.');
  }

  res.writeHead(200, {
    'Content-Type':'text/xml'
  });
  res.end(resp.toString());

});

When the Twilio messages webhook triggers a new POST request to your server we include request parameters with information about the message. We’ll be using the Body parameter to examine the content the user texted in and the From parameter to determine the number they texted from. If they’ve texted in the word ‘subscribe’ and they’re not already in our database we’ll use the push function on our Firebase reference to add them.

Our app is now ready to go, let’s run it and give it a try:

node app.js

What Will You Do

We did it! Now that you’ve built a simple daily SMS reminder app it’s your chance to customize the daily message to whatever you want. Maybe a random Jack Handy quote, headline from the NY Times or a link to a hilarious gif. Once you’re done reach out to me on twitter or e-mail and let me know what you’ve made. I’d love to subscribe.