Skip to contentSkip to navigationSkip to topbar
Rate this page:
On this page

Create Tasks from Phone Calls using TwiML: Dequeue a Call to a Worker


In the previous step we created a Task from an incoming phone call using <Enqueue workflowSid="WW0123401234..">. In this step we will create another call and dequeue it to an eligible Worker when one becomes available.

Back in Part 1 of the Quickstart we created a Worker named Alice that is capable of handling both English and Spanish inquiries. With your Workspace open in the TaskRouter web portal(link takes you to an external page), click 'Workers' and click to edit the details of our Worker Alice. Ensure that Alice is set to a non-available Activity state such as 'Offline'. Next, edit Alice's JSON attributes and add a "contact_uri" field. When Alice accepts a Task, she will receive a call on the phone number entered in the "contact_uri" field. Replace the dummy 555 number below with your own phone number.

Alice's modified JSON attributes:


_10
{"languages": ["en", "es"], "contact_uri": "+15555555555"}

Or, as displayed in the web portal:

Alice's Worker Details.

In this step, we again use <Enqueue> to create a Task from an incoming phone call. When an eligible Worker (in this case Alice) becomes available, TaskRouter will make a request to our Assignment Callback URL. This time, we will respond with a special 'dequeue' instruction; this tells Twilio to call Alice at her 'contact_uri' and bridge to the caller.

For this part of the Quickstart, although not totally necessary it will be useful to have two phones available - one to call your Twilio number, and one to receive a call as Alice. Experienced Twilio users might consider using Twilio Client as one of the endpoints.

Before we add the 'dequeue' assignment instruction we need to create a new Activity in our TaskRouter Workspace. One of the nice things about integrating TaskRouter with TwiML is that our Worker will automatically transition through various Activities as the call is assigned, answered and even hung up. We need an Activity for our Worker to transition to when the call ends.

With your Workspace open in the TaskRouter web portal(link takes you to an external page), click 'Activities' and then 'Create Activity'. Give the new Activity a name of 'WrapUp' and a value of 'unavailable'. Once you've saved it, make a note of the Activity Sid:

Create a WrapUp Activity.

To return the 'dequeue' assignment instruction, modify run.py assignment_callback endpoint to now issue a dequeue instruction, substituting your new WrapUp ActivitySid between the curly braces:


run.py

runpy page anchor

_79
# -*- coding: latin-1 -*-
_79
_79
from flask import Flask, request, Response
_79
from twilio.rest import Client
_79
from twilio.twiml.voice_response import VoiceResponse
_79
_79
app = Flask(__name__)
_79
_79
# Your Account Sid and Auth Token from twilio.com/user/account
_79
account_sid = "{{ account_sid }}"
_79
auth_token = "{{ auth_token }}"
_79
workspace_sid = "{{ workspace_sid }}"
_79
workflow_sid = "{{ workflow_sid }}"
_79
_79
client = Client(account_sid, auth_token)
_79
_79
@app.route("/assignment_callback", methods=['GET', 'POST'])
_79
def assignment_callback():
_79
"""Respond to assignment callbacks with an acceptance and 200 response"""
_79
_79
ret = '{"instruction": "dequeue", "from":"+15556667777", "post_work_activity_sid":"WA0123401234..."}' # a verified phone number from your twilio account
_79
resp = Response(response=ret, status=200, mimetype='application/json')
_79
return resp
_79
_79
@app.route("/create_task", methods=['GET', 'POST'])
_79
def create_task():
_79
"""Creating a Task"""
_79
task = client.workspaces(workspace_sid) \
_79
.tasks.create(workflow_sid=workflow_sid,
_79
attributes='{"selected_language":"es"}')
_79
_79
print(task.attributes)
_79
resp = Response({}, status=200, mimetype='application/json')
_79
return resp
_79
_79
@app.route("/accept_reservation", methods=['GET', 'POST'])
_79
def accept_reservation(task_sid, reservation_sid):
_79
"""Accepting a Reservation"""
_79
task_sid = request.args.get('task_sid')
_79
reservation_sid = request.args.get('reservation_sid')
_79
_79
reservation = client.workspaces(workspace_sid) \
_79
.tasks(task_sid) \
_79
.reservations(reservation_sid) \
_79
.update(reservation_status='accepted')
_79
_79
print(reservation.reservation_status)
_79
print(reservation.worker_name)
_79
_79
resp = Response({}, status=200, mimetype='application/json')
_79
return resp
_79
_79
@app.route("/incoming_call", methods=['GET', 'POST'])
_79
def incoming_call():
_79
"""Respond to incoming requests."""
_79
_79
resp = VoiceResponse()
_79
with resp.gather(numDigits=1, action="/enqueue_call", method="POST", timeout=5) as g:
_79
g.say("Para Español oprime el uno.".decode("utf8"), language='es')
_79
g.say("For English, please hold or press two.", language='en')
_79
_79
return str(resp)
_79
_79
@app.route("/enqueue_call", methods=['GET', 'POST'])
_79
def enqueue_call():
_79
digit_pressed = request.args.get('Digits')
_79
if digit_pressed == "1":
_79
language = "es"
_79
else:
_79
language = "en"
_79
_79
resp = VoiceResponse()
_79
with resp.enqueue(None, workflowSid=workflow_sid) as e:
_79
e.task('{"selected_language":"' + language + '"}')
_79
_79
return str(resp)
_79
_79
if __name__ == "__main__":
_79
app.run(debug=True)

This returns a very simple JSON object from the Assignment Callback URL:



_10
{"instruction":"dequeue", "from": "+15556667777", "post_work_activity_sid": "WA01234012340123401234"}

The JSON instructs Twilio to dequeue the waiting call and, because we don't include an explicit "to" field in our JSON, connect it to our Worker at their "contact_uri". This is convenient default behavior provided by TaskRouter.

In the next step, we test our incoming call flow from end-to-end.

Next: End-to-End Phone Call Task Assignment »


Rate this page: