So my call app has a 'ring group' functionality. The idea being that certain numbers should fan the call out to multiple ring group members. Twilio has an article which describes this process here:
https://www.twilio.com/blog/2009/05/dialing-multiple-numbers-simultaneously-with-twilio.html
I want to do something similar. Loop through my available ring group members and do a dial.number to each of them. This would create a new call to each one of them that hits our regular incoming call webhook. Works great except if no one answers then the call will be sent to a random members voicemail.
I thought of a couple strategies to possibly fix this but none are quite working:
Manage the timeouts. Set the timeout of the dial for the ring group to something shorter than the timeouts for our incoming call webhook. My thought was this might skip the after action on the incoming calls and go to the after action on the ring group - which is a ring group voicemail box. But in this case setting the timeout on the ring group dial doesn't do anything. Only the timeout on the incoming call webhook is being respected.
Pass some context. If I could pass additional params from the ring group call through the dial.number method then I could recognize in the incoming call webhook that this is coming from a ring group and act accordingly. But apparently you cannot pass custom params. It seemed the only thing I could change was the callerId - which I could use to indicate the ring group number but then I lose the context of who the call is coming from.
Attach a status_callback. I could put a status_callback on the dial.number in the ring group. Once the call is initiated it will post to me with a CallSid. I could use this sid to look through the calls created by my incoming call controller and link up the sids thereby identifying which calls are from a ring group. Unfortunately the CallSid i get on the status_callback for the ring group dial.number does not match any other sid that my app receives. The sids on the incoming call webhook are distinct - and if I fan it out to multiple members interestingly each incoming call webhook gets a different sid. I initially thought that since there was only one leg connected to the incoming call that they would all share the same sid...
I wonder if anyone has any other ideas?
Related
From what I understand, there is a difference between how Twilio handles call forwarding and how the telcom carriers do it.
In the first situation, for standard carrier forwarding, say A calls B. The call gets forwarded to C if either B doesn't answer (conditional call forwarding) or they've set up to always forward (unconditional call forwarding). In other words, the call is routed from the red line to the purple. This is done on the carrier side (B's phone does not even need to be on for this to work).
However, in the case with Twilio, if A is already talking to Twilio (purple path) and application logic decides it is OK to connect A to C (same final result as with the first situation), it does this by passing through Twilio (green path). Twilio calls this Call Forwarding even though it does not behave the same way as before. In this case, there is a middleman in the picture (Twilio), and Twilio also charges you for both the ingoing and outgoing legs.
Is it possible for Twilio to forward the call such that it just takes the blue path, and connects A to C directly? Or am I missing something?
Twilio Programmable Voice uses Twilio Markup Language (TwiML) to control the call flow. If you call your Twilio number and want to forward that call to an end-point off Twilio, Twilio still remains in the signaling and media path, which allows you to remain in control of the call, which is the key part of why that call path is the way it is.
There is no way to remove Twilio from this call flow, as Programmable Voice depends on Twilio remaining in the call path.
Setting Up Call Forwarding
I'm looking to implement a custom call routing function for customers dialing a set of company phone numbers for a sales organization using Twilio. Roughly speaking, I want to do something like the following:
When an incoming call is received, based on the called number (i.e. which twilio number was dialed), lookup a different routing algorithm to decide how to route the call.
Routing algorithm will have a number of specific steps, some of which would be like these:
lookup calling number in sales database, if already assigned then route call to assigned agent
lookup "agent on duty" in shift database, if agent is on-shift then route call to agent on duty
simultaneous ring multiple agents, first agent (if any) to pick up and "dial 1 to accept" gets connected to caller
dial a specific agent
fallback to voicemail
For all these cases we want to "whisper" some caller information to the agent, and optionally present a challenge like "dial 1 to accept call" and gather a response before they are connected
We also want to record calls (and preannounce "this call may be recorded..."
Looking at the Twilio API it seems like there might be a few different high-level approaches, for instance:
Implement my own routing logic, and at each step (potentially) initiate a new twilio outbound call to the agent, present a challenge, gather digits, and connect to caller if agent accepts the call
Implement Twilio Queues - probably place incoming caller in queue, step through routing table until we find an agent (or voicemail), and then pull caller out of queue and connect them
Implement Twilio Queues + TaskRouter - as above, but use Task Router to specify my call routing algorithm.
There will not be a high volume of calls, so queuing wouldn't necessarily be my natural choice, but it is possible there might be a few simultaneous calls at any point. I'm more thinking that queuing might be useful in that it's designed to handle this workflow - specifically accept call, play music/message/ring while we locate an agent, then connect the agent to the queued call.
In general would like some guidance on which path to take - not sure whether Task Router will be flexible enough to handle my call routing (i.e. can I use decision logic based on external database queries, API calls, etc to make task routing decisions). Also, if I choose to do all of this myself (i.e. no queues, task router), then it wasn't clear to me how to "connect" two separate Twilio calls together (i.e. the inbound caller "call" and the outbound "call" to the agent) - do I need to create a twilio conference?
I'll be implementing this in python, but any references to similar implementations in any language would be helpful...
Thanks in advance!
I'd love some advice on my twilio setup for a problem I'm trying to solve.
Overview
A client can call our twilio number and have one of three cases to handle:
- is our client and has a question - should be transfered to CC queue (2ppl),
- wants to buy our services - should be transfered to Sales queue (7ppl),
- has some other case - should be transfered to a different queue, lets call it Other (1 person)
Current solution
The client calls:
welcome message
we gather his digit input
enqueue a call to the appropiate queue
assign a task to an available worker with the conference instruction
Problem with the current solution
If there are no workers in the office to handle the call the client will wait forever until he hangs-up by himself. The wroker who answers doesn't know the clients phone number so he isn't able to fallow-up if neccesary.
Questions
After the client picks a queue i would like to check if I have any workers in the office in that queque (not in Offline mode). If everybody is on offline mode redirect to voicemail and a an email is sent to a specified email address with the caller phone number and voicemail recording url.
After the worker picks-up (accepts the reservation) send him a message with the clients phone number.
If no worker answers within a specified amount of time (for example 5 minutes) the call gets redirected to voicemail and a an email is sent to a specified email address with the caller phone number and voicemail recording url.
Twilio developer evangelist here.
Answers in order, parts 1 and 3 need to talk about voicemail which I'll cover at the bottom:
You can use a skip_if expression to skip a queue if there are no available workers.
I assume this is using the reservation.conference instruction in the JavaScript SDK. You can actually inspect the reservation object at this stage too, check out reservation.task.attributes for all the task attributes, which should include the call attributes. You can use this to show your agent on screen or send them a message some other way.
For this, you should set a timeout on your queue. When the timeout fires the task should drop through to the next queue in the workflow.
Voicemail
For parts 1 and 3 we are ejecting a task from one queue, but it needs to go somewhere else to be dealt with. You want to send the calls to voicemail, which doesn't require an agent to deal with it. Currently, the best way to deal with this is direct the task to a queue that has one bot worker in it. The job of the worker is to redirect incoming reservations straight to some TwiML. You achieve this by instantly responding to an assignment callback with the redirect instruction.
To create voicemail, you can combine <Say> and <Record>. Make sure you set the recordingStatusCallback attribute to a URL in your application, you can then use the results to email the link to the voicemail recording.
Let me know if this helps at all.
thank you for yout time to answer my questions. Below please find my reply:
1. It seems that this does not work in console - I find this information in the documentation "skip_if cannot be configured through the console - it must be posted on the workflow API". As I am not using the workflow API this is probably not a solution for me.
2. I using this tutorial: https://www.twilio.com/docs/quickstart/php/taskrouter/twiml-dequeue-call but instead of using dequeue instruction i use conference. I don't quit get how to "inspect the reservation" - maybe you have a tutorial on that? While looking for other solutions I came up with workspace event calback, but I am not sure if this would work.
3) How can I do that in the console?
I have read a couple similar posts here on SO, however the responses do not explaiin how, they only explain that it is possible with Twilio. If a Twilio Evangelist could give me some specific direction on this it would be greatly appreciated.
The idea is (Caller A) calls (Twilio Number). Twilio stores Caller A's number until a second caller is achieved.
Once (Caller B) calls the same (Twilio Number) he is connected to Caller A.
This is at random, and handling many requests at the same time. Once Caller A and Caller B are connected, their numbers are removed from the storage so nobody else will be connected with them.
Rinse repeat.
Twilio developer evangelist here.
You can do this using Enqueue and <Queue>. First you need to create your queue using the REST API. This can be done ahead of time.
I'm going to use Ruby for the example here, however you can see what this looks like in other languages in our documentation.
require "twilio-ruby"
client = Twilio::REST::Client.new(ENV["TWILIO_ACCOUNT_SID"], ENV["TWILIO_AUTH_TOKEN"])
queue = client.queues.create(:friendly_name => "call_roulette")
puts queue.sid
You'll need to save the Queue Sid and friendly name, you'll use them to connect to the queue later.
Then, when a person calls you need to check whether there is anyone in the queue waiting. If there is then you connect the two callers, if there isn't then you place that caller into the queue and wait for another call.
When the call is made, Twilio will send an HTTP request to the URL you supply in the Twilio console. You need to respond with the correct
based on the conditions above.
This example uses Sinatra as the web framework.
require "twilio-ruby"
require "sinatra"
client = Twilio::REST::Client.new(ENV["TWILIO_ACCOUNT_SID"], ENV["TWILIO_AUTH_TOKEN"])
post "/call" do
queue = client.queues.get(QUEUE_SID)
if queue.current_size == 0
twiml = "<Response><Enqueue>#{QUEUE_FRIENDLY_NAME}</Enqueue></Response>"
else
twiml = "<Response><Dial><Queue>#{QUEUE_FRIENDLY_NAME}</Queue></Dial></Response>"
end
return twiml
end
When the queue is empty, we use Enqueue to put the caller in the queue, when the queue has someone in it, we use Dial and Queue to dial the person in the Queue.
Let me know if that helps at all.
I'm using Twilio to create phone calls between two phone numbers. In certain cases during the call I want to interrupt the call and play IVR messages. When I interrupt the call I want to play a different message to each person.
I see the way to interrupt the call is by redirecting the call here.
Then if I want to say some thing I use the twiml say command here.
But I can't see any way specifying which recipient receives what from the twiml. It seems that when you say a message it will be played to both people on the call.
Can Twilio support this functionality?
Twilio evangelist here.
So I think what you are going to have to do in this case is leverage a Conference. This may change how your initiating the two legs of the call. If you are currently using <Dial> to connect the two callers together, the problem there is that there is no easy way to get the Call SID of the second leg of the call. This means there is no easy way to redirect that call.
So instead of using <Dial>, what I normally do is when Caller A dials in, I put them into a conference, saving the name of the conference room to a database. Then I use the Twilio REST API to make an outbound call to Caller B. When they answer I put them into the same conference room as Caller A.
This also means I have both calls Call SIS, which I can use to redirect the two call legs independently. So in your case, when you wanted to Say something to Caller A, you would simply redirect them our of the conference, use <Say> or <Play> to talk to them, then redirect them back into the conference. Same process for caller B.
Hope that helps.