Build a Post-call Transcription System in Laravel with Twilio

December 17, 2024
Written by
Lucky Opuama
Contributor
Opinions expressed by Twilio contributors are their own
Reviewed by

Build a Post-call Transcription System in Laravel with Twilio

This tutorial will show you how to develop a post-call transcription system in Laravel using Twilio's powerful Programmable Voice API. By the end of this tutorial, you will have a fully operational system for recording and transcribing phone calls, with the transcriptions safely stored in a database.

What is a post-call transcription system?

A post-call transcription system automatically converts audio from phone calls to text after the call has ended. The system is widely used in many industries, including customer service, sales, healthcare, and law, to generate written records of conversations for future reference, analysis, compliance, and training.

Benefits of a post-call transcription system

Using post-call transcriptions eliminates the need to manually jot down important information, saving time and ensuring easy access to details without worrying about misplacing them.

Here are several other key benefits of using a post-call transcription system:

  • Enhanced Focus During Conversations: By eliminating the need to take notes manually, individuals can fully engage in the conversation, leading to more meaningful interactions with better understanding.
  • Accuracy and Reliability: Transcriptions provide a precise conversation record, reducing the risk of errors caused by omission or misinterpretation of information. This ensures that all details are captured accurately.
  • Inclusivity and Accessibility: Transcribing conversations makes them accessible to individuals who are deaf or hard of hearing, promoting inclusivity and adhering to accessibility standards.
  • Data-Driven Decision Making: With a complete and accurate record of conversations, you can make informed decisions based on actual data, rather than relying on assumptions or incomplete information.
  • Legal and Compliance Support: Maintaining detailed records of conversations can be crucial in legal or judicial processes, providing verifiable documentation that may be required for compliance or dispute resolution.

Prerequisites

  • Composer installed globally
  • PHP 8.3 or higher with the PDO extension installed and enabled
  • A free or paid Twilio account. Create a free account if you are new to Twilio
  • Ngrok - a utility that connects your local development server to the internet via secure tunnels.
  • Prior experience working with databases
  • Your preferred text editor or IDE

Create a new Laravel project

Let’s begin by setting up a new Laravel project. Open your terminal and navigate to the directory where you want to install the Laravel project.

Then, run the following command to create the project using Composer, and to change into the newly created project directory.

composer create-project laravel/laravel post-call-transcription
cd post-call-transcription

Now that you’ve successfully created a new Laravel project, the next step is to create the database.

Create the database

Running the database migration allows you to define and modify your database schema in a structured and organized way. It allows you to easily manage database changes, track modifications over time, and ensure consistency across different environments.

To define the database schema, run the following command:

php artisan make:migration create_transcriptions_table --create=transcriptions

After running this command, a new migration file will be created in the database/migrations directory. Navigate to this directory, locate the most recent file ending with _create_transcriptions_table.php, and replace its content with the following code.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('transcriptions', function (Blueprint $table) {
            $table->id();
            $table->string('call_sid');
            $table->string('phone_number');
            $table->text('transcription_text');
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('transcriptions');
    }
};

The code above allows you to define and manage the database tables in a consistent, version-controlled, and automated way. The database table contains the following fields:

  • id(): This is a unique field used to identify each entry in the database table, ensuring no two records have the same id.
  • call_sid: This is a string field that stores the unique identification for each call.
  • phone_number: This is a string field that stores the caller's phone number.
  • transcription_text: This is a text field that stores the call's transcription.
  • timestamps(): This function uses the autogenerated created_at and updated_at columns to store the time the call was received and last updated.

Next, run the command below to run the database migrations which you just created.

php artisan migrate

Now, let’s create the transcription model. The model represents the data structure and interacts with the database, allowing you to manage your data in an object-oriented way. Each model maps to a specific database table and facilitates various database operations. This model is an essential component of the post-call transcription service, enabling the application to store, manage, and retrieve transcriptions of recorded calls.

It also supports mass assignment, allowing you to efficiently create new transcription records by passing an array of attributes. This feature is useful when handling webhook data from Twilio, where multiple fields need to be stored simultaneously.

To create the transcription model, run the command below:

php artisan make:model Transcription

Next, navigate to the app/Models directory, open the Transcription.php file, and replace its contents with the following code:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Transcription extends Model
{
    use HasFactory;

    protected $fillable = [
        'call_sid',
        'phone_number',
        'transcription_text',
    ];
}

The Transcription class is an Eloquent model that represents transcription records in the database. It includes the following attributes:

  • call_sid: This attribute stores the unique identifier for the call, which is typically provided by Twilio when the call is initiated.
  • phone_number: This attribute contains the caller's phone number. It helps identify who made the call and is useful for logging and reference purposes.
  • transcription_text: This attribute contains the text of the transcription, which is the result of converting the recorded call's audio into written form.

Install Twilio's PHP Helper Library

Now, install Twilio's PHP Helper Library, which simplifies integrating Twilio's Programmable Voice API with your application, by running the following command:

composer require twilio/sdk

Retrieve your Twilio credentials

Now that you have successfully installed Twilio's PHP Helper Library, copy and paste the following at the end of .env, located in the project's top-level directory.

TWILIO_SID=<<your_twilio_sid>>
TWILIO_AUTH_TOKEN=<<your_twilio_auth_token>>
TWILIO_PHONE_NUMBER=<<your_twilio_phone_number>>

These three environment variables will store the Twilio-specific details your application needs: your Account SID, Auth Token, and Twilio phone number.

Screenshot of Twilio account info showing Account SID, Auth Token, and trial phone number.

Now, log in to your Twilio Console dashboard to retrieve the details from your Twilio account. Copy your Account SID, Auth Token, and Twilio phone number, which you can find in the Account Info panel, into .env, replacing the respective placeholders.

Create the Twilio Service Provider

The Service Provider is the central hub for binding classes and configurations to Laravel's service container. It not only streamlines service registration and configuration, but also assures that they are available throughout your application, increasing modularity and maintainability.

Creating a dedicated Twilio Service Provider encapsulates the Twilio client's setup and initialization in a single, controllable area. To create the Twilio service provider, run the following command:

php artisan make:provider TwilioServiceProvider

Next, navigate to the app/Providers directory, open the TwilioServiceProvider.php file, and replace its contents with the following code:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Twilio\Rest\Client;

class TwilioServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register()
    {
        $this->app->singleton(Client::class, function ($app) {
            return new Client(
                config('services.twilio.sid'), 
                config('services.twilio.token')
            );
        });
    }

    /**
     * Bootstrap services.
     */
    public function boot()
    {
        //
    }
}

The code above configures and registers the Twilio client within the service container, making it available throughout the application.

Next, navigate to the config directory, open the services.php file, and add the following configurations:a

'twilio' => [
    'sid' => env('TWILIO_SID'),
    'token' => env('TWILIO_AUTH_TOKEN'),
    'phone' => env('TWILIO_PHONE_NUMBER'),
],

This code simplifies configuring your Twilio credentials and details across different environments, and helps keep sensitive data out of your source code, enhancing the security of your application.

Create a call controller

Now, we’ll create a controller to manage incoming calls and initiate call recording. To get started, generate a new controller by running the following command:

php artisan make:controller CallController

Next, navigate to the app/Http/Controllers directory, open the CallController.php file, and replace its existing contents with the following code:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Twilio\Rest\Client;
use Twilio\TwiML\VoiceResponse;
use App\Models\Transcription;

class CallController extends Controller
{
    protected $twilioClient;

    public function __construct(Client $twilioClient)
    {
        $this->twilioClient = $twilioClient;
    }

    public function handleIncomingCall(Request $request)
    {
        $response = new VoiceResponse();
        $response->say('Please leave a message after the beep.');
        $response->record([
            'transcribe' => true,
            'transcribeCallback' => route('transcription.callback')
        ]);
        $response->hangup();
        return response($response, 200)
            ->header('Content-Type', 'text/xml');
    }

    public function transcriptionCallback(Request $request)
    {
        $transcriptionText = $request->input('TranscriptionText');
        $recordingUrl = $request->input('RecordingUrl');
        $callSid = $request->input('CallSid');
        $phoneNumber = $request->input('From');
        Transcription::create([
            'call_sid' => $callSid,
            'phone_number' => $phoneNumber,
            'transcription_text' => $transcriptionText,
        ]);
        return response('OK', 200);
    }
}

The CallController handles responses to incoming calls, processing call transcriptions. Below is an overview of its key public methods:

  • The __construct()method leverages Laravel's dependency injection to automatically inject an instance of the Twilio client (Client), ensuring that the controller remains flexible and testable by centralizing the creation and management of the Twilio client.
  • The handleIncomingCall() method generates a TwiML response to guide the call flow, including recording and transcribing the call.
  • The transcriptionCallback() method processes the transcription sent by Twilio and stores it in the database.

Define the required routes

To guarantee that your application handles user requests efficiently and produces accurate results, you must establish the necessary routes. Begin by going to your routes directory, open the web.php file, and add the following code at the end of the file:

Route::get('/incoming-call', [App\Http\Controllers\CallController::class, 'handleIncomingCall']);
Route::get('/transcription-callback', [App\Http\Controllers\CallController::class, 'transcriptionCallback'])->name('transcription.callback');

Configure the Twilio webhook

When a call is completed and a transcription is generated, Twilio sends an HTTP request to the configured webhook URL for your post-call transcription system. This request includes important data, such as the transcription text, the phone number, and the unique identifier for the call. The application captures this data through the webhook, processes it, and then saves the transcription and recording information to your database. For more details, feel free to explore Twilio documentation.

To configure your Twilio webhook, first, start your application's local development server by running the following command:

php artisan serve

You can access the application by opening your browser to http://127.0.0.1:8000. This will launch the application's default page, as shown in the screenshot below.

Laravel homepage features documentation, tutorials, news, and ecosystem resources.

Then, start ngrok listening on port 8000 by running the following command in a new terminal session or tab:

ngrok http 8000

This command will generate a forwarding URL, which you can see in the terminal screenshot below.

Screenshot of ngrok console displaying session status, plan details, and a public URL for tunneling.

Now, copy the generated Forwarding URL. Then, back in your Twilio console, navigate to Phone Numbers > Manage > Active Numbers. There, click on your Twilio number, then select the Configure tab.

Scroll down to the Voice Configuration section and make the following adjustments:

  • Configure With: Select Webhooks, TwiML Bins, Functions, Studio, or Proxy
  • A Call Comes In: Choose Webhook
  • In the URL field, paste your temporary Ngrok URL with /incoming-call appended to the end
  • Change the HTTP method to HTTP GET
  • Primary Handler Fails: Choose Webhook
  • In the URL field, paste your temporary Ngrok URL with /transcription-callback appended to the end
  • Change the HTTP method to HTTP GET

The image below illustrates this concept clearly.

Screenshot of the Voice Configuration settings page showing routing and URL configurations for a call.

These settings ensure that incoming calls and transcription callbacks are correctly routed to your application through the temporary Ngrok tunnel. Now scroll down and click on Save configuration to apply the changes.

Testing the application

You can now conduct a thorough test of your application. Call your Twilio number. You should hear the prompt "Please leave a message after the beep". After leaving your message, end the call.

Then, check your database to confirm that the call transcription has been saved, as seen in the image below.

SQLite database browser showing a table with call transcription records and associated metadata.

To further verify, go to your Twilio console dashboard and navigate to Monitor > Logs > Call Recordings, where you'll find a list of all successfully recorded calls. This section provides detailed information on each recording, ensuring your calls are captured and stored as expected.

That's how to create a post-call transcription system in Laravel with Twilio

Creating a post-call transcription system involves several key steps that effectively integrate Twilio's communication features with Laravel. By setting up a Twilio Service Provider, handling incoming calls through a dedicated controller, configuring webhooks for transcription callbacks, and ensuring data is properly recorded in the database.

This system not only enhances your application's functionality by offering automated transcription services but also ensures that all call-related information is well-organized and easily accessible.

Whether for customer service, data analysis, or record-keeping, this integration provides a scalable method for managing phone conversations within your application. With this setup, you can leverage Twilio's capabilities to deliver a smooth and reliable post-call transcription experience. Happy coding!

Lucky Opuama is a software engineer and technical writer with a passion for exploring new tech stacks and writing about them. Connect with him on LinkedIn.