I cannot control the flow of a call created using Dial
keyword inside of amdStatusCallback
webhook I provide in the Number
tag. I'm using C# Twilio library and Voice JavaScript SDK. Apologies for the long one in advance.
Use case:
2.1. If the result is human
or unknown
, a message should be said, stating that continuing the call indicates the called party's consent to be recorded. Then it should connect the caller in browser and the callee.
2.2. machine-start
: no point in asking for consent, so it should connect immediately for the caller to leave a message.
2.3. fax
: just disconnect. I'll let the caller know it's a fax.
The perfect scenario would be if there was asyncAMD
flag in Number
keyword like it exists in CallResource.CreateAsync
, and the call would go the 2.1 route by default and change after, but for some reason there's no such thing. I can live with that though, it's not the main issue.
Here's what happens:
<Response>
<Dial callerId="{myTwilioPhoneNumber}" record="record-from-answer" answerOnBridge="true" ringTone="us">
<Number machineDetection="Enable" amdStatusCallbackMethod="GET" amdStatusCallback="{amdUrl}" machineDetectionTimeout="5">*phone-number*</Number>
</Dial>
</Response>
Here's what I tried to do in amdUrl
:
Say
TwiML instruction. But it is completely ignored.<Response>
<Say language="en-US">Very long message stating that continuing the call indicates your consent to be recorded</Say>
</Response>
CallResource.UpdateAsync
. Both using twiMl
parameter and as a response to another webhook I provided in the url
parameter. It worked BUT the call gets disconnected from the twilio device in browser.
I tried to add <Dial><Client>{voiceSdkDeviceId}</Client></Dial>
or <Dial><Client><Identity>{voiceSdkDeviceId}</Identity></Client></Dial>
after the Say
to at least somehow connect them back but it also didn't work. I see the child call created in the logs but it ends with No Answer
. I double-checked the device id multiple times, I call device.register()
in my JS, I see the registered
event fired.When I created outbound calls using CallResourse.CreateAsync
for another task, I enabled AMD there as well, and it worked just as described in this tutorial. It's a very unpleasant surprise that it doesn't work like this using Dial
.
Before I enabled AMD I had a webhook that responded with the same Say
instruction. I provided url to it in the Number
tag and had the message said while hearing ringing in browser and then got connected. But if the call goes to voicemail, the consent message may easily be longer than the voicemail's greeting and still be playing after the beep. So the caller would have no idea it went to voicemail, and the callee would receive a message that starts in the middle of the consent message followed by confused silence of the caller. I'd really like to avoid it. Please help.
So, I've turned everything over. List of problems and their respective solutions:
<Dial><Number>
from AMD webhooks:CallResource.CreateAsync()
), enable AMD there and provide the same webhook urls. I also was able to enable async AMD this way.No Answer
):So, instead of <Dial><Number>
on one side and <Dial><Client>
on the other I have <Dial><Conference>
on both sides.
Problems with the new approach:
waitUrl
parameter in future.statusCallback
url parameter to the CreateAsync
, provide the conference name there. If a request with a completed
status is received, end the conference through API:var conference = (await ConferenceResource.ReadAsync(friendlyName: conferenceName)).FirstOrDefault();
if (conference != null)
await ConferenceResource.UpdateAsync(conference.Sid, status: ConferenceResource.UpdateStatusEnum.Completed);