Have you ever dialed a company and been prompted to follow along with menu prompts? If you have then you have interacted with an Interactive Voice Response (IVR). The IVR acts on input provided by the caller, usually in the form of numeric keypad choices. You can build your own IVR using Ruby on Rails and the Nexmo Voice API.
In this walkthrough, we will build a small Rails application that will host a simple IVR service. After we are done, you can expand on this application to build whatever you need. In this tutorial, our application will accept a numeric input (also called a DTMF code) from the caller, and then speak back the input entered to the caller.
Prerequisites
You will need the following to follow along in this tutorial:
- A Nexmo account
- Ruby on Rails
- ngrok so Nexmo can access the service running locally on your machine
Getting Started
Create a Rails Application
The first thing we need to do is to create a new Rails application. You can do so on your command line with the following:
1 2 |
$ rails new nexmo-rails-ivr-demo --skip-activerecord |
The above command will create our Rails app in /nexmo-rails-ivr-demo
, and will also skip installing a database. In this tutorial we will not be persisting our data, so we do not need it.
Change directories into the nexmo-rails-ivr-demo
folder and run bundle install
from the command line. While Nexmo has a robust Ruby SDK gem, and a new Rails initializer gem, we do not need to install either for this application.
Create an IVR Controller
Now that our application has been created our next step is to create the Controller that will respond to two routes with Nexmo Call Control Objects (NCCO). The first route will answer the call and request the caller to press a number on their keypad. The second route will speak back the number the caller entered.
To create our Controller run the following from the command line:
1 2 |
$ rails generate controller IVR |
Once that has completed, open up the application in your preferred code editor and let’s edit the newly generated /app/controllers/ivr_controller.rb
. We are going to add methods for our two routes now. First, let’s create the #answer
method that will pick up the call:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# ivr_controller.rb class IvrController < ApplicationController skip_before_action :verify_authenticity_token BASE_URL = '' def answer render json: [ { :action => 'talk', :text => 'Welcome to the Nexmo Ruby on Rails IVR Demo Application. Please enter a number on your keypad, followed by the hash key.', :voiceName => 'Amy' }, { :action => 'input', :submitOnHash => true, :eventUrl => ["#{BASE_URL}/event"] } ].to_json end end |
As shown above, the #answer
method provides two NCCO instructions. The first is the talk
action, wherein the caller is greeted by the application. I chose the Amy
voice for this action, however, there are numerous voice options to choose from in the text-to-speech guide.
The second action is the input
action, and we have set the optional parameter submitOnHash
to true
so that the input ends when the user presses the hash key on their phone. We also provide the required eventUrl
parameter with a URL that points to our other route that will respond to the user input.
Lastly, we see that the #answer
method uses a constant variable called BASE_URL
that is currently defined as an empty string. Later in this walkthrough, we will fill that in with our ngrok externally accessible URL.
Now, let’s add our second and final Controller action, #event
. This will act upon the caller input by speaking back to the caller their number choice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# ivr_controller.rb def event number = params['dtmf'] render json: [ { :action => 'talk', :text => "You entered #{number}. Thank you for trying the Nexmo Ruby on Rails IVR Demo Application!", :voiceName => 'Joey' } ].to_json end |
All together our Controller will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# ivr_controller.rb class IvrController < ApplicationController skip_before_action :verify_authenticity_token BASE_URL = '' def answer render json: [ { :action => 'talk', :text => 'Welcome to the Nexmo Ruby on Rails IVR Demo Application. Please enter a number on your keypad, followed by the hash key.', :voiceName => 'Amy' }, { :action => 'input', :submitOnHash => true, :eventUrl => ["#{BASE_URL}/event"] } ].to_json end def event number = params['dtmf'] render json: [ { :action => 'talk', :text => "You entered #{number}. Thank you for trying the Nexmo Ruby on Rails IVR Demo Application!", :voiceName => 'Joey' } ].to_json end end |
Define Routes
The last step we need to do in setting up our Rails application, for now, is to define our routes. We do that by editing the /config/routes.rb
file and adding the two URL paths corresponding to our two Controller actions:
1 2 3 4 5 |
# routes.rb get '/answer', to: 'ivr#answer' post '/event', to: 'ivr#event' |
At this point, our Rails application is ready to run. Now let’s set up our ngrok externally accessible URL. We will need that for the final step, which is creating our Nexmo application and our Nexmo provisioned phone number.
Connect to the Outside World
Set Up ngrok
There are several ways to make our local development server externally accessible, but one of the simplest ways is with ngrok. You can read this article for a more detailed explanation of how ngrok works.
However, for our purposes, we just need to get it running and copy the URL that it provides us.
In order to start ngrok, open up a new terminal window and execute the following from the command line:
1 2 |
$ ngrok http 3000 |
You will now see a ngrok logging interface in your terminal window. Near the top of the interface is a line that begins with Forwarding
and contains two URLs. The first is the externally accessible ngrok URL, which ends with ngrok.io
followed by http://localhost:3000
, that being your local development server. Now, when you or Nexmo contacts the ngrok.io
URL, it will forward it to your local server.
Now would be a good time to go back to the ivr_controller.rb
and replace the empty string with your ngrok URL for the BASE_URL
constant. We will also be using it in our next step of setting up our Nexmo account, phone number, and Voice application.
Get Connected with Nexmo
Set Up a Nexmo Account
In order for our voice application to work, we need a Nexmo account, a Nexmo provisioned phone number, a Nexmo application, and, lastly, we need to link our application to our phone number.
You can create a Nexmo account for free, and as an added bonus, your account will be credited with 2 euros to begin using your new application. Navigate to https://dashboard.nexmo.com/sign-up in your web browser and go through the signup steps. Once you have finished you will be in your Nexmo dashboard.
From the left-hand menu, click on the Voice menu
item. You will see the following four options under APPLICATIONS
:
Click on the Create an application
option and you will be directed to a page where you can set up a new Nexmo application.
Complete the form with the following:
Application name
text field enternexmo-rails-ivr-demo
Event URL
text field enter your ngrok URL:https://[ngrok url here]/event
Answer URL
text field enter your ngrok URL again:https://[ngrok url here]/webhooks/answer
Once you have finished, go ahead and click the blue Create Application
button.
After the application has been created you can generate a public/private key pair. We will not be using them for this tutorial, but it is good to know where they are in case you choose to expand upon this application with more functionality.
You now have created a Nexmo Voice application. Our next step is to purchase a Nexmo phone number and link it to this application.
From the Nexmo Dashboard, click on the Numbers
menu item on the left-hand menu. You will see three options appear:
Click on the Buy numbers
option and you will be directed to a page where you can choose a country, features, type, and four digits you would like the number to have.
For our purposes: pick the country that you are currently in so that the call will be a local call for you; pick Voice
for features and either mobile or landline for type. You do not need to enter anything for the Number
text field. When you click Search
, you will see a list of phone numbers available.
Pick one by clicking the orange Buy
button, and click the orange Buy
button once more in the confirmation prompt.
Once you own the number, you can now link it to your nexmo-rails-ivr-demo
Voice application. To do so, click on the gear icon next to the phone number and you will see the following menu:
Select the nexmo-rails-ivr-demo
Application from the drop-down list and click on the blue Ok
button. Your Nexmo phone number is now linked to your application and ready to accept phone calls and send them to the IVR Rails app.
With that last step, you have finished! You now have a fully functional simple IVR Rails application powered by Nexmo. You can give it a go by starting your Rails server, and with ngrok also running, give your application a call at the phone number you just purchased.
Further Reading
To continue learning about what we discussed consider exploring the following: