Menu

Expand
Rate this page:

Warm Transfer with Ruby and Rails

Have you ever been disconnected from a support call while being transferred to someone else? That couldn't have left a great impression on you...

Warm transfer eliminates this problem - it allows your agents to have the ability to dial in another agent in real time.

Today we'll add warm transfer to a Ruby on Rails application so we can engender warm feelings among customers talking to support.

Here's how it works at a high level:

  1. The first agent becomes available by connecting through the web client.
  2. The second agent becomes available by connecting through the web client.
  3. A customer calls our support line.
  4. The client stays on hold while the first agent joins the call.
  5. While the first agent is on the phone with the client, he or she dials the second agent into the call.
  6. Once the second agent is on the call, the first one can disconnect. The client and the second agent stay on the call.

Let's get started! Clone the sample application from Github, and click the button below to begin.

Let's Transfer... Warmly

Set Up The Voice Web Hook

First, let's configure the voice web-hook for the Twilio number that customers will dial when they want to talk to a support agent.

Twilio Console for Warm Transfer

In production, this should be the public-facing URL for your app.

One option to expose a development URL from your local machine is to use ngrok. Your URL would then be something like:

https://<your-ngrok-id>.ngrok.io/conference/connect/client

Loading Code Sample...
        
        
        config/routes.rb

        Route for our webhook

        config/routes.rb

        Nice work! With a webhook in place we're ready to dive into the code.

        Next

        Connect an Agent to a Call

        Here you can see all front-end code necessary to connect an agent using Twilio's Voice Web Client.

        We need three things to have a live web client:

        • A capability token (provided by our Rails app)
        • A unique identifier (string) for each agent
        • Event listeners to handle different Twilio-triggered events
        Loading Code Sample...
              
              
              app/assets/javascripts/main.js

              Create a new call from the browser

              app/assets/javascripts/main.js

              In the next step we'll take a closer look at capability token generation.

              Generate the Token!

              Generate a Capability Token

              In order to connect the Twilio Voice Web Client we need a capability token.

              To allow incoming connections through the web client an identifier must be provided when generating the token.

              Loading Code Sample...
                    
                    
                    Generate a new capability token for a given agent identifier

                    lib/twilio_capability.rb

                    Generate a new capability token for a given agent identifier

                    Next up let's take a look at how to handle incoming calls.

                    Next

                    Handle Incoming Support Calls

                    For this tutorial we used fixed identifier strings like agent1 and agent2 but you can use any unique application generated string for your call center clients. These identifiers will be used to create outbound calls to the specified agent using the Twilio REST API.

                    When a client makes a call to our Twilio number the application receives a POST request asking for instructions. We'll use TwiML to instruct the client to join a conference room and use the Twilio REST API client to invite (and initiate a call to) the first agent.

                    When providing instructions to the client, we also provide a waitUrl. This URL is another end point of our application and will return more TwiML to SAY welcome to the user and also PLAY some music while on hold.

                    We use the client's CallSid as the conference identifier. Since all participants need this identifier to join the conference, we'll need to store it in a database so that we can grab it when we dial the second agent into the conference.

                    Loading Code Sample...
                          
                          
                          app/controllers/conference_controller.rb

                          Create a conference call, connect the first agent, and put the client on hold

                          app/controllers/conference_controller.rb

                          Next up we'll look at the TwiML response to the client support call.

                          Next

                          Provide TwiML Instructions For The Client

                          Here we create a TwiMLResponse that will contain a DIAL verb with a CONFERENCE noun that will instruct the JavaScript client to join a specific conference room.

                          Loading Code Sample...
                                
                                
                                lib/twiml_generator.rb

                                Generate a TwiML response for the client to join a conference call

                                lib/twiml_generator.rb

                                Now let's look at how we dial the first support agent into the conference call.

                                Next

                                Dial The First Agent Into the Call

                                For our app we created a Caller module to handle dialing our agents. This module uses Twilio's REST API to create a new call.

                                The create method receives a hash with the following keys:

                                1. from: Your Twilio number
                                2. to : The agent web client's identifier (agent1 or agent2)
                                3. url : A url to ask for TwiML instructions when the call connects

                                Once the agent answers the call in the web client, a request is made to the callback url instructing Twilio to join the agent's call with the conference room where the client is already waiting.

                                Loading Code Sample...
                                      
                                      
                                      lib/caller.rb

                                      Call an agent and redirect to the conference room

                                      lib/caller.rb

                                      Next up, let's look at bringing the second agent into the phone call.

                                      Next

                                      Dial The Second Agent Into the Call

                                      When the client and the first agent are both in the call we are ready to perform a warm transfer to a second agent.

                                      The first agent makes a request passing its identifier to allow us to look for the conference_id needed to add the second agent. Since we already have a Caller module, we can simply use the call_agent instance method to connect the second agent.

                                      Loading Code Sample...
                                            
                                            
                                            app/controllers/conference_controller.rb

                                            Add the second agent to the conference call

                                            app/controllers/conference_controller.rb

                                            Once the second agent is in the call we can have the first agent disconnect. Let's look at the handoff next.

                                            Next

                                            The First Agent Leaves the Call

                                            When the three participants have joined the same call, the first agent has served his or her purpose. Now agent #1 can drop the call, leaving agent #2 and the client to discuss support matters and the weather.

                                            It is important to notice the differences between the TwiML each one of the participants received when joining the call:

                                            • Both agent one and two have startConferenceOnEnter set to true.
                                            • For the client calling and for agent two, endConferenceOnExit is set to true.

                                            Translated, this means a conference will start when either agent joins the call. It also means the client or agent #2 disconnecting will hang up the call.

                                            Loading Code Sample...
                                                  
                                                  
                                                  lib/twiml_generator.rb

                                                  Instruction to dial into a conference call

                                                  lib/twiml_generator.rb

                                                  And that's a wrap! You've now helped us implement warm transfers for our support application. You're ready to add this capability on your own website!

                                                  Next

                                                  Where to Next?

                                                  Ruby and Twilio are excellent partners. Here are two other tutorials you're sure to enjoy:

                                                  Browser Calls

                                                  Learn how to use Twilio Client to make browser-to-phone and browser-to-browser calls with ease.

                                                  ETA Notifications

                                                  Learn how to implement ETA Notifications using Ruby on Rails and Twilio.

                                                  Did this help?

                                                  Thanks for checking this tutorial out! Let us know on Twitter what you've built... or what you're building.

                                                  Mario Celi Hector Ortega David Prothero Kat King Samuel Mendes Andrew Baker Paul Kamp Brianna DelValle
                                                  Rate this page:

                                                  Need some help?

                                                  We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.

                                                  Loading Code Sample...
                                                        
                                                        
                                                        

                                                        Thank you for your feedback!

                                                        Please select the reason(s) for your feedback. The additional information you provide helps us improve our documentation:

                                                        Sending your feedback...
                                                        🎉 Thank you for your feedback!
                                                        Something went wrong. Please try again.

                                                        Thanks for your feedback!

                                                        thanks-feedback-gif