- Install the dependencies.
bundle install-
In app.rb, configure the following variables accordingly:
TWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN,TWILIO_PHONE_NUMBER,TWIML_URL. -
Start the server and check it out at http://localhost:4567.
ruby app.rbbundle installIn app.rb, configure the following variables accordingly: TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_PHONE_NUMBER, TWIML_URL.
Start the server and check it out at http://localhost:4567.
ruby app.rb| require 'sinatra' | |
| require 'data_mapper' | |
| require 'dm-migrations' | |
| require 'twilio-ruby' | |
| require 'json' | |
| # Get these credentials from http://twilio.com/user/account | |
| TWILIO_ACCOUNT_SID = 'my-account-sid' | |
| TWILIO_AUTH_TOKEN = 'my-auth-token' | |
| TWILIO_PHONE_NUMBER = 'my-phone-number' | |
| # Your URL should be accessible through the web. | |
| # If you are testing locally, you can use 'ngrok' to expose it. | |
| # Remember to append the /twiml suffix. | |
| TWIML_URL = 'https://www.example.org/twiml' | |
| DataMapper.setup(:default, 'sqlite::memory:') | |
| class User | |
| include DataMapper::Resource | |
| property :id, Serial | |
| property :phone_number, String, required: true | |
| property :verification_code, String | |
| property :verified, Boolean, default: false | |
| end | |
| DataMapper.finalize | |
| DataMapper.auto_migrate! | |
| get '/' do | |
| send_file 'index.html' | |
| end | |
| post '/call' do | |
| verification_code = rand(100000...999999) | |
| phone_number = params[:phone_number] | |
| User.all.destroy | |
| User.create( | |
| phone_number: phone_number, | |
| verification_code: verification_code, | |
| verified: false | |
| ) | |
| client = Twilio::REST::Client.new TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN | |
| client.account.calls.create( | |
| from: TWILIO_PHONE_NUMBER, | |
| to: phone_number, | |
| url: TWIML_URL | |
| ) | |
| { verification_code: verification_code}.to_json | |
| end | |
| post '/twiml' do | |
| code = params[:Digits] | |
| if code.nil? || code.empty? | |
| Twilio::TwiML::Response.new do |r| | |
| r.Gather numDigits: '6' do |g| | |
| g.Say 'Please enter your verification code.' | |
| end | |
| end | |
| else | |
| phone_number = params[:Called] | |
| user = User.first(phone_number: phone_number, verification_code: code) | |
| if user.nil? | |
| Twilio::TwiML::Response.new do |r| | |
| r.Gather numDigits: '6' do |g| | |
| g.Say 'Verification code incorrect, please try again.' | |
| end | |
| end | |
| else | |
| user.verified = true | |
| user.save() | |
| Twilio::TwiML::Response.new do |r| | |
| r.Say 'Thank you! Your phone number has been verified.' | |
| end | |
| end | |
| end.text | |
| end | |
| post '/status' do | |
| phone_number = params[:phone_number] | |
| user = User.first(phone_number: phone_number, verified: true) | |
| {status: user.nil? ? 'unverified': 'verified'}.to_json | |
| end |
| source 'https://rubygems.org' | |
| gem 'sinatra', '1.4.7' | |
| gem 'data_mapper', '1.2.0' | |
| gem 'dm-sqlite-adapter', '1.2.0' | |
| gem 'twilio-ruby', '4.11.1' |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
| <title>Phone Verification by Twilio</title> | |
| <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |
| <script type="text/javascript"> | |
| $(document).ready(function(){ | |
| $("#enter_number_form").submit(function(e) { | |
| e.preventDefault(); | |
| initiateCall(); | |
| }); | |
| }); | |
| function initiateCall() { | |
| $.post("/call", $("#enter_number_form").serialize(), function(data) { | |
| showCodeForm(data.verification_code); | |
| }, "json"); | |
| checkStatus(); | |
| } | |
| function showCodeForm(code) { | |
| $("#verification_code").text(code); | |
| $("#verify_code").fadeIn(); | |
| $("#enter_number_form").fadeOut(); | |
| } | |
| function checkStatus() { | |
| $.post("/status", $("#enter_number_form").serialize(), function(data) { | |
| updateStatus(data.status); | |
| }, "json"); | |
| } | |
| function updateStatus(current) { | |
| if (current === "unverified") { | |
| $("#status").append("."); | |
| setTimeout(checkStatus, 3000); | |
| } else { | |
| $("#status").text("Verified!"); | |
| } | |
| } | |
| </script> | |
| </head> | |
| <body> | |
| <form id="enter_number_form"> | |
| <p>Enter your phone number:</p> | |
| <p><input type="text" name="phone_number" id="phone_number" /></p> | |
| <p><input type="submit" name="submit" value="Verify" /></p> | |
| </form> | |
| <div id="verify_code" style="display: none;"> | |
| <p>Calling you now.</p> | |
| <p>When prompted, enter the verification code:</p> | |
| <h1 id="verification_code"></h1> | |
| <p><strong id="status">Waiting...</strong></p> | |
| </div> | |
| </body> | |
| </html> |
Generally we should prefer to use the Ruby 1.9 hash syntax.
https://gist.github.com/mosampaio/0771e1322b81600b09f25737c303f4fb/#file-app-rb-L59-L61
r.Gather numDigits: '6' do |g|
g.Say 'Please enter your verification code.'
enddone @acamino
@mosampaio, would you mind removing the trailing slashes from the route's definitions please?
e.g. https://gist.github.com/mosampaio/0771e1322b81600b09f25737c303f4fb/#file-app-rb-L55