Building IVR Hotline with Plivo
- 08 Feb 2018
Plivo is on a mission to simplify telecom, and developers are at the center of this endeavour. For a developer coming from other domains outside core telecom, creating an end-to-end working implementation of a voice-based application can be a daunting task. For a recent hackathon, Jordan Crawford from New Zealand decided to take up precisely this challenge. He decided to try combining web and telephony to create an IVR hotline system in less than 48 hours — and he succeeded! It’s fulfilling for us to see how developers from almost any domain can use Plivo APIs to add Voice and SMS capability to virtually any application.
We asked Jordan to share his experience working with Plivo.
|Ten percent of my work time is dedicated to professional development through two “Hackdays” a month. For my most recent Hackdays I wanted to combine old-school phone technology with modern web technologies. I thought of using Plivo, which lets you work with the phone network through a web API.|
Why did I choose Plivo?
You can do a lot of things with Plivo, including:
- Sending and receiving SMS messages
- Receiving inbound calls and making outbound calls
- On a call you can:
- Convert text to speech
- Play audio by providing a URL to an MP3 file
- Accept digits from callers (“press 1 for sales” in phone menus)
In addition, the Plivo documentation has plenty of resources that help you get started on a project right away.
Making something with Plivo
My initial plan was to implement a game of Hangman over SMS, especially considering I’d written a game of Hangman back on my devtrain. However, I quickly discovered that Plivo didn’t support receiving SMS messages in New Zealand, only sending them. Next, I thought I’d just make a phone call-based Hangman game, but without speech recognition support, it would be difficult to receive character inputs.
I put my thinking hat on and came up with the idea of implementing a simple number guessing game. This was a great place to start because the logic for such a game is simple, which allowed me to focus on the phone integration side. The game chooses a random number between 1 and 100 and asks the caller to guess the number by entering it on their dialpad.
The game gives feedback on whether the guess is correct or higher or lower than the actual number. If the guess is wrong, the caller can keep guessing until they get it correct.
How did I work with Plivo for calling?
Something I was unsure about initially was how you’d actually handle a call. I’d assumed that after a call was picked up that you’d need to deal with the audio stream yourself, but in fact, Plivo handles the entire audio stream for you.
When a call comes in, Plivo hits your API and provides a set of instructions in XML. Depending on the actions you ask for, you may need to define a callback URL for Plivo to hit later with more data — that is, a URL for it to hit for instructions after receiving digits from the caller.
It takes a little while to think about phone calls in terms of API requests, but this approach means that you can scale your phone system just like you scale your normal web APIs.
I used Node.js and Plivo’s Node SDK to build the hotline’s API. Plivo’s SDK handles all the XML instruction formatting for you, making implementation simple. A good reference for this was Plivo’s Getting Started with IVR guide, which introduces all the Plivo functionality I used for the project.
The game is pretty simple. It consists of two endpoints for Plivo to hit: one for when the call is made to welcome the caller (and prompt them to enter a guess) and the other as a callback for the caller’s guess.
When a call comes in, Plivo hits the
/ route with a
GET request and the route returns the following XML to instruct Plivo:
<Response> <Speak>Welcome to the number guessing hotline.</Speak> <GetDigits action="[server URL]/guess?number=[chosen random number]" method="POST" timeout="10" numDigits="2" retries="3"> <Speak>What is your guess?</Speak> <Play>[server URL]/elevator_music.mp3</Play> </GetDigits> <Speak>Huh? I didn't understand. Could you try again?</Speak> </Response>
This tells Plivo to speak a welcome message, then allow the caller to enter some digits with a defined callback URL. Plivo will ask the caller what their guess is and play music while the caller enters their digits.
GetDigits action fails (if the caller takes too long, for instance) then Plivo will speak the wrong input message.
Guess checking route
When the caller enters digits, Plivo hits the guess URL with a
POST request. Plivo puts the entered digits in a Digits field in the request (if you’re testing this out for yourself in a tool like Postman, use the
x-www-form-urlencoded format of
In addition to this, you may have noticed in the XML above, the game’s chosen random number is a query string parameter in the callback URL. This is because I’m lazy and I didn’t want to have to persist the chosen random number for a call in a database. Getting Plivo to pass this parameter around for us means we can easily scale up the number of app servers as required for the millions of simultaneous calls required by our booming number guessing hotline startup!
You can checkout the code for the guess route, but it yet again returns some XML for Plivo:
<Response> <Speak>You guessed too [low/high]!</Speak> <GetDigits action="[server URL]/guess?number=[chosen random number]" method="POST" timeout="10" numDigits="2" retries="3"> <Speak>What is your guess?</Speak> <Play>[server URL]/elevator_music.mp3</Play> </GetDigits> <Speak>Huh? I didn't understand. Could you try again?</Speak> </Response>
Once again, this makes use of
GetDigits to prompt the caller for a further guess, making use of the same callback URL with the random number. If the caller gets the number correct, it returns a simple
You can check out all the code on GitHub.
Setting the hotline up on Plivo
When a call comes in, Plivo needs to hit a public API endpoint that we provide. This means we need to host our API somewhere on the internet.
If you aren’t comfortable with SSHing into a server to set up your app, Heroku is a good option that takes care of all the server management stuff for you. If you want to save a bit of money and don’t mind running the app server yourself, DigitalOcean or Vultr will work great. All these options use hourly (or in the case of Heroku, secondly) billing so it won’t cost you much to mess around with Plivo. This game might also be a good candidate for Serverless given the simplicity of our application code.