Skip to contentSkip to navigationSkip to topbar
Page tools
Useful for sharing or LLM

Looking for more inspiration?Visit the

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. Replace the dummy 555 number below with your own phone number.

Alice's modified JSON attributes:

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

Or, as displayed in the web portal:

Alice's worker details with offline status and contact URI.

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 the Twilio Dev Phone 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:

Form to create activity with name WrapUp in Customer Care Center workspace, availability set to unavailable.

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

server.rb

serverrb page anchor
1
require 'rubygems'
2
require 'twilio-ruby'
3
require 'sinatra'
4
require 'json'
5
6
set :port, 8080
7
8
# Find your Account SID at twilio.com/console
9
# Provision API Keys at twilio.com/console/runtime/api-keys
10
account_sid = '{{ account_sid }}'
11
api_key = '{{ api_key }}'
12
api_secret = '{{ api_secret }}'
13
workspace_sid = '{{ workspace_sid }}'
14
workflow_sid = '{{ workflow_sid }}'
15
16
@client = Twilio::REST::Client.new(api_key, api_secret, account_sid)
17
18
post '/assignment_callback' do
19
# Respond to assignment callbacks with accept instruction
20
content_type :json
21
# from must be a verified phone number from your twilio account
22
{
23
"instruction" => "dequeue",
24
"from" => "+15556667777",
25
"post_work_activity_sid" => "WA0123401234..."
26
}.to_json
27
end
28
29
get '/create-task' do
30
# Create a task
31
task = @client.taskrouter.workspaces(workspace_sid)
32
.tasks
33
.create(
34
attributes: {
35
'selected_language' => 'es'
36
}.to_json,
37
workflow_sid: workflow_sid
38
)
39
task.attributes
40
end
41
42
get '/accept_reservation' do
43
# Accept a Reservation
44
task_sid = params[:task_sid]
45
reservation_sid = params[:reservation_sid]
46
47
reservation = @client.taskrouter.workspaces(workspace_sid)
48
.tasks(task_sid)
49
.reservations(reservation_sid)
50
.update(reservation_status: 'accepted')
51
reservation.worker_name
52
end
53
54
get '/incoming_call' do
55
Twilio::TwiML::VoiceResponse.new do |r|
56
r.gather(action: '/enqueue_call', method: 'POST', timeout: 5, num_digits: 1) do |gather|
57
gather.say('Para Español oprime el uno.', language: 'es')
58
gather.say('For English, please hold or press two.', language: 'en')
59
end
60
end.to_s
61
end
62
63
post '/enqueue_call' do
64
digit_pressed = params[:Digits]
65
if digit_pressed == 1
66
language = "es"
67
else
68
language = "en"
69
end
70
71
attributes = '{"selected_language":"'+language+'"}'
72
73
Twilio::TwiML::VoiceResponse.new do |r|
74
r.enqueue workflowSid: workflow_sid do |e|
75
e.task attributes
76
end
77
end.to_s
78
end

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

{"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 »