How to build a conference line with Twilio and Ruby
Tags: ruby, rails, twilio
Published: 2020-04-08 05:00:22

---
title: How to build a conference line with Twilio and Ruby
published: true
description: When you need to get a bunch of remote people to talk together, a conference call is the simplest way to do so. Everyone dials a number and in seconds they are talking to each other. In this post we'll build a conference line that anyone can join using Twilio and Ruby on Rails.
tags: ruby, rails, twilio
canonical_url: https://www.twilio.com/blog/build-conference-line-twilio-ruby
cover_image: https://twilio-cms-prod.s3.amazonaws.com/images/3aL4JqUfu8iBclHz3ILMhCc74xEZojpM55XsJZT7hSDWqs.width-808.png
series: Conference Calls on Rails
---

When you need to get a bunch of remote people to talk together, a conference call is the simplest way to do so. Everyone dials a number and in seconds they are talking to each other. In this post we'll build a conference line that anyone can join using Twilio and [Ruby on Rails](https://rubyonrails.org/).

## What you'll need

In order to build this conference line you will need:

*   [Ruby](https://www.ruby-lang.org/en/downloads/) and [Bundler](https://bundler.io/) installed
*   A Twilio account (if you don't have one yet, [sign up for a new Twilio account here and receive $10 credit when you upgrade](https://twil.io/philnash))
*   A [Twilio phone number](https://www.twilio.com/user/account/phone-numbers/incoming) that can receive incoming calls
*   [ngrok](https://ngrok.com/) for [testing webhooks with our local application](https://www.twilio.com/blog/2015/09/6-awesome-reasons-to-use-ngrok-when-testing-webhooks.html)

With those tools gathered, we can get started.

## Getting started with a Rails application

For this post we will create a new Rails app. If you want to add this capability to an existing application, you can skip over this part.

Install the latest version of Rails:

```bash
gem install rails
```

Generate a new Rails application. This application won't need a bunch of stuff that Rails brings with it by default, so I've skipped a few things here:

```bash
rails new --skip-action-mailer --skip-action-mailbox --skip-action-text --skip-active-record --skip-active-storage --skip-action-cable --skip-sprockets --skip-javascript --skip-turbolinks conference-calls-on-rails
cd conference-calls-on-rails
```

Run your new Rails app to make sure everything is working as expected.

```bash
./bin/rails server
```

Open `localhost:3000` and you will see the new Rails application home page. This is what mine looks like:

![The page that shows Rails is running. My Rails version is 6.0.2.2 and Ruby version 2.7.0.](https://twilio-cms-prod.s3.amazonaws.com/images/AD_s5g4jIEy39EjQCwiICq3Rc54kc1XHUtvfI01-UK94Iv.width-500.png)

Now that we have an application to work with let's get to work building our conference line.

## Building the conference line

The conference line will require one controller with an action that will respond to an incoming webhook from Twilio when someone calls your Twilio number. We will respond to the request with [TwiML](https://www.twilio.com/docs/voice/twiml) to tell Twilio to send the caller into a conference call.

### Dependencies

Start by adding the `twilio-ruby` gem to the application `Gemfile`:

```ruby
gem 'bootsnap', '>= 1.4.2', require: false

gem 'twilio-ruby'

group :development, :test do
```

Install the new dependency with:

```bash
bundle install
```

### Creating the controller

Next up, let's generate a new controller for our incoming calls. On the command line run:

```bash
./bin/rails generate controller calls create
```

This will create a `CallsController` that will receive the webhook and return TwiML. It will also generate a route for us, but that route is not the one we want. Twilio webhooks are `POST` requests by default, so let's make our route for a `POST` request too. Open `config/routes.rb` and change it to:

```ruby
Rails.application.routes.draw do
  resources :calls, only: [:create]
end
```

Now we need to update our `CallsController` to return the TwiML to drop callers into a conference call. Open `app/controllers/calls_controller.rb`.

The first thing in this file we need to do is skip the cross-site request forgery (CSRF) protection. The controller is intended to respond to incoming webhooks not from users, but from Twilio, so CSRF protection is unnecessary. Instead, check out this post on how to [protect webhook endpoints in Ruby applications by validating the request signature using Rack middleware](https://www.twilio.com/blog/2014/09/securing-your-ruby-webhooks-with-rack-middleware.html).

To skip the protection, add this to the top of the controller class:

```ruby
class CallsController < ApplicationController
  skip_before_action :verify_authenticity_token

  def create
  end
end
```

Now to build up the TwiML response as part of the `create` action. We'll respond with a quick message to welcome the caller using [<Say>](https://www.twilio.com/docs/voice/twiml/say) then dial them into a conference room with [<Dial>](https://www.twilio.com/docs/voice/twiml/dial) and [<Conference>](https://www.twilio.com/docs/voice/twiml/conference). We have to give the conference room a name so that everyone dialling in arrives in the same place. You can call yours whatever you like.

We'll build up the TwiML using the `twilio-ruby` gem's `Twilio::TwiML::VoiceResponse` class and then render it as XML.

```ruby
class CallsController < ApplicationController
  skip_before_action :verify_authenticity_token

  def create
    twiml = Twilio::TwiML::VoiceResponse.new
    twiml.say(voice: 'alice', message: "Welcome to the conference call, let's dial you in right away.")
    twiml.dial do |dial|
      dial.conference('Thunderdome')
    end
    render xml: twiml
  end
end
```

Run the application again and make a `POST` request to _http://localhost:3000/calls_.You will see the TwiML returned as XML.

```bash
curl -X POST http://localhost:3000/calls
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say voice="alice">Welcome to the conference call, let's dial you in right away.</Say>
  <Dial>
    <Conference>Thunderdome</Conference>
  </Dial>
</Response>
```

### Testing with a real number

It's all very well making `curl` requests, but we want to make sure this conference line works for real. To do so we'll need to open up our local development server to the internet so that it can receive webhook requests from Twilio. [I recommend doing this with ngrok](https://www.twilio.com/blog/2015/09/6-awesome-reasons-to-use-ngrok-when-testing-webhooks.html) and here is how:

First start ngrok and point it to port 3000, which is the port the application server is listening on. You will need to pass the `--host-header` argument with a value of "localhost:3000" too.

```bash
ngrok http 3000 --host-header "localhost:3000"
```

Now grab the ngrok URL that is generated for you. It should look like: `https://NGROK_SUBDOMAIN.ngrok.io`. Open up the [Twilio console and navigate to the phone number you want to use for this conference line](https://www.twilio.com/console/phone-numbers/incoming). Enter the ngrok URL plus the path `/calls` into the field labelled "When a call comes in".

![Enter your webhook URL in the field marked "A call comes in"](https://twilio-cms-prod.s3.amazonaws.com/images/DNQ4PVe-DVXL6hx5Xl5y08ADYuL0bX0U4CVNi6y1BsZpHk.width-500.png)

Save the number, make sure your Rails application is still running, and **give it a call from your phone**. For extra credit, get someone else to call the number too, the holding music will end and you'll be chatting in your own conference line.

By the way, if you want to change the music you can do that using [the `waitUrl` attribute](https://www.twilio.com/docs/voice/twiml/conference#attributes-waitUrl).

## The power to conference call is in your hands

Now that you know how to build a conference line, you can start to add other features to it. Check out the [Conference TwiML](https://www.twilio.com/docs/voice/twiml/conference) docs to learn how to[join a Conference on mute](https://www.twilio.com/docs/voice/twiml/conference?code-sample=code-join-a-conference-muted-9&code-language=Node.js&code-sdk-version=3.x), [silently bridge calls](https://www.twilio.com/docs/voice/twiml/conference?code-sample=code-bridging-calls-9&code-language=Node.js&code-sdk-version=3.x), or [build a moderated conference call](https://www.twilio.com/docs/voice/twiml/conference?code-sample=code-a-moderated-conference-9&code-language=Node.js&code-sdk-version=3.x).

If you want to check out [the complete code for this application you can find it on GitHub](https://github.com/philnash/conference-calls-on-rails). I'd love to hear what you're building with Twilio too, so do hit me up on [Twitter at @philnash](https://twitter.com/philnash) or drop me an email at [philnash@twilio.com](mailto:philnash@twilio.com).