javascriptc#twiliotwilio-apitwilio-twiml

Automatic Machine Detection workflow is different when used under <Dial><Number> vs when used in an outbound call using API


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:

  1. Start a call from browser to a phone number:
  2. When the called party picks up I want AMD to work, then:

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:

<Response>
    <Say language="en-US">Very long message stating that continuing the call indicates your consent to be recorded</Say>
</Response>

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.


Solution

  • So, I've turned everything over. List of problems and their respective solutions:

    1. Can't control calls created with <Dial><Number> from AMD webhooks:
    1. Can't connect the call from above to Voice JS SDK device in browser (calls ended with 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:

    1. I'll be charged more for it. But it works.
    2. The ringing sound was replaced by weird music:
    1. If the callee hangs up before ever connecting to the conference, the caller will not know about it:
    var conference = (await ConferenceResource.ReadAsync(friendlyName: conferenceName)).FirstOrDefault();
    if (conference != null)
        await ConferenceResource.UpdateAsync(conference.Sid, status: ConferenceResource.UpdateStatusEnum.Completed);