2020-10-04

Twilio API with node.js for phone verification

Twilio is a communication service provider that provides, audio, text, video and other API services for applications. Phone number verification with SMS is a very common tasks for many application especially in signup process and also remote login security verification.

Phone number verificaiton using Twilio SMS API and node.js

Easiio provides cloud base phone system, call center, and website chat support. The system automatic response such as IVR (Interactive Voice Response) and ITR (Interactive Text Response) can be configured to call to their party API such as HTTP API provided by node.js and JavaScript.

In this example, I will show how easy it is to create a ITR (chatbot) to collect user phone number, send a HTTP API call to node.js API written in JavaScript to generate the verification code and call Twilio API to send the SMS to website visitor's cellphone. By doing so, it completes the verification of the user cellphone number and can be used for website signup, subscription and other applications. The node.js API for SMS verification code can be used standalone. You are welcome to use it for your own applications.

Step 1. Write node.js API for Twilio API

There are two parts in the twilio node.js API. First part, it is the generation of the random 6 digit verification code and store it in redis storage.

var number = Math.floor(Math.random() * 899999 + 100000);
...
redisClient.set(formData.phone, number);
redisClient.expire(formData.phone, 600); // setting expiry for 10 minutes.

Second part, it send the SMS message by Twilio API.

       client.messages
          .create({
             body: 'Your Easiio verification code: ' + number,
             from: '+15614492296',
             to: formData.phone
           })
          .then(message => console.log(message.sid));

Here is the code snippet to send SMS. Please make sure you install Redis on node.js using "npm install redis" command, and install twilio API by "npm install twilio".

else if (request.url === "/send_verification_code_itr") {
      var requestBody = '';
      request.on('data', function(data) {
        requestBody += data;
        if(requestBody.length > 1e7) {
          response.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
          response.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
        }
      });
      request.on('end', function() {
        console.log("post end", requestBody);
        var formData = JSON.parse( requestBody );
        var number = Math.floor(Math.random() * 899999 + 100000);
        console.log("send sms twilio phone: ", formData.phone);
        const client = require('twilio')(accountSid, authToken);
        redisClient.set(formData.phone,number);
        redisClient.expire(formData.phone,600); // setting expiry for 10 minutes.
        // create and send the client message
        client.messages
          .create({
             body: 'Your Easiio verification code: ' + number,
             from: '+15614492296',
             to: formData.phone
           })
          .then(message => console.log(message.sid));
        response.write('[ { "id": 1, "action": "play", "text": "The varification code send via sms: ' + number + '" }]');
        response.end('');
      });
    }

Start the node.js by running command "node twilio_sms.js". You can then test the API by the following command line using curl. Make sure to change localhost to your host address.

curl -H "Content-Type:application/json" -X POST -d '{"name":"John Doo","phone":"9254449999"}' http://localhost:1337/send_verification_code_itr

Once the sending verification complete. There is another API for verification of the code. By receiving the phone number and verification code by HTTP API, this part can use phone number to retrieve the code from the redis and compare the value to verify. It returns success or failure depends on the outcome. It can be tested using this command line curl.

else if (request.url === "/check_varification_code") {
      var requestBody = '';
      request.on('data', function(data) {
        requestBody += data;
        if(requestBody.length > 1e7) {
          response.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
          response.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
        }
      });
      request.on('end', function() {
        console.log("post end", requestBody);
        var formData = JSON.parse( requestBody );

        console.log("post end code: ", formData.code, " phone: ", formData.phone);

        var code = redisClient.get(formData.phone,function(err,reply) {

          if(err) {
            console.log ("Error in redis.");
            response.write('[ { "id": 1, "action": "play", "text": "Error in redis.' + queryObject.code + '" }]');
            response.end('');
          }
          if(reply === null) {
            console.log ("Invalid email address.");
            response.write('[ { "id": 1, "action": "play", "text": "Invalid email address: ' + email + '" }]');
            response.end('');
            return 1;
          }
          return_code = reply;
          console.log ("email check return_code:." + reply);
          if (return_code == formData.code) {
            console.log("verification successful. ", formData.phone, " ", return_code);
            response.writeHead(200, {'Content-Type': 'text/html'});
            response.write('<!doctype html><html><head><title>email verification successful</title></head><body>email verification successful</body></html>');
            response.end();
          } else {
            response.writeHead(200, {'Content-Type': 'text/html'});
            response.write('<!doctype html><html><head><title>email verification failed</title></head><body>email verification failed. Please try again</body></html>');
            response.end();
          } 
        });
      });
    }
curl -H "Content-Type:application/json" -X POST -d '{"code":"661871","phone":"9254449999"}' http://localhost:1337/check_varification_code

Complete source code is available at GitHub twilio_sms.js.

Step 2. Configure Easiio ITR (chatbot) for API call

If you do not have Easiio account, signup for a free one. Login to Easiio account backend. For more instruction, about Easiio setup, please read this Easiio Web Chat Plugin Guide.

Open "Advanced configuration" next "Visual IVR". Create a new IRT or use existing one. In my case, I will use our demo/bakery ITR for testing. I created a new entry in the first level menu called "Verify phone number". Configured the form to be as shown in following picture. Pay attention to the form name, which is created using "Advanced Configuration" next "IVR form". Setting the url to the node.js API for sending verification code in the previous section. Then, add the call to the form of verification once Twilio send the SMS verification code.

Visual ITR configuration for Verify phone number
ITR configuration for phone number collection form

The second form use Phone Verification

Form to confirmed the verification code.

Step 3. Verify the Twilio API and ITR

Verify the ITR/Chatbot call to the Twilio SMS node.js API by open the ITR created. In my case, I open the https://easiio.com/demo. Once the chat window popup, I select "Verify phone number" menu. Enter name and phone, click submit to receive my SMS by Twilio SMS service. Then, I enter the phone number again and the verification code by phone, then click to complete the verification.

ITR chatbot using Easiio webchat plugin

Conclusion:

This blog shows how to create a phone verification API using Twilio SMS API on node.js. The Twilio API is very easy to use. This sample API can be used standalone without Easiio. Keep in mind you will need more error handling code to make the code production friendly. Easiio provides a very powerful website chatbot (ITR) live chat plugin. It has many powerful features such as the form feature shown in this example. You can signup for free and use it with your website.

More reading:

https://www.easiio.com/use-node-js-and-cloudmailin-api-to-send-emails-from-chat