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.
Related
Is there any way to change what events trigger the status callback? Normally you can use statusCallbackEvent but I can't seem to find a way to make this work for the Voice SDK's leg of the call. It works fine on the call leg of the outbound participant, but not the Voice SDK's call leg. I only get completed status event for this leg (and I also can get ringing from the called action url).
Things I tried without success:
Updating the call using the REST api to set statusCallbackEvent to initiated ringing answered completed when the outbound call starts
Setting statusCallbackEvent as an outbound parameter on the Voice SDK's token (in PHP you can set custom parameters using $clientToken->allowClientOutgoing(...) but it seems normal parameters cannot be modified)
I really wish you could set this on the TwiML Application so that any numbers calling out with that application set will just automatically use your set events. That or let me set the parameters on the client's token.
One way to fix this is just to poll for the information but that is an ugly hack and isn't real time.
Twilio developer evangelist here.
I don't think you can do what you're asking for here, but for good reason.
When you are placing the call from the Voice SDK, that call leg is then between the application and Twilio. You know the call was "initiated", because you started it. There is no "ringing" because Twilio is not a phone and won't ring. You know it is "answered" because a request is made to your voice URL defined by the TwiML app. And finally, you do get the "completed" event.
As you say, you do get the events for the outbound leg of the call from Twilio to another phone number.
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.
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.
I want to stop the ringing sound when anyone call on my twilio number or is there any way I can make the incoming call to get retrieved automatically,I mean when any call comes to my twilio number it just instantly get received.I don't the caller to hear the ringing sound.
Thanks,
Twilio developer evangelist here.
As far as I'm aware, the ringing is the least possible, but it is also not under our control. As you can imagine, when you dial a Twilio number the call has to go through several networks before it reaches Twilio, Twilio then has to make an HTTP request to your application, retrieve the TwiML required to answer the phone and then respond to the call. All of that can't happen instantly so the phone will ring.
Does that make sense?