Chris Guzman

Vonage Team Member

Chris is a Developer Advocate at Nexmo where he helps developers use their global communications platform. When he’s not at conferences you can find him roaming the world.

[Read more]
< Tutorial />

Receive Voice Call Events for a Call In Progress with Ruby on Rails

Last updated on May 20, 2021

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.


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.

Screenshot of new Meetings API session in progress
Start developing in minutes with free credits on us. No credit card required!

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       
Forwarding           -> localhost:3000
Forwarding           -> 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" --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" --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])
            status: params[:status],
            conversation_uuid: params[:conversation_uuid]

    head :ok

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 (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 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",
  "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.