Skip to content

Instantly share code, notes, and snippets.

@a7me63azzab
Forked from mosampaio/README.md
Created May 11, 2018 12:06
Show Gist options
  • Save a7me63azzab/aa66fdeb7958dfee69f4c0d28eda4958 to your computer and use it in GitHub Desktop.
Save a7me63azzab/aa66fdeb7958dfee69f4c0d28eda4958 to your computer and use it in GitHub Desktop.
Simple Phone Verification with Twilio, Node.js, Mongoose, and jQuery Raw

Please make sure you have set the following environment variables:

(This URL should be accessible thru the web. You can use Ngrok to help you if you are testing locally.)

export TWIML_SERVER_URL=https://www.example.org/twiml/

(This information can be found in your Twilio dashboard)

export TWILIO_ACCOUNT_SID=your-account-sid
export TWILIO_AUTH_TOKEN=your-auth-token
export TWILIO_PHONE_NUMBER=your-phone-number

How to run?

npm install
npm start
var express = require('express')
, path = require('path')
, cookieParser = require('cookie-parser')
, bodyParser = require('body-parser')
, app = express()
, mongoose = require('mongoose')
, Number = require('./number')
, twilio = require('twilio')
, twilioClient = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN)
, port = 3000;
app.set('views', path.join(__dirname));
app.set('view engine', 'pug');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
// routes
app.get('/', (req, res) => res.render('index'));
app.get('/static/main.js', (req, res) => res.sendFile(__dirname + '/main.js'));
app.get('/static/style.css', (req, res) => res.sendFile(__dirname + '/style.css'));
app.post('/call', (req, res) => {
var verificationCode = rand(100000, 999999);
var phoneNumber = req.body.phoneNumber;
Number.remove({'phoneNumber': phoneNumber}, (err) => {
Number.create({'phoneNumber': phoneNumber, 'verificationCode': verificationCode}, (err, number) => {
var params = {
to: req.body.phoneNumber,
from: process.env.TWILIO_PHONE_NUMBER, // Your twilio phone number
url: process.env.TWIML_SERVER_URL // full URL of /twiml route on your server
};
twilioClient.makeCall(params, (err, message) => {
if (err) {
console.log(err);
res.status(500).send(err);
} else {
res.send({'verificationCode': verificationCode});
}
});
});
});
});
app.post('/status', (req, res) => {
Number.findOne({'phoneNumber': req.body.phoneNumber, verified: true}, (err, number) => {
res.send({status: (number) ? 'verified' : 'unverified'});
});
});
app.post('/twiml', (req, res) => {
res.type('text/xml');
var verificationCode = req.body['Digits'];
var phoneNumber = req.body['Called'];
if (!verificationCode) {
res.send(new twilio.TwimlResponse().gather({numDigits: 6}, function() {
this.say('Please enter your verification code.');
}).toString());
} else {
Number.findOne({'phoneNumber': phoneNumber, 'verificationCode': verificationCode}, (err, number) => {
if (!number) {
res.send(new twilio.TwimlResponse().gather({numDigits: 6}, function() {
this.say('Verification code incorrect, please try again.');
}).toString());
} else {
number.verified = true;
number.save((err, number) => {
res.send(new twilio.TwimlResponse()
.say('Thank you! Your phone number has been verified.').toString());
});
}
});
}
});
var rand = function(low, high) {
return Math.floor(Math.random() * (high - low) + low);
};
app.listen(port, function () {
console.log('Listening on port ' + port);
});
mongoose.connect('mongodb://localhost/twilio-phone-verification');
doctype html
html
head
meta(http-equiv='Content-Type', content='text/html; charset=utf-8')
title Phone Verification by Twilio
script(type='text/javascript', src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js')
script(type='text/javascript', src='/static/main.js')
link(rel='stylesheet', href='/static/style.css')
body
form(id='enter_number')
p Enter your phone number:
p
input(type='text', name='phone_number', id='phone_number')
p
input(type='submit', name='submit', value='Verify')
div(id='verify_code')
p Calling you now.
p When prompted, enter the verification code:
h1(id='verification_code')
p
strong(id='status') Waiting...
$(document).ready(function(){
$("#enter_number").submit(function(e) {
e.preventDefault();
initiateCall();
});
});
function initiateCall() {
$.post("/call", { phoneNumber : $("#phone_number").val() },
function(data) { showCodeForm(data.verificationCode); }, "json");
checkStatus();
}
function showCodeForm(code) {
$("#verification_code").text(code);
$("#verify_code").fadeIn();
$("#enter_number").fadeOut();
}
function checkStatus() {
$.post("/status", { phoneNumber : $("#phone_number").val() },
function(data) { updateStatus(data.status); }, "json");
}
function updateStatus(current) {
if (current === "unverified") {
$("#status").append(".");
setTimeout(checkStatus, 3000);
}
else {
success();
}
}
function success() {
$("#status").text("Verified!");
}
'use strict';
var mongoose = require('mongoose');
var schema = new mongoose.Schema({
phoneNumber: { type : String , unique : true, required : true, dropDups: true },
verificationCode: Number,
verified: Boolean
});
module.exports = mongoose.model('numbers', schema);
{
"name": "simple-phone-verification-node",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"body-parser": "~1.13.2",
"cookie-parser": "~1.3.5",
"express": "~4.13.1",
"mongoose": "^4.5.9",
"pug": "^2.0.0-beta5",
"twilio": "^2.9.2"
}
}
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
#verify_code {
display: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment