Ionic, Twilio and Node Scheduler – A Reminder App – Part I [Server]

This post is part 1 of 2 in the series Ionic, Twilio and Node Scheduler – A Reminder App
Tweet about this on TwitterShare on LinkedIn9Share on Google+7Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page

Ionic, Twilio and Node Scheduler – A Reminder App – Part I [Server]

In this post, we will take a look at building a Reminder app. With this mobile hybrid app, a user can register, login and then create a reminder. While creating the reminder, the user has an option to schedule a Call or a SMS to remind him/her of the task at the scheduled time. Sweet right?

Our client will be built using Ionic Framework and our server side will be built on top of Node.js with Express.js as the framework. We will be leveraging a node module named node-schedule to schedule tasks. And we will be using the powerful cloud based communication API exposed by Twilio to make a call or send an SMS.

Below is a video recording of the app. There is no audio, but you can find the recorded phone call after that

Note : There is ~25 seconds gap between scheduling the call and the call arriving. The call start @ 01.06 mins into the video.

Screenshot_2014-09-29-23-51-47 Screenshot_2014-09-29-23-53-15 Screenshot_2014-09-29-23-54-00

You can find the completed code here.

This post is going to be the first half of the tutorial, where we would be working on the server side to build the REST API with which our Ionic app would consume to register, authenticate users and manage reminders.

For the Ionic app take a look : Ionic, Twilio and Node Scheduler – A Reminder App – Part II [Client]

So, Let us get started.


As mentioned earlier, we would be using Node.js and Express.js for building the REST API. If you are new to Node.js, refer this and Express.js refer this. We will be using DiskDB a file system based DB as our persistence layer. You can get more information about DiskDB here .

Apart from that we will be using Twilio to make Calls and send messages. I have written a very basic app using Twilio here, that shows how to setup Twilio and the basics of TwiML, which I would not cover here. Also do check out ngrok as we are going using this to host our locally hosted apps as publicly accessible URLs.

The communication between layers is achieved via REST API over HTTP. You can find more info on that here.


We have 3 major pieces that we are trying to integrate. The Ionic application with the node.js application. The node.js application with the node-scheduler and finally the node-scheduler with Twilio cloud services.


You can see from the above diagram as how each layer interacts with the other. Do remember that we are using REST API to communicate between the Ionic app and the node.js server and the node.js server and Twilio.

Note : Twilio connects to our node.js application at the time of making the call to fetch the TwiML. TwiML will be the response read out by Twilio IVR to the end user. This is also achieved via REST API, where Twilio would consume an end point on our node.js app.

Setting up the Server

Now we have a basic idea of what we are building and how we are going to build it. So let us get started. First, create a new folder named remindMe. Inside that create another folder named server. We will create a new Node.js app here. Open a new terminal/prompt inside the server folder and run

npm init

Fill it up as applicable. Next, we will install the required dependencies. Run

npm install --save bcrypt body-parser diskdb express morgan node-schedule twilio

The final package.json would look like

Now, we will configure and setup the Express.js server. Create a new file named app.js at the root of the server folder and update it as below

Standard Express.js config.

Now, we will create a list of routes that our server will support. Create a new folder at the root of server folder and name it routes. Inside the routes folder, create a new file named index.js. Update index.js as below

Things to notice

Line 4,5,6 : Include the route definitions

Line 9,10 : Login and Register routes

Line 13-17 : Routes to perform CRUD operations on the routes

Line 20 : The endpoint that will be invoked by Twilio when a call is placed to a user. This endpoint will return the custom TwiML for the current user/reminder.

First we will work on the authentication part. We will be splitting the app into 3 layers. One the routes, next the logic part and finally the DB layer.  We will also have a message layer that will support internalization if needed.

Inside the routes folder create another file named auth.js and update it as below.

Things to notice

Line 1 : We require the list of messages that we want to send to the client

Line 4 : We define the register method

Line 7 : Validate the data in the request. Incase of error, we will send back a 400.

Line 16 : We call the register method inside the logic layer to start processing the registration.

Line 18 : The logic layer sends -1 as response if the user with this username already exists. We send back a 409

Line 25 : On successful registration we send a 200 with the newly created user object.

The same logic is applicable for the login as well. We validate the incoming data, process it and respond accordingly.

The above layer is responsible for accepting the request and dispatching the response only.

Now, we will write the business logic for the auth process. Create a new folder named logic inside the server folder. We will write all the logic needed to process the request here.

Inside the logic folder, create another folder named auth. Inside this folder, create a file named auth.js. Update auth.js as below

Things to notice

Line 1 : We include the DB methods

Line 2 : We include the logic to create a password hash while registering and compare passwords while login.

Line 8 : During the registration, we create a new password hash

Line 11 : We save the user object to DB and return the response.

Line 16 : During the login step, we check if a user with this credentials exists. Else we return -2. Then we check if the passwords match, else we return -1. If everything goes well, we return the user object without the password.

For password management, create another file named crypt.js inside the logic/auth folder. Update it as below

Quite self explanatory.

This is pretty much our logic layer. Now, we will build our DB layer.

To store the data, we are going to use DiskDB. DiskDB needs a folder where all the collections will be placed. Create a new folder named database inside the server folder.

Next, create another folder named db inisde the server folder. This is where we write the code to interact with the Database. Inside the db folder, create a file named db.auth.js. And update it as below

Things to notice

Line 6 : Check duplicates before saving the user to the database

Line 13 : Method to fetch a user by username

Line 18 : Method to fecth  a user by Id

Simple right! This is a simple and easy way to layer your code logically. This split up is optional but the code is a lot modular.

Now, we will setup the CRUD operations for the Reminders. Inside the routes folder create a new file named reminder.js. 

Quite a lot of things going on. But most of it is same for all the methods. As soon as the request arrives, validate it. If things are not as expected, send back a 400. Else start processing the request.

One key thing to notice is on line 80. Here we validate the date part of the request. We have designed our app to send a false if the user does not want to schedule a call or SMS in the shdlSMS/shdlCall fields. If they want to schedule a call, this field will be filled with a date time stamp. The only condition is that the date time stamp should be from the future.

To complete this validation, create a new folder named util inside the server folder and create a file named validate.js.

Update validate.js as below

Next, We will write the logic layer for reminders. Create a new folder named reminder inside the logic folder and name it reminder.js. Update it as below

The meat of our app lies here.

Line 2  :We will require the scheduler. This file consist of the logic to schedule tasks. In our case SMSs or Calls.

Line 6 : Returns all the reminders that were created by the provided user id.

Line 10 : Returns one reminder that matches the provided reminder id.

Line 13 : When we create a new reminder, we schedule  a call or SMS depending on the request. Then on 18/21, we schedule the required task.

Line 27 : To cancel a scheduled Job

Line 30 : Delete a reminder along with its schedules.

To complete the scheduling logic, create a new folder named scheduler inside the logic folder. Create a new file named schedule.js inside this folder. Update it as

Things to notice

Line 3 : Logic to issue an SMS using Twilio Node API

Line 4 : Logic to issue a call using Twilio Node API

Line 12/24 : Schedule a new job. The first argument is the name of the job, the second is the time at which the job needs to be triggered and finally the third would be the function to be invoked. This is where we trigger the call/SMS and update that the task is completed.

Line 34 : Will fetch a list of pending jobs and cancel them

To complete our logic layer, we will write the logic to trigger a call and SMS using the Twilio Node API.

Create a new folder named twilio inside the logic folder. Create a new file named client.js. This file will hold the Twilio API and Key, which you can get from your Twilio dashboard.

Update it as below

Create another file named triggerSMS.js inside the twilio folder and update it as below

Things to notice

Line 6 : To the recipients number

Line 7 : Your twilio number

Line 8 : The text to be sent as SMS

Next, the logic to trigger a call. Inside the same folder, create another file name triggerCall.js, update it as below

Line 6 : To whom the call needs to be made

Line 7 : Your Twilio number

Line 8 : The URL, which consist of the TwiML for this call. To customize the app and make it user friendly, we will dispatch a customized message when the call is made. Twilio will call the URL provided here to get a TwiML to be used during the call.

This URL should be a public one. For testing purposes, we are going to expose our server as a static address using ngrok.

You will need to update this URL after starting the server. More on that soon.

We will write the logic for saving the reminders and schedules to DB now. Create a file named db.reminder.js inside the db folder and update it as below.

Standard DB methods.

Next, create another file named db.schedule.js inside the same folder and update it as

Here we save and delete schedules.

Finally to complete our server side code, we will fill in the logic for generating the TwiML. Create a new file named twilio.js inside the routes folder and update it as

This is the endpoint that gets triggered when Twilio makes a call. We dispatch a TwiML based on the input params.

To complete the logic, create a new file named generateTwiml.js inside the logic/twilio folder and update it as

Line 7 : Get the reminder details from DB

Line  15-22 : Build the response

Line 27 : Dispatch it

To complete the server side, we will update the externalized messages. Create a new folder named messages at the root of server folder. Create a new file named messages.js inside it and update it as

That is it! Now you can run

nodemon app .js or  node app.js

from the server folder. To make our app publically accessible, we will start the ngrok server on port 3000. This will spit out a public URL like

Screen Shot 2014-09-28 at 10.24.26 pm

which you would need to update on line 8 server/logic/twilio/triggerCall.js.

Testing the REST API

To test the server, you can use CURL or Postman or any REST client. I will use a chrome extension named Advanced Rest client.

First, we will register a new account for that we will send a request like

Screen Shot 2014-09-28 at 10.29.55 pmAnd you should receive a response like

Sweet. Now let us try login.

Screen Shot 2014-09-28 at 10.31.56 pm

And the response

Let us try and create a new reminder with a new SMS scheduledScreen Shot 2014-09-28 at 10.36.23 pmQuick tip : To get the timestamp of the required time in chrome, run 

copy((new Date(2014, 08, 28, 22, 36)).getTime())

in the console. The arguments are year, month (starting at index 0), date, hours and minutes. Now you can paste the copied datetimestamp.

Your response would look like

And at the scheduled time, you should receive a SMS. You can test out the call too.

In the same fashion you can test out the other REST endpoints too. The data is stored under the database folder if you want to take a peek.

Now, we are going to build a Mobile Hybrid app based on this REST API. You can navigate to that tutorial from here : Ionic, Twilio and Node Scheduler – A Reminder App – Part II [Client]

Thanks for reading! Do comment.

Series NavigationIonic, Twilio and Node Scheduler – A Reminder App – Part II [Client] >>
Tweet about this on TwitterShare on LinkedIn9Share on Google+7Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page
  • jesus israel perales martinez

    Wooww!! , Thanks, I needed an example of node-schedule

  • markbarton

    Will the server lose the scheduling if its stoppped and restarted? I assume so.

    What do you think is best – just load in the active jobs from the database when the server starts up?

    • Arvind Ravulavaru

      Hello markbarton.

      If I am not wrong, even though you restart the server, you can fetch the scheduled jobs using

      This is the same logic used to cancel jobs in the above example.


  • Oron Ben Zvi

    This DiskDB is using only “Sync” methods to write and read from the harddisk, doesn’t it ruins all node performance? making your entire code blocking, instead of non-blocking.

    • Arvind Ravulavaru

      Hello Oron, Yes it does. I have used DiskDB in this example to keep things simple. You can always use MongoDB in place of it. There is already a plan to make DiskDB async.


      • Oron Ben Zvi

        Hey Arvind, thanks for your response. I just noticed that diskdb is your own module. would you like me to pull request, add “Sync” suffix to the sync methods and add async ones?

        • Arvind Ravulavaru

          Hello Oron,

          Sure. pls be my guest. Thanks for coming forward with the contribution.


          • Arvind Ravulavaru

            I am sorry**

            Please leave the existing methods as is and add an async to the new ones. I want diskDB to be backward compatible.


          • Oron Ben Zvi

            Adding Async suffix to methods is the opposite of node convention, so maybe we should think of different names to the async methods if you don’t want this to be a “breaking change” but adding Async suffix is c# not nodejs.

          • Arvind Ravulavaru

            Lol. True that. Why don’t you open an issue on github. Lets hash it out there.

          • Oron Ben Zvi

            Sure buddy, I’ll get back from my vacation next week and we’ll start working on this.

          • Arvind Ravulavaru

            Great. Thanks.