Bmore
Bmore

Reputation: 53

Call someone with Twilio then disconnect me and play a message to other person

I'm trying to create a button on a webpage (on my presonal PHP webserver) that should connect me (either call my cellphone or via the webclient), then call a number, I then want to have an options to either hangup the call, or just disconnect me but play an mp3 to the other person and then hangup.

I'm not sure how to go about it. I created a TwiML, but how do I connect that to the existing call? Or is there a different way to do it?

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Play>https://something-something.twil.io/assets/recording1.mp3</Play>
  <Hangup/>
</Response>

Thanks in advance.

Upvotes: 3

Views: 1206

Answers (2)

Sam
Sam

Reputation: 144

I think I get what you're trying to do. You have a list of people you're trying to call. The app will call them and connect you. If you hear an answering machine, you want to press a key then hangup and move on to the next call. But after you hang up, that first outbound call stays online and leaves a .mp3 message to that recipient?

I believe one solution would be creating a conference with a bot.

Your app makes an outbound call to you, to the bot and to the recipient and puts everyone into a conference room called "room-timestamp" where timestamp is the current time. The bot is a twilio number that listens for a Gather dtmf. If you press 1, it will play message 1 then hang up. But because this is a conference, you can hangup at anytime and move on to the next call. The bot could loop a few times and if no dtmf is detected, it will hang itself up. This is all made easier using the new Outbound conference API where you can pass it the conference name instead of conference SID :

https://www.twilio.com/docs/api/rest/participant#list-post

Edit:

Connect three numbers to a conference room :

$uniqueid = time();
$call = $client->account->calls->create($officeline,$twilionum,

array("url" => "http://yourdomain/conference.php?id=$uniqueid"));

$call = $client->account->calls->create($botline,$twilionum,

array("url" => "http://yourdomain/conference.php?id=$uniqueid"));

$call = $client->account->calls->create($customerline,$twilionum,

array("url" => "http://yourdomain/conference.php?id=$uniqueid"));

This will connect three numbers to a conference room:

  • $officeline (your number),
  • $botline (twilio phone # of a bot that responds to dtmf)
  • $customerline (the customer you're calling)

conference.php just returns a conferenceID for calls to connect to:

header('Content-Type: text/xml');

$confid = $_REQUEST['id'];
echo<<<XMLOUT
<?xml version="1.0" encoding="ISO-8859-1"?>

<Response>
<Dial>
<Conference statusCallbackEvent="leave" statusCallback="killconference.php">$confid</Conference>
</Dial>
</Response>

XMLOUT;

killconference.php is called so that the conference can be terminated when there's only one person left. Just make sure your bot hangs up after playing something.

killconference.php

 $theconference = $_REQUEST['ConferenceSid'];

 $participants = $client
    ->conferences($theconference)
    ->participants
    ->read();


 if (count($participants) == 1) {

   $conference = $client
    ->conferences($theconference)
    ->fetch();

   $conference->update(array(
        "Status" => "completed"
    ));

 }

your botline twilio number will be pointing to bot.php that responds to dtmf:

bot.php

   header('Content-Type: text/xml');

   $dtmf = isset($_REQUEST["Digits"]) ? $_REQUEST["Digits"] : "";
   $playmore = "";
   if ($dtmf == "1") {
       $playmore = "<Say>Hey I just wanted to leave you a message </Say><Hangup/>\n";
   }
   if ($dtmf == "2") {
       $playmore = "<Play>http://www.soundboard.com/mediafiles/22/224470-33a9f640-d998-45a3-b0c1-31c1687c2ae4.mp3</Play><Hangup/>\n";
   }


echo<<<XMLOUT
<?xml version="1.0" encoding="ISO-8859-1"?>
<Response>

$playmore
<Gather action="bot.php" numDigits="1" timeout="30">
</Gather>
<Hangup/>

</Response>

XMLOUT;

The bot will stay on the line for 30 seconds, if no dtmf is entered it hangs itself up. Press 1 to leave the customer a message, 2 for Leroy Jenkins

Upvotes: 2

philnash
philnash

Reputation: 73075

Twilio developer evangelist here.

This is an ideal use case for Answering Machine Detection. With Twilio's answer machine detection you can set it to Enabled or DetectMessageEnd which means that you can use Twilio to work out whether a machine has answered the call and wait until the message is over then play it a message. Otherwise you can connect the call to yourself.

With PHP, you can generate the call like this:

use Twilio\Rest\Client;

// Your Account Sid and Auth Token from twilio.com/console
$sid = "YOUR_ACCOUNT_SID";
$token = "YOUR_AUTH_TOKEN";
$client = new Client($sid, $token);

$call = $client->calls->create(
    "+14155551212", "+14158675309",
    array(
      "url" => "http://example.com/calls",
      "MachineDetection" => "DetectMessageEnd"
    )
);

Then, for your URL, you need to respond to the call depending on what the machine detected. You do that with the AnsweredBy parameter. Something like this, which dials your number if someone answers or speaks a message using <Say> if a machine answers:

<?php
  if ($_REQUEST['AnsweredBy'] == "human") {
    echo "<Response><Dial><Number>YOUR_NUMBER</Number></Dial></Response>";
  } else {
    echo "<Response><Say>Hello, this is my message</Say></Response>";
  }

Let me know if that helps at all.

Edit

Without Answering Machine Detection

Ok, to do this without Answering Machine Detection I recommend you build yourself a dialler using Twilio Client JS. There is a quickstart guide here, so I won't go through how that works here.

Once you have a dialler you can use it to initiate the phone calls. The issue is then moving the voicemail calls to play the message. I would build two buttons, one that hangs up as if you've completed the call successfully and the other that plays the message instead. The first button is a simple function call to Twilio.Device.activeConnection().disconnect().

The second one needs a couple of things. The idea is that it will make a call to your server to redirect the other call to a new set of TwiML.

First up, you need the SID of the call you created. You can get that from the connection object you receive in response to calling connect.

var connection = Twilio.Device.connect({ number: "+1234567890" });
var callSid = connection.parameters.CallSid;

When you want to hangup and play a message you need to send this to your server. This is the SID of the parent call though, and you need to get the child call, the other leg. So, on your server you need to use the REST API to get the other call, then redirect it.

use Twilio\Rest\Client;

// Your Account Sid and Auth Token from twilio.com/console
$sid = "YOUR_ACCOUNT_SID";
$token = "YOUR_AUTH_TOKEN";
$client = new Client($sid, $token);

$calls = $client->calls->read(
    array("ParentCallSid" => $_REQUEST['CallSid'])
);
// Loop over the list of calls, it should only have one call in it, and redirect the call to a URL that has the message TwiML
foreach ($calls as $call) {
    $call->update(array(
        "url" => "http://example.com/message.xml"
    ));
}

When you redirect the child call, the parent call will no longer be connected so it will hang up. The URL you redirect the child call to should contain the TwiML required to play the message to the machine using <Say> or <Play>.

Upvotes: 3

Related Questions