I have an application where I need to delay answering the incoming call while I ring multiple agents in parallel, and then connect the incoming call to one selected agent. Note that for this application it is not an option to answer the call and play a MP3 that mimics a phone ringing - the calling system is an automated system that recognizes when the call has been answered and immediately looks for an agent to respond.
If I want to forward to a single agent's phone, <Dial> + answerOnBridge works perfectly.
I have not been able to come up with a solution for ringing multiple agents in parallel. My issue is holding off the incoming call from being answered. I've tried:
Delay responding to incoming webhook while I locate an agent (Twilio times out)
Respond to the incoming webhook with short duration <Pause> only. Twilio re-sends the incoming webhook after the timeout (with a new CallSid which complicates things). This might work (I can bridge the call on a later retry once I locate an agent), but unfortunately some carriers seem to not handle this <Pause> only - I see Call Failed.
Respond to the incoming webhook with long duration <Pause> + <Hangup>. Then when an agent answers, redirect the incoming call with client.calls().update(). This fails with:
TwilioRestException: HTTP 400 error: Unable to update record: Call is not in-progress. Cannot redirect.
NOTE: the update() works if I respond in a way that answers the incoming call ... but that doesn't work for me.
Is there some other way to keep the incoming call ringing / truly not answered while I broadcast call a few agents, and then connect the incoming caller to one selected agent? Conceptually I'd like something that does a <Enqueue> + answerOnBridge, but I'm running out of ideas for how this can be done...
Twilio developer evangelist here.
Have you tried using multiple <Number>s within your original <Dial answerOnBridge="true">? That would dial each number until one is picked up, connecting the agent who answered and cancelling the other calls.
Something like:
<Response>
<Dial answerOnBridge="true">
<Number>FIRST_NUMBER</Number>
<Number>SECOND_NUMBER</Number>
</Dial>
</Response>
Let me know if that helps.
Related
Scenario:
Person A calls my server. My server returns Twiml with Dial plus extra, connecting them to my client C. Sometimes C's phone is busy, and the extra just tells A they couldn't be connected, try texting.
I want to have a failover, where the same thing happens when C is not busy, but if C is busy, A is put in a queue, as are subsequent callers. When C's call ends, I try to connect A to C.
Is there a way of doing this with simple Twiml verbs, like dial.queue, and Redirect? So far I've failed: I can enqueue A when C is busy, hearing hold music and all, but I've utterly failed to get A off the queue and in touch with C. I suspect I'll need to create calls using the API, but figured I'd ask to see if the Twiml way should be doable.
I am aware that I could just throw all callers into a queue, but for business reasons I want to preserve the "ring and connect" behavior when the client is immediately available.
Twilio developer evangelist here.
The bit here is getting A to start a new call once they are done with the call they are on. You could, for example, send an SMS message to A to tell them that someone is waiting in the queue. Then, when they call their Twilio number back return TwiML that <Dial>s into the <Queue>.
When using the <Queue> TwiML, the caller will be connected to the person waiting at the front of the queue.
Alternatively, if you don't trust A to call the queue back, you could keep trying to periodically make calls to A using the REST API and once the call connects return the same TwiML to <Dial> into the <Queue>. If the caller hangs up and the queue becomes empty before A answers the call, you can stop calling and perhaps send a message to inform A that someone called and they can choose to call them back.
Do Play verb with loop 0 value cause the music to play till the call is connected?
https://www.twilio.com/docs/api/twiml/play
Twilio developer evangelist here.
Effectively in this situation you are looking to put your user in a queue while you dial your agents. This is how you'd do it:
First up, when you receive the incoming call you can respond with <Enqueue> that directs a user into a queue. You can set a waitUrl attribute that allows you to define either a music file or TwiML that will play while the user waits for the call to be answered.
<Response>
<Enqueue waitUrl='/wait-music'>incoming</Enqueue>
</Response>
While your incoming caller is waiting, you can then start making calls to your agents using the REST API. Once an agent connects and accepts the whisper you would then join the calls by dialling the <Queue>.
<Response>
<Dial><Queue>incoming</Queue></Dial>
</Response>
With this method you'd need to maintain whether your user has been answered yet and manually handle whether to redirect their call from the queue to more TwiML to <Record> a voicemail.
There is a more robust way to set all this up. It still requires enqueueing in the first place, but you should take a look at TaskRouter. It's an automated call distribution service with configurable workflows. There's a bit more setup involved on the Twilio side, but TaskRouter will handle directing calls to your agents and allow you to define rules for how to handle a user who's been waiting too long. I recommend you check out the TaskRouter documentation and then take a look at the quickstart guide as an example.
Let me know if that helps at all.
My Twilio server has 3 pages
/listener
Sets up a <dial> and <Conference statusCallback="/gather" statusCallbackEvent="speaker start"> and appends caller to said conference. In the conference, the events request should be sent on any user speaking and conference starting (starting is just used for debugging in case it's something wrong with speaking alone, but the starting request won't be sent as well).
/gather
Uses gather to listen to speech with action='/parse'
/parse
Parses the message.
Right now, when I set the webhook to /gather, I could see 2 POST requests to /gather and /parse no problem. But when I set it to /listener, only 1 POST request per call would appear and no subsequent requests would be sent on conference start or people speaking. Can anyone possibly tell me any example of statusCallbackEvent working with gather or provide any workarounds?
Twilio developer evangelist here.
It looks to me like you are trying to use speech detection on the ongoing conference call via events?
If that is the case, then I'm afraid that is not what statusCallbacks in <Conference> do. statusCallback events during calls are asynchronous callbacks, your response to them will not affect the ongoing call. Responding to a statusCallback event with TwiML will have no effect.
Subsequently, it's not possible to simultaneously continue a <Conference> and use <Gather> on the participants.
For my Twilio number I have TwiML App and I am using Flask as a backend to handle URL for incoming calls. My goal is to create behavior that for every incoming call it hangs up (and send sms, but this is not so relevant at the moment)
so far I used:
Twiml Response with Hangup ends with "busy signal"
Twiml Response with Reject ends with message "number you are calling is not available"
using twilio rest client (like in Twilio's example) client.calls.update("CAe1644a7eed5088b159577c5802d8be38", status="completed") also results in "busy signal"
twilio rest client: client.calls.hangup(twilio_call_sid) also results in "busy signal"
so I am running out of ideas and I can't believe that it's not possible to finished incoming call (without answering) clearly with no busy signal, or I am probably missing something.
I would appreciate any help
Realize this is coming way late, but if you want to simply respond to incoming calls with an SMS you can use the <Sms> TwiML verb to do so.
And then from the users perspective, gracefully end the call with <Hangup>.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Sms from="+14105551234" to="+14105556789" action="URL_TO-HANGUP_TWIML">Say hello StackOverflow.</Sms>
</Response>
I am using twilio's call screening / whisper example. So basically when we use the Dial verb to call the number, we want to play a message when the receiver picks up the phone and give them the option to accept/reject the call. While the caller should keep hearing the ringing tone until the receiver makes a choice.
Most of this works as expected if we follow what's described in the call screening example https://www.twilio.com/docs/howto/callscreening
The problem is as soon as the receiver picks the phone, the caller can no longer hear the ringing tone, and the call goes silence until we have a response back from the receiver. This is a huge problem, because the caller will probably hang up once the ringing tone stops and there is no answer.
I have already had a look at the following two answers.
Twillio Call Screening silence on answer
Detecting when call had been answered using Dial verb
I personally don't want to go down the conference route.
In Number verb's documentation its clearly mentioned that the caller will continue to hear ringing tone.
https://www.twilio.com/docs/api/twiml/number#attributes-url
The 'url' attribute allows you to specify a url for a TwiML document that will run on the called party's end, after she answers, but before the parties are connected. You can use this TwiML to privately play or say information to the called party, or provide a chance to decline the phone call using Gather and Hangup. The current caller will continue to hear ringing while the TwiML document executes on the other end. TwiML documents executed in this manner are not allowed to contain the Dial verb.
The same issue happens with the Find Me Twimlet as well.
twilio.com/labs/twimlets/findme
Contacted Twilio support, you'll need to set "ringTone" attribute on like this:
<Dial answerOnBridge="true" ringTone="us">
I have tried that and it worked for me.