How to use Machine Detection feature

With the conversation API you are able to detect if your call is answered by a human or a machine. When your call is answered by a machine, you have the choice either to define an appropriate Dialplan or to hang up the call.

In this example, you will see how to use the machine detection feature of Conversation API.

The Case:
Consider that you have some potential customers that want to learn more about your company. They have provided their numbers, eg via a form, and asked you to communicate with them.

You can save cost and time from your company's resources if they are connected only to your customers that have already answered the call. With machine detection, you will avoid the cases where the calls are answered by machines. Furthermore, you can leave the appropriate message to their answering machine, to inform them that you have tried to communicate with them.

You can send the following request in order to make the outbound call:

You should add the following headers: authorization and content-type:

KEY

VALUE

Authorization

Bearer {access_token}

Content-Type

application/json

The example request is shown below:

curl -X POST \
  https://connect.routee.net/voice/conversation \
  -H 'Authorization: Bearer 5a3a0e18-40ea-4932-a902-4bde70974b33' \
  -H 'Content-Type: application/json' \
  -d '{
   "from": "theCompany",
   "to": {
      "phone": "+12012xxxxxx"
   },
   "dialPlan": {
      "verbs": [
         {
            "type": "SAY",
            "message": {
               "language": "en-US",
               "gender": "female",
               "text": "Hello from theCompany. We will connect you shortly to a company'\''s representative. Please hang on to your phone"
            }
         },
         {
            "type": "DIAL",
            "from": "+12012xxxxxx",
            "to": {
               "phone": "+12012xxxxxx"
            }
         }
      ]
   },
   "machineDetection": {
      "strategy": "Continue",
      "eventUrl": "http://your-event-service"
   }
}'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n   \"from\": \"theCompany\",\n   \"to\": {\n      \"phone\": \"+12012xxxxxx\"\n   },\n   \"dialPlan\": {\n      \"verbs\": [\n         {\n            \"type\": \"SAY\",\n            \"message\": {\n               \"language\": \"en-US\",\n               \"gender\": \"female\",\n               \"text\": \"Hello from theCompany. We will connect you shortly to a company's representative. Please hang on to your phone\"\n            }\n         },\n         {\n            \"type\": \"DIAL\",\n            \"from\": \"+12012xxxxxx\",\n            \"to\": {\n               \"phone\": \"+12012xxxxxx\"\n            }\n         }\n      ]\n   },\n   \"machineDetection\": {\n      \"strategy\": \"Continue\",\n      \"eventUrl\": \"http://your-event-service\"\n   }\n}");
Request request = new Request.Builder()
  .url("https://connect.routee.net/voice/conversation")
  .post(body)
  .addHeader("Authorization", "Bearer 5a3a0e18-40ea-4932-a902-4bde70974b33")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var client = new RestClient("https://connect.routee.net/voice/conversation");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Bearer 5a3a0e18-40ea-4932-a902-4bde70974b33");
request.AddParameter("undefined", "{\n   \"from\": \"theCompany\",\n   \"to\": {\n      \"phone\": \"+12012xxxxxx\"\n   },\n   \"dialPlan\": {\n      \"verbs\": [\n         {\n            \"type\": \"SAY\",\n            \"message\": {\n               \"language\": \"en-US\",\n               \"gender\": \"female\",\n               \"text\": \"Hello from theCompany. We will connect you shortly to a company's representative. Please hang on to your phone\"\n            }\n         },\n         {\n            \"type\": \"DIAL\",\n            \"from\": \"+12012xxxxxx\",\n            \"to\": {\n               \"phone\": \"+12012xxxxxx\"\n            }\n         }\n      ]\n   },\n   \"machineDetection\": {\n      \"strategy\": \"Continue\",\n      \"eventUrl\": \"http://your-event-service\"\n   }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://connect.routee.net/voice/conversation",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\n   \"from\": \"theCompany\",\n   \"to\": {\n      \"phone\": \"+12012xxxxxx\"\n   },\n   \"dialPlan\": {\n      \"verbs\": [\n         {\n            \"type\": \"SAY\",\n            \"message\": {\n               \"language\": \"en-US\",\n               \"gender\": \"female\",\n               \"text\": \"Hello from theCompany. We will connect you shortly to a company's representative. Please hang on to your phone\"\n            }\n         },\n         {\n            \"type\": \"DIAL\",\n            \"from\": \"+12012xxxxxx\",\n            \"to\": {\n               \"phone\": \"+12012xxxxxx\"\n            }\n         }\n      ]\n   },\n   \"machineDetection\": {\n      \"strategy\": \"Continue\",\n      \"eventUrl\": \"http://your-event-service\"\n   }\n}",
  CURLOPT_HTTPHEADER => array(
    "Authorization: Bearer 5a3a0e18-40ea-4932-a902-4bde70974b33",
    "Content-Type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPConnection("connect,routee,net")

payload = "{\n   \"from\": \"theCompany\",\n   \"to\": {\n      \"phone\": \"+12012xxxxxx\"\n   },\n   \"dialPlan\": {\n      \"verbs\": [\n         {\n            \"type\": \"SAY\",\n            \"message\": {\n               \"language\": \"en-US\",\n               \"gender\": \"female\",\n               \"text\": \"Hello from theCompany. We will connect you shortly to a company's representative. Please hang on to your phone\"\n            }\n         },\n         {\n            \"type\": \"DIAL\",\n            \"from\": \"+12012xxxxxx\",\n            \"to\": {\n               \"phone\": \"+12012xxxxxx\"\n            }\n         }\n      ]\n   },\n   \"machineDetection\": {\n      \"strategy\": \"Continue\",\n      \"eventUrl\": \"http://your-event-service\"\n   }\n}"

headers = {
    'Authorization': "Bearer 5a3a0e18-40ea-4932-a902-4bde70974b33",
    'Content-Type': "application/json"
    }

conn.request("POST", "voice,conversation", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://connect.routee.net/voice/conversation")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer 5a3a0e18-40ea-4932-a902-4bde70974b33'
request["Content-Type"] = 'application/json'
request.body = "{\n   \"from\": \"theCompany\",\n   \"to\": {\n      \"phone\": \"+12012xxxxxx\"\n   },\n   \"dialPlan\": {\n      \"verbs\": [\n         {\n            \"type\": \"SAY\",\n            \"message\": {\n               \"language\": \"en-US\",\n               \"gender\": \"female\",\n               \"text\": \"Hello from theCompany. We will connect you shortly to a company's representative. Please hang on to your phone\"\n            }\n         },\n         {\n            \"type\": \"DIAL\",\n            \"from\": \"+12012xxxxxx\",\n            \"to\": {\n               \"phone\": \"+12012xxxxxx\"\n            }\n         }\n      ]\n   },\n   \"machineDetection\": {\n      \"strategy\": \"Continue\",\n      \"eventUrl\": \"http://your-event-service\"\n   }\n}"

response = http.request(request)
puts response.read_body
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://connect.routee.net/voice/conversation",
  "method": "POST",
  "headers": {
    "Authorization": "Bearer 5a3a0e18-40ea-4932-a902-4bde70974b33",
    "Content-Type": "application/json"
  },
  "processData": false,
  "data": "{\n   \"from\": \"theCompany\",\n   \"to\": {\n      \"phone\": \"+12012xxxxxx\"\n   },\n   \"dialPlan\": {\n      \"verbs\": [\n         {\n            \"type\": \"SAY\",\n            \"message\": {\n               \"language\": \"en-US\",\n               \"gender\": \"female\",\n               \"text\": \"Hello from theCompany. We will connect you shortly to a company's representative. Please hang on to your phone\"\n            }\n         },\n         {\n            \"type\": \"DIAL\",\n            \"from\": \"+12012xxxxxx\",\n            \"to\": {\n               \"phone\": \"+12012xxxxxx\"\n            }\n         }\n      ]\n   },\n   \"machineDetection\": {\n      \"strategy\": \"Continue\",\n      \"eventUrl\": \"http://your-event-service\"\n   }\n}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"Authorization": @"Bearer 5a3a0e18-40ea-4932-a902-4bde70974b33",
                           @"Content-Type": @"application/json" };
NSDictionary *parameters = @{ @"from": @"theCompany",
                              @"to": @{ @"phone": @"+12012xxxxxx" },
                              @"dialPlan": @{ @"verbs": @[ @{ @"type": @"SAY", @"message": @{ @"language": @"en-US", @"gender": @"female", @"text": @"Hello from theCompany. We will connect you shortly to a company's representative. Please hang on to your phone" } }, @{ @"type": @"DIAL", @"from": @"+12012xxxxxx", @"to": @{ @"phone": @"+12012xxxxxx" } } ] },
                              @"machineDetection": @{ @"strategy": @"Continue", @"eventUrl": @"http://your-event-service" } };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://connect.routee.net/voice/conversation"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];

Since the "machineDetection" object is present in your request, Routee will try to detect, in 1-2 sec, if the call is answered by a human or a machine.
When the call is answered, the "SAY" Verb (text-to-speech message) will start to play.

If a human is detected, then the flow won't change. After the text-to-speech message, the "DIAL" verb will be executed and your potential customer will be connected to one of your representatives ("to.phone" inside the "DIAL" verb).

If a machine is detected, the execution of the diaplan will be interrupted and a different dialplan will be executed.

Your callback service at "eventUrl" will receive a POST HTTP request with the following request body:

{
    "messageId": "d8b8c124-ddab-4342-ba6c-f313048ffa35",
    "conversationTrackingId": "c0310d52-6842-448c-8cb7-2ba034a62178",
    "detectMachineStatus": "MACHINE"
}

In response to the above request, Routee awaits the new valid dialplan. The dialplan can be the following:

{
  "verbs":[  
     {  
        "type":"SAY",
        "message":{  
           "language":"en-US",
           "gender":"male",
           "text":"Hello. Thank you for your interest in theCompany. A representative of our company tried to connect with you. We will try again tomorrow, or you can make a new communication request. Have a nice day"
        }
     }
  ]
}

Instead of leaving the above message to the answering machine, you are able to hangup the call, once a machine is detected. You can do this by defining as "Hangup" the "machineDetection.strategy".