This is the second article in a series of "Getting Started with Nexmo APIs and Ruby on Rails" tutorials. It continues the "Getting Started with Nexmo SMS and Ruby on Rails" series.
In our previous tutorial I showed you how to make a text-to-speech call using the Nexmo API and the Nexmo Ruby gem in a Rails application. What we didn't looked at though is how to know when a call has connected or completed. In this tutorial, we will look at how we can listen for call events from Nexmo to update the status of a call in our application.
View the source code on GitHub.
Prerequisites
To follow this tutorial, I assume you have:
a basic understanding of Ruby and Rails
Rails installed on your machine
NPM installed for the purpose of our CLI
followed our previous tutorial on Making a text-to-speech call with Ruby on Rails
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
What Does "Connected" Mean?
When you make a successful Voice Call request to Nexmo, the API returns a status for your call. Often this will be the initial state of started
. Next, Nexmo will route your call and start ringing the phone of the recipient. When that happens we can notify your Rails application of the change in status using a Call Event Webhook.
To receive this webhook in your application, you will need to set up a webhook endpoint, telling Nexmo where to forward these receipts.
Set the Webhook Endpoint with Nexmo
To receive a webhook we need two things. First, we need to set up our server so that Nexmo can make an HTTP call to it. If you are developing on a local machine, this might be hard, which is where tools like Ngrok come in. I won't go too much into detail, but with Ngrok you can make your local Rails server available to the outside world within seconds. If you'd like to read more about using ngrok, check out this article detailing how to use an ngrok tunnel.
# forwarding port 3000 to an externally accessible URL $ ngrok http 3000
Session Status online Account Cristiano Betta Version 2.2.4 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://abc123.ngrok.io -> localhost:3000 Forwarding https://abc123.ngrok.io -> localhost:3000
With this in place, you can set up this URL as your event_url
webhook address on your Nexmo Application. Lucky for us, we already did this when we created the Nexmo Application in the previous tutorial.
$ nexmo app:create "My Voice App" http://abc123.ngrok.io/inbound_calls http://abc123.ngrok.io/call_events --keyfile private.key --answer_method POST --event_method POST Application created: aaaaaaaa-bbbb-cccc-dddd-0123456789ab Private Key saved to: private.key
If you need to change the URLs somehow, you can do so easily using a pretty similar command.
$ nexmo app:update aaaaaaaa-bbbb-cccc-dddd-0123456789ab "My Voice App" http://abc123.ngrok.io/inbound_calls http://abc123.ngrok.io/call_events --answer_method POST --event_method POST Application updated
Handle a Call Event WebHook
The hard part is done at this point, really. When a call has been initiated Nexmo will notify your application of any changes in the call by sending a webhook. A typical payload will look something like this:
{
"uuid": "aaaaaaaa-bbbb-cccc-dddd-0123456789ab",
"conversation_uuid": "CON-aaaaaaaa-bbbb-cccc-dddd-0123456789ab",
"status": "ringing",
"direction": "outbound"
}
We can extend the example from our previous tutorial and update the call record we stored then with the new status.
# app/controllers/call_events_controller.rb
class CallEventsController < ApplicationController
# We disable CSRF for this webhook call
skip_before_action :verify_authenticity_token
def create
if params[:uuid]
Call.where(uuid: params[:uuid])
.first_or_create
.update(
status: params[:status],
conversation_uuid: params[:conversation_uuid]
)
end
head :ok
end
end
In this example, we find the call record with the uuid
provided, and then update its status with the given status
, in this case "ringing"
.
Start a Call and Receive a Call Event
Now we can use our "Make a call" form by navigating to http://abc123.ngrok.io/outbound_calls (your ngrok URL will be different). You can check out how we built this form in the first article of this series, "Make an Outbound Text-to-Speech Phone Call."
When the call event is sent, we’ll see a log of it in our Rails console.
Started POST "/call_events" for 192.0.2.0 at 2020-01-01 12:00:00 -0500 Parameters: { "conversation_uuid"=>"CON-aaaaaaaa-bbbb-cccc-dddd-0123456789ab", "status"=>"ringing", "direction"=>"outbound"} Call Load (0.3ms) SELECT "calls".* FROM "calls" WHERE "calls"."uuid" = ? ORDER BY "calls"."id" ASC LIMIT ? [["uuid", "aaaaaaaa-bbbb-cccc-dddd-0123456789ab"], ["LIMIT", 1]] Processing by CallEventsController#create as HTML (0.0ms) begin transaction Parameters: {"uuid"=>"aaaaaaaa-bbbb-cccc-dddd-0123456789ab", "conversation_uuid"=>"CON-aaaaaaaa-bbbb-cccc-dddd-0123456789ab", "status"=>"started", "direction"=>"outbound"} SQL (0.3ms) UPDATE "calls" SET "status" = ?, "conversation_uuid" = ?, "is_inbound" = ?, "updated_at" = ? WHERE "calls"."id" = ? [["status", "ringing"], ["conversation_uuid", "CON-aaaaaaaa-bbbb-cccc-dddd-0123456789ab"], ["is_inbound", "f"], ["updated_at", "2020-01-01 12:00:00"], ["id", 6]] Call Load (0.1ms) SELECT "calls".* FROM "calls" WHERE "calls"."uuid" = ? ORDER BY "calls"."id" ASC LIMIT ? [["uuid", "aaaaaaaa-bbbb-cccc-dddd-0123456789ab"], ["LIMIT", 1]] (0.7ms) commit transaction (0.0ms) begin transaction Completed 200 OK in 7ms (ActiveRecord: 1.3ms)
To Sum Things Up
That's it for this tutorial. We've set up our Rails application to receive webhooks, informed Nexmo where to find our server, and processed an incoming webhook with a Delivery Receipt.
You can view the code used in this tutorial on GitHub.
Next Steps
In the next tutorial, we will look at receiving inbound voice calls into our application.