How to Use Queues

If you've ever called any company's support or sales line, you've probably used a queue. Queueing is a crucial part of an IVR for any company to handle multiple callers at once. SignalWire makes it very easy to store callers in a queue in the order that they called and then connect them to a live agent whenever it's their turn. This guide will show you how to implement queues simply using XML bins and how to implement them using the SignalWire SDK.

What do I need to get started?

You will need a SignalWire phone number that we can configure to handle inbound calls or to make outbound calls. You can read our handy guide on how to purchase a phone number here if you have not done so already.

You can also read here to learn more about webhooks and how to configure them. We will be using inbound voice call webhooks for recording inbound calls.

If you want to create an application that can handle more complex conferencing, you will also need to create an XML document in one of the SignalWire SDKs. This allows for greater customizability and the ability to build expansive applications serving multiple purposes in one document. You will need to make sure you have installed one of the SignalWire client SDKs in Python, Node.JS, PHP, or Ruby to write the XML document. You can view installation instructions here.

Lastly, if you are using the SignalWire SDK, you will need to host your code on a server to make it publically accessible! For local testing without using a server, ngrok is a great tool to allow you to create an SSH tunnel to your code on localhost making it publically accessible by SignalWire. You will then need to use it as your webhook for handling inbound calls.

Queues with XML Bins (serverless code hosting)

At the most basic level, the only thing needed to create a simple queue is to use the verb Enqueue to place an incoming caller into a queue. You can create an XML bin with the following code and attach it to a phone number as the webhook for handling inbound calls.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say> Thank you for calling Best Quality Vacuum. Ed Galbraith is currently unavailable or speaking with other customers. Please stay on the line to speak with one of his representatives. </Say>
    <Enqueue>Best Quality Vacuum</Enqueue>
</Response>

To connect to the customer in the queue who is next in line, we simply need to use the Dial verb to reach the same queue and include a URL with instructions for handling the customer's side of the call. In this case, we will play a short message.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>Connecting to caller...the next voice you hear will be the customer.</Say>
    <Dial>
        <Queue url="https://bowl-test.signalwire.com/laml-bins/962230ad-10f5-485d-9bfa-458c7ae1213c">Best Quality Vacuum</Queue>
    </Dial>
</Response>

The URL in the previous bin can point to another bin that includes the Say verb to play a short message for the caller informing them that they will soon be connected to an agent. You could also use the Play verb

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>This call will be recorded for quality control and training. You will now be connected to the next representative.</Say>
</Response>

Queues with the SignalWire SDK

The code sample below is an example of a queuing application on a Flask framework with the Python SDK. However, you can replicate this demo with any of our other SignalWire SDKs and a valid web framework.

This example will set a global array that contains the phone numbers of your agents. You can have only one agent or you could list a whole team.

When a call comes in, the code will first check if any digits were pressed and passed along with the HTTP request. If there were no digits pressed, we will then check to see if the caller number is in the support agent array. If the caller is a support agent, we will play a prompt asking them to either press 1 to connect to the next caller in the queue or press 2 to hang up the call and take a break. Once they press digits, we will pass those in the HTTP request back to the default route.

This time, we will check what digits are pressed and either dial the queue or hang up the call. If neither 1 or 2 is pressed, we will remind the agent to pick a choice and replay the prompt. If the caller is a customer and therefore not in the support agent array, we will play a short prompt advising them to wait in the queue for the next available agent.

from flask import Flask, request
from signalwire.voice_response import VoiceResponse, Dial, Gather
from dotenv import load_dotenv
load_dotenv()

app = Flask(__name__)

# Set up support agents
support_agents = ['+12141111111', '+13461111111']

@app.route("/default", methods=["GET", "POST"])
def voice():
    # instantiate voice response as response 
    response = VoiceResponse()
    
    # check if any digits have already been pressed and passed back to our default route 
    if "Digits" in request.values:
        selection = request.values['Digits']

        # check if caller is support agent
        if request.values.get('From') in support_agents:
          
            # if caller is support agent and digits pressed were 1, we will connect to the support queue 
            if selection == "1":
                response.say("You will now be connected to the customer, please hold. "
                             "The next voice you hear will be the customer's.")
                dial = Dial()
                dial.queue("support")
                response.append(dial)
                
                        # if the caller is a support agent and digits pressed were 2, we will hangup the call 
            elif selection == "2":
                response.say("That's okay, everyone needs a break! See you later for more customer calls, goodbye!")
                response.hangup()
                
                        # if digits pressed were not 1 or 2 and caller is a support agent, we will ask them to make a selection and replay the prompt
            else:
                response.say("Please select 1 or 2 so that we can direct your call!")
    
    # if no digits were pressed, assume this is the first time calling in and play welcome message
    else:
      
        # if caller is support agent, use gather to gather input and play prompt to connect to caller or hang up 
        if request.values.get('From') in support_agents:
            gather = Gather(num_digits=1)
            gather.say(
                "Hello team member. Thank you for dialing in. Press 1 to connect to the next caller or "
                "press 2 to end the call if you are not ready to speak to customers.")
            response.append(gather)
            
                # if caller is not support agent, play customer prompt and use enqueue to put them in the support queue 
        else:
            response.say("Hello and thank you for calling! All of our agents are currently on the line with other "
                         "customers. Please hold, and someone will be with you soon.")
            response.enqueue("support")
    
    # redirect to default after gathering digits so that the call can be routed correctly 
    response.redirect("/voice")
        
        # convert response to string as compatibility api requires proper XML 
    return str(response)
  
# run app
if __name__ == "__main__":
    app.run()

Did this page help you?