Broadcast a Voicemail to Multiple Numbers in Laravel PHP with Twilio Voice
Time to read: 7 minutes
My son just started kindergarten and his first year of not being homeschooled. To say that everyone was nervous was an understatement. Luckily, his school is filled with caring people who aren’t afraid to embrace technology for efficient communication (and calming nervous parents).
There we were, running errands after his drop-off and our phone was alerted with an email including a photo and message of his progress. The personal touch of being able to see him relaxed calmed our anxiety, allowing us to enjoy the remainder of our afternoon.
No matter how much we advance technology, it’s my opinion that we must find ways to include “human touch” as much as possible, even if it’s automated.
This got me thinking about how else I would like to be contacted by his school, especially in case of an emergency. Wouldn’t it be cool if, instead of 160 characters, I could receive a call from his teacher assuring me that everything is okay? While this does sound comforting, it wouldn’t scale well. The more efficient route would be to create a voice-based broadcast that could call every parent and share the teacher’s words.
What are we building?
In this tutorial, we will learn how to create a Teacher-Parent Broadcast App (using newly released Laravel 6.0) to simultaneously broadcast a voice message to multiple numbers.
Our application will implement Laravel’s Authentication, with the addition of the user’s phone numbers added to the signup form. This will enable us to create a collection of numbers to simultaneously call.
Lastly, we will create a Laravel Command to execute the broadcast directly from our terminal.
You will need the following tools to complete this tutorial:
Create a New Laravel Application
Our Teacher-Parent Broadcast App will be built on the Laravel framework. If you haven’t installed it locally, a simple guide is available to get you started. Once Laravel is installed run the following commands in your terminal.
Include the Twilio PHP SDK
The Twilio Voice API will be responsible for processing our requests to make the phone calls. While it boasts many features and use-cases, we will use it to provide a pre-recorded message to play when the user answers their phone.
In order for our application to connect to the API, we will need to include the Twilio PHP SDK in our project. This can be accomplished by running the following command.
Add Your Twilio Credentials to the Project
Now that the SDK is installed, our credentials to authenticate each request to the API will need to be added to the project. Laravel includes a dotenv file in each installation to securely expose 3rd party credentials. In your root folder open .env
and add the following variables with their respective values.
Create a Custom Laravel Configuration
The dotenv file will provide support out of the box to read credentials using the dotenv()
function. However, this isn’t the recommended way as it requires us to hard code the credentials within each location used. It also may not translate well to production environments. Instead, we will wrap these variables within Laravel’s config object and create multiple dynamic variables, keeping in line with SOLID principles.
Custom configurations in Laravel are found within config/services.php
. Open this file and add the following array to the services array.
This update will globalize our Twilio credentials, making them available for use within our system command.
Create a Collection of Phone Numbers
In a real-world application, our database would be prepopulated with users' contact information. We will need to provide a mechanism for simulating this data within our demo.
Our Laravel application comes preloaded with scaffolding for storing users’ information, but we will need to modify the declarations in order to store their phone numbers.
Open the User model located at app/User.php
and add the number
key to the $fillable
(or mass assignable) attributes.
In order to create a column for the user’s phone number, the database migration will need to be modified. Open the CreateUsersTable migration located at database/migrations/2014_10_12_000000_create_users_table.php
and add the 'phone_number'
definition to the schema in the up()
method.
Now that the model and migration have been updated, the migration can be run to generate the users table. Run the following command in your terminal:
NOTE: Your database will need to be defined in the DB_DATABASE
var of your .env
file. Without it, the previous command will not know which database to generate the tables in.
Register a Single User
We’re ready to add a user to the application. To do so, we’ll enable Laravel’s authentication system which will generate the registration and login for us. Run the following commands in your terminal.
Now start the local web server using the Valet command share
.
NOTE: You will need to open a new terminal and leave this one running.
The default registration page only includes fields for name, email, and password. A field will need to be added to the registration page to allow the user to input their phone number. Open up resources/views/auth/register.blade.php
and add the following code above the block of code for the Register submit button.
Validation will be required for this field to successfully submit. In the RegistrationController.php
file update the validator()
method to include the phone_number
.
We require the field to be entered, restrict its type to a string, and set a minimum length of nine (9) characters.
In the same file, add the field to the array in the create()
method to allow it to be inserted into the database.
Registration scaffolding is now complete. Navigate to http://127.0.0.1:8000/register
in your browser and register yourself. Be sure to use your real phone number as our application will use this value to make a phone call.
NOTE: To see a full test of this application, register an additional user with a phone number you have access to.
Create an Artisan Console CommandFor sake of brevity, we will create a console command to trigger our broadcast from the terminal. Ideally, this could be added as a button within an administration dashboard. To generate the scaffolding for our command, run the following in your terminal.
Define the Signature for the Command
The previous command generated a file callEveryone.php
in app/Console/Commands/
. The actual command that we’ll use in the terminal needs to be specified in our class variables. Update the $signature
and $description
variables as shown below. This will allow us to register the command php artisan call:everyone
.
When this command is run our application will register a Twilio client, query the database for all users, and return their attributes in a collection.
New to Laravel are Lazy Collections, a new class that “leverage PHP's generators to allow you to work with very large datasets while keeping memory usage low.” This means that if our application contained 10K users, each user would automatically be read in very small batches versus loading all into before processing.
Accessing this class is simple. On any model, just call ::cursor()
in a foreach
loop and include the respective logic. Each record will be processed individually and memory preserved.
Add the following code to the handle()
method in callEveryone.php
to create a batch calling script.
Test the Broadcast
At this point, we have created a fully operational registration system with an artisan command that calls each user. In your terminal run php artisan call:everyone
and wait for the call to come to your phone.
Setup a Custom Endpoint to Broadcast our Message
Everything we need to broadcast a message to multiple phone numbers is complete. The only item left to complete is controlling the message the recipient hears. To do this we will need to create an endpoint that supplies a TwiML response.
The first thing required to create an endpoint is a new controller. Our controller will be responsible for creating a callback to add to a command. In your terminal run:
This command will create the controller VoiceController.php
in the app/Http/Controllers/API
folder. Open this file and add the following code.
The code above uses Twilio’s VoiceResponse class to generate TwiML and play an mp3 file for the caller. Your application will replace the https://api.twilio.com/cowbell.mp3
URL with your actual voice message.
NOTE: The URL to your mp3 must be publicly accessible.
We’ll need to create a route to access the controller via HTTPS. In the routes
folder is a file named api.php
. This routing file is the home of all CRUD endpoints for our applications. Open the file and add the following line of code.
Lastly, we need to tell the command we created earlier to use this endpoint as a callback URL. This URL will be executed via a POST request and play the voice message when the command is executed.
Navigate back to the terminal that is running your webserver. Copy the HTTPS Forwarding URL and open callEveryone.php
again. Replace the url
parameter of http://demo.twilio.com/docs/voice.xml
with the Forwarding URL + /api/broadcast
.
Conclusion
Your Teacher-Parent Broadcast App is now complete! Give it a try by running the php artisan call:everyone
command in your terminal.
I’d love to see how you build upon this. Maybe you’ll add a GUI to upload your voice message directly or write programmatic responses using the <Say>
verb. Either way, feel free to reach out to me on Twitter or via email if you have any questions or modifications.
Additional Resources
An Introduction to Lazy Collections - The official Laravel Documentation about how the LazyCollection
class leverages PHP Generators.
Understanding PHP Generators - The official PHP Documentation offers an overview with examples to help you understand how PHP generators preserve memory.
Use Laravel for a Quick Development Server - How to Create a Local WordPress Setup in 5 Minutes using Valet, by Marcus Battle, describes how Laravel Valet can improve your existing local development.
If you need any assistance, don’t hesitate to reach out on Twitter or shoot me an email.
Marcus Battle is Twilio’s PHP Developer of Technical Content. You can learn more about him on the blog.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.