How to Build a Voice-Controlled Virtual Assistant (IVR) in PHP Using Laravel and Plivo

A virtual assistant can help your business if you have clients who call your phone number. Interactive voice response (IVR) helps you to automate call reception by routing callers to the most appropriate department or the agent most qualified to meet their needs. Among its many advantages, IVR can provide increased operational efficiency, a stronger brand image, and better customer insights.

A voice-controlled virtual assistant is one step ahead of the legacy Touch-Tone/DTMF controlled one because of the flexibility it allows end users. They can just speak into their phone’s microphone to provide input to control the call.

Building a voice-controlled virtual assistant using Plivo’s automatic speech recognition (ASR) feature in PHP using Laravel is simple. This guide shows you how to set up a voice-controlled IVR phone tree to a Plivo number and manage the call flow when the call reaches the Plivo voice platform. To see how to do this, we’ll build a Laravel application to receive an incoming call and use the GetInput XML element to capture speech input and implement a simple IVR phone system.

Prerequisites

Before you get started, you’ll need:

  • A Plivo account — sign up for one for free if you don’t have one already.
  • A voice-enabled Plivo phone number if you want to receive incoming calls. To search for and buy a number, go to Phone Numbers > Buy Numbers on the Plivo console.
  • Laravel and Plivo PHP packages.
  • ngrok — a utility that exposes your local development server to the internet over secure tunnels.

How it works

Receive Speech Inputs

Create a Laravel application to create a voice-controlled virtual assistant

First, install Laravel if you haven’t done so already. We suggest using Composer to install it. Add a new Laravel project with boilerplate code with the command composer create-project laravel/laravel virtual_assistant --prefer-dist. This will create a receive_calls project directory with the necessary folders and files for development. Then change to the newly created receive_calls directory and install the Plivo PHP package (composer require plivo/plivo-php).

Once you’ve installed Laravel and the Plivo PHP SDK, run php artisan make:controller VirtualassistantController to create a Laravel controller to handle incoming calls on a Plivo number. To handle an incoming call, you need to return an XML document from the URL configured as the answer URL in the application assigned to the Plivo number. The PHP SDK can manage the XML document generation, and you can use the GetInput XML element to capture speech inputs and implement a simple IVR phone system. Use this code:

<?php

namespace App\Http\Controllers;
require '../vendor/autoload.php';
use Plivo\RestClient;
use Plivo\XML\Response;
use Illuminate\Http\Request;

class VirtualassistantController extends Controller
{
  // GetInput XML to handle the incoming call
  public function detectSpeech()
  {
      $welcome_message = "Welcome to the demo app. Say Sales to talk to our Sales representative. Say Support to talk to our Support representative"; //  Welcome message - firstbranch
      $no_input = "Sorry, I didn't catch that. Please hang up and try again later."; // This is the message that Plivo reads when the caller does nothing at all
      $response = new Response();
      $get_input = $response->addGetInput(
                  [
                      'action' => 'https://' . $_SERVER["HTTP_HOST"] . '/representative_speech',
                      'method' => "POST",
                      'interimSpeechResultsCallback' => 'https://' . $_SERVER["HTTP_HOST"] . '/representative_speech',
                      'interimSpeechResultsCallbackMethod' => 'POST',
                      'inputType' => "speech",
                      'redirect' => "true",
                  ]);
      $get_input->addSpeak($welcome_message, ['language'=>"en-US", 'voice'=>"Polly.Salli"]);
      $response->addSpeak($no_input);
      $xml_response = $response->toXML();
      return response($xml_response, 200)->header('Content-Type', 'application/xml');
  }

  // Action URL block for Sales and Support branch
  public function repBranch(Request $request)
  {
      $wrong_input = "Sorry, invalid input."; // This is the message that Plivo reads when the caller inputs a wrong digit.
      $speech = $request->query('Speech');
      $from_number = $request->query('From');
      $response = new Response();
      $params = array(
          'callerId' => $from_number
      );
      if ($speech=="sales") {
          $dial = $response->addDial($params);
          $number = "14156667777";
          $dial->addNumber($number);
      } elseif($speech=="support") {
          $dial = $response->addDial($params);
          $number = "14156667778";
          $dial->addNumber($number);
      } else {
          $response->addSpeak($wrong_input);
      }
      $xml_response = $response->toXML();
      return response($xml_response, 200)->header('Content-Type', 'application/xml');
  }
}

Now add a route for the virtualAssistant function in the VirtualassistantController class. Open the routes/web.php file and add these lines at the end of the file:

Route::match(['get', 'post'], '/detect_speech', 'App\Http\Controllers\VirtualassistantController@detectSpeech');
Route::match(['get', 'post'], '/representative_speech', 'App\Http\Controllers\VirtualassistantController@repBranch');

Note: We need to add the route of the app to the “except” array to disable cross-site request forgery (CSRF) verification in the app/Http/Middleware/VerifyCsrfToken.php file.

<?php

namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
   /**
    * The URIs that should be excluded from CSRF verification.
    *
    * @var array
    */
   protected $except = [
       '/detect_speech',
       '/representative_speech'
   ];
}

Test the code locally

Now the VirtualassistantController is ready to handle incoming calls to your Plivo number using Laravel and the Plivo PHP SDK. To run the code on the Laravel server, use the command

$ php artisan serve

You should see your basic server application in action on http://127.0.0.1:8000/detect_speech.

Expose the local server to the internet using ngrok

Once you see the application working locally, the next step is to connect the application to the internet to return the XML document to process the incoming call. For that, we recommend using ngrok, which exposes local servers behind NATs and firewalls to the public internet over secure tunnels.

Install it and run ngrok on the command line, specifying the port that hosts the application on which you want to receive calls (8000 in this case, as our local Laravel application is running there):

$ ./ngrok http 8000

Ngrok will display a forwarding link that you can use as a webhook to access your local server over the public network.

Ngrok CLI

Test the link by opening the ngrok URL(https://02a9fe62aabd.ngrok.io/detect_speech) in a browser or HTTPie to check the XML response from the ngrok URL.

XML document with GetDigits XML element

Connect the Laravel application to a Plivo number

The final step is to configure the application as a Plivo voice application and assign it to a Plivo number on which you want to activate the voice-controlled virtual assistant.

Go to the Plivo console and navigate to Voice > Applications > XML, then click on the Add New Application button in the upper right.

Provide a friendly name for the application — we used “App-Virtual-Assistant” — and configure the ngrok URL https://02a9fe62aabd.ngrok.io/detect_speech as the Answer URL. Select the HTTP verb as POST, then click Create Application.

Create Plivo App for voice-controlled IVR Laravel app

Now go to Phone Numbers > Your Numbers and click on the number to which you want to assign the application. From the Plivo Application drop-down, choose the voice application you just created. Finally, click Update Number.

Assign Virtual-Assistant Plivo App

Test the application

Make a phone call to the Plivo number you selected. You should see that the VirtualAssistant Laravel application automatically routes the call to the Sales and Support departments based on the speech inputs received on the call.

And that’s how simple it is to set up a voice-controlled virtual assistant on a Plivo number and handle it using XML documents using Plivo’s PHP SDK and a Laravel application. You can implement other use cases on the Plivo Voice platform, such as phone system IVR, call forwarding, and number masking, as your business requires.

Haven’t tried Plivo yet? Getting started is easy and only takes five minutes. Sign up today.

comments powered by Disqus