Thursday, 13 June, 2019 UTC


Summary

Introduction
There may be times in building your app that you will need to send an SMS to the phone number of a user. Wouldn't it be awesome if you could confirm that the number supplied is actually a cellphone? Or maybe you want to only send SMS to verified users. With Twilio's Authy API, these use cases are easy to implement. This tutorial is aimed at helping developers to build a phone number validator to verify users phone numbers in any PHP application and check if a number is a cellphone or landline before sending an SMS.

Technical Requirements

For this tutorial, it is expected that you have basic knowledge of the following:
  • Composer
  • Are familiar with Laravel
  • Understand PHP 5+
  • Have a Twilio account
NOTE: Don’t forget to craft a Laravel project for this purpose. Here’s a link to a guide on the installation process for installing Laravel.
Phone Number Verification
First, we need to install the Twilio PHP SDK which makes available the functions we would need to carry out the task of verifying a phone number. In the root folder of your Laravel project, run the following command.
$ composer require twilio/sdk authy/php 
After successfully installing the Twilio SDK, we need to configure the client application to be able to communicate with our Twilio account. To do this, please add the following to your .env file. This should be after you have created an Authy application in your Twilio Console:
AUTHY_API_KEY=XXXXXXXXXXXXXXXXXXXX TWILIO_ACCOUNT_SID=ACXXXXXXXXXXXXXXXXXXX TWILIO_AUTH_TOKEN=XXXXXXXXXXXXXXXXXXXXX TWILIO_PHONE=APXXXXXXXXXXXXXXXXXXX 
NOTE: Your "AUTHY_API_KEY” can be retrieved from the Settings tab of the Authy application you just created and “TWILIO_PHONE” is your Twilio Phone Number.
Now add the code below in config/app.php to access the Twilio configuration variables globally.
'twilio' => [  'AUTHY_API_KEY' => env('AUTHY_API_KEY'),  'TWILIO_ACCOUNT_SID' => env('TWILIO_ACCOUNT_SID'),  'TWILIO_AUTH_TOKEN' => env('TWILIO_AUTH_TOKEN'),  'TWILIO_PHONE' => env('TWILIO_PHONE'), ], 
Now that we are done with the basic installation setup, we will begin building the controller methods to process our Twilio requests. This can be achieved by using the following command and should be done inside your project directory:
$ php artisan make:controller TwilioController 
Open the newly created controller file located in app/Http/Controllers/TwilioController.php and import the Twilio AuthyApi class which will be used for phone number verification and checking verification codes.
<?php  namespace App\Http\Controllers;  use Illuminate\Http\Request; use Twilio\Rest\Client; use Authy\AuthyApi; 
Next, we will initialize the constructor, define the needed variables, and make them accessible within the controller. Add the following code:
<?php  class TwilioController extends Controller {  protected $authy;  protected $sid;  protected $authToken;  protected $twilioFrom;   public function __construct() {  // Initialize the Authy API and the Twilio Client  $this->authy = new AuthyApi(config('app.twilio')['AUTHY_API_KEY']);  // Twilio credentials  $this->sid = config('app.twilio')['TWILIO_ACCOUNT_SID'];  $this->authToken = config('app.twilio')['TWILIO_AUTH_TOKEN'];  $this->twilioFrom = config('app.twilio')['TWILIO_PHONE'];  }  } 
Now create the controller method to verify the user’s phone number. Upon validation, it will send out a verification code to the user which will be used in the next step. Next, create another method to verify the verification code that was sent to the user.
<?php  public function verifyPhone(Request $request) {  // Validate form input  $this->validate($request, [  'country_code' => 'required|string|max:3',  'phone' => 'required|string|max:10',  'via' => 'required|string'  ]);   //Call the "phoneVerification" method from the Authy API and pass the phone number, country code and verification channel(whether sms or call) as parameters to this method.  $response = $this->authy->phoneVerificationStart($request->phone, $request->country_code, $request->via);   if ($response->ok()) {  print $response->message();  } else {  print $response->message();  } }  public function verifyCode(Request $request) {  // Call the method responsible for checking the verification code sent.  $response = $this->authy->phoneVerificationCheck($request->phone, $request->country_code, $request->code);  if($response->ok()) {  print $response->message();  } else {  print $response->message();  } } 
Open up web.php located in the routes folder and paste in the following code for the phone verification code verification methods:
Route::view('/verify', 'phone-verification'); Route::post('/verify', '[email protected]')->name('verify-phone'); Route::post('/verify-code', '[email protected]')->name('verify-code'); 
Next, create a file in the resources/views directory called phone-verification.blade.php which will be used to receive user input. Add the following to the file you just created.
<html>  <head>  <title>Twilio + Laravel</title>   <!-- Bootstrap -->  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">   <style>  form {  background-color: #fff;  width: 600px;  float: center;  margin: auto;  margin-top: 100px;  }  </style>  </head>  <body>  @if ($errors->any())  <div class="alert alert-danger">  <ul>  @foreach ($errors->all() as $error)  <li>{{ $error }}</li>  @endforeach  </ul>  </div>  @endif  <form method="post" action="{{ route('verify-phone') }}">  {{csrf_field()}}  <h4>Phone Verification</h4>  <div class="row">  <div class="form-group col-md-3">  <label>Country code</label>  <input type="text" class="form-control" name="country_code" aria-describedby="emailHelp" placeholder="123">  <small id="emailHelp" class="form-text text-muted">Country dial code for phone number.</small>  </div>  <div class="form-group col-md-6">  <label for="phoneNumber">Phone Number</label>  <input type="text" class="form-control" name="phone" id="phoneNumber" aria-describedby="phoneNumberHelp" placeholder="1234567890">  <small id="emailHelp" class="form-text text-muted">Phone number to be verified.</small>  </div>  <div class="form-group col-md-3">  <label for="via">via</label>  <select class="form-control" name="via" id="exampleFormControlSelect1">  <option value="sms">SMS</option>  <option value="call">Call</option>  </select>  </div>  </div>  <button type="submit" class="btn btn-primary">Submit</button>  </form>   <form method="post" action="{{ route('verify-code') }}">  {{csrf_field()}}  <h4>Code Verification</h4>  <div class="row">  <div class="form-group col-md-3">  <label>Country code</label>  <input type="text" class="form-control" name="country_code" aria-describedby="codeHelp" placeholder="123">  <small id="codeHelp" class="form-text text-muted">Country dial code for phone number.</small>  </div>  <div class="form-group col-md-6">  <label for="phoneNumber">Phone Number</label>  <input type="text" class="form-control" name="phone" id="phoneNumber" aria-describedby="phoneNumberHelp" placeholder="1234567890">  <small id="phoneNumberHelp" class="form-text text-muted">Phone number to be verified.</small>  </div>  <div class="form-group col-md-3">  <label for="code">Code</label>  <input type="text" class="form-control" name="code" placeholder="1234">  </div>  </div>  <button type="submit" class="btn btn-primary">Submit</button>  </form>   <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>  </body> </html> 
Sending the SMS
We have created and defined the necessary variables we need for this app to verify our phone number. We will now proceed to create the logic to send our SMS.

Create a file in the resources/views directory called send-sms.blade.php and add the following code to it.
<html>  <head>  <title>Twilio + Laravel</title>   <!-- Bootstrap -->  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">   <style>  form {  background-color: #fff;  width: 600px;  float: center;  margin: auto;  margin-top: 100px;  }  </style>  </head>  <body>  @if ($errors->any())  <div class="alert alert-danger">  <ul>  @foreach ($errors->all() as $error)  <li>{{ $error }}</li>  @endforeach  </ul>  </div>  @endif   <form method="post" action="{{ route('send-sms') }}">  {{csrf_field()}}  <h4>Send SMS</h4>  <div class="row">  <div class="form-group col-6">  <label for="phoneNumber">Phone Number</label>  <input type="text" class="form-control" name="phone" id="phoneNumber" aria-describedby="phoneNumberHelp" placeholder="+1231234567890">  <small id="phoneNumberHelp" class="form-text text-muted">Phone number to send SMS.</small>  </div>  </div>  <div class="row">  <div class="form-group col-md-12">  <label>Text Message</label>  <input type="text" name="message" class="form-control" id="text" aria-describedby="phoneNumberHelp" placeholder="Message here...">  </div>  </div>  <button type="submit" class="btn btn-primary">Submit</button>  </form>   <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>  </body> </html> 
Route:
Route::view('/send-sms', 'send-sms'); Route::post('/send', '[email protected]')->name('send-sms'); 
TwilioController:
<?php  public function sendSMS(Request $request) {  // Validate User input from form.  $this->validate($request, [  'phone' => 'required|string',  'message' => 'required|string'  ]);   // Create REST API Client  $client = new Client($this->sid, $this->authToken);   try {  $sms = $client->messages->create($request->phone,  [  'from' => $this->twilioFrom,  'body' => $request->message  ]  );   if($sms) {  return redirect()->back()->with('success', 'SMS sent successfully');  } else {  return redirect()->back()->with('error', 'SMS failed!');  }  } catch(Exception $e) {  echo 'Error: ' . $e->getMessage();  }  } 
Here’s the complete TwilioController code.
<?php  namespace App\Http\Controllers;  use Illuminate\Http\Request; use Twilio\Rest\Client; use Authy\AuthyApi;  class TwilioController extends Controller {  protected $authy;  protected $sid;  protected $authToken;  protected $twilioFrom;   public function __construct() {  // Initialize the Authy API and the Twilio Client  $this->authy = new AuthyApi(config('app.twilio')['AUTHY_API_KEY']);  // Twilio credentials  $this->sid = config('app.twilio')['TWILIO_ACCOUNT_SID'];  $this->authToken = config('app.twilio')['TWILIO_AUTH_TOKEN'];  $this->twilioFrom = config('app.twilio')['TWILIO_PHONE'];  }   public function verifyPhone(Request $request) {  // Validate form input  $this->validate($request, [  'country_code' => 'required|string|max:3',  'phone' => 'required|string|max:10',  'via' => 'required|string'  ]);   //Call the “phoneVerification” method from the Authy API and pass the phone number, country code and verification channel(whether sms or call) as parameters to this method.  $response = $this->authy->phoneVerificationStart($request->phone, $request->country_code, $request->via);   if ($response->ok()) {  print $response->message();  } else {  print $response->message();  }  }   public function verifyCode(Request $request) {  // Call the method responsible for checking the verification code sent.  $response = $this->authy->phoneVerificationCheck($request->phone, $request->country_code, $request->code);  if($response->ok()) {  print $response->message();  } else {  print $response->message();  }  }   public function sendSMS(Request $request) {  $this->validate($request, [  'phone' => 'required|string',  'message' => 'required|string'  ]);  $phone = $this->authy->phoneInfo( $request->phone, '1' );     if ( 'landline' == $phone->bodyvar('type') ) {   return redirect()->back()->withErrors( [ 'This is a landline' ] );   }    // Create REST API Client   $client = new Client($this->sid, $this->authToken);   try {  $sms = $client->messages->create($request->phone,  [  'from' => $this->twilioFrom,  'body' => $request->message  ]  );   if($sms) {  return redirect()->back()->with('success', 'SMS sent successfully');  } else {  return redirect()->back()->with('error', 'SMS failed!');  }  } catch(Exception $e) {  echo 'Error: ' . $e->getMessage();  }  } } 
Testing
With all this done, you will want to see how this works. All you need to do is start your development server using the command below in your terminal(Unix)/Command Prompt(Windows).
$ php artisan serve 
Now, using your preferred browser, visit http://localhost:8000/verify (for phone verification) or http://localhost:8000/send-sms (for sending SMS). Fill in the forms and submit. On /send-sms, input a landline number to test Authy’s phone information API. On submit, it should return an error.
Conclusion
Following this, you can see how easy it is to verify phone numbers and also send out SMS using the Twilio service. Now you can go ahead and build awesome communication-based projects.
Ugendu Martins Ositadinma
Email: [email protected]
Twitter: https://twitter.com/ohssie_
Github: https://github.com/ohssie