Dynamically set Twilio <Dial> timeLimit - twilio

I have an app which lets the users dial number(s) they want to add to a call. Each user is subjected to Balance they have in their account.
The dial is performed by using TwiML <Dial>
So as per my amount per minute rate i calculate the remaining balance in terms of seconds and set that as a timeLimit for <Dial>.
I want to do a simple thing like when the user is in a call and his call timeLimit is about to expire, I would want to charge them using my payment methods and If the charge was a success replenish the timeLimit for the same call.
Can this be done?

Twilio Developer Evangelist here.
There isn't a way to modify the timeLimit on a dial while the call is in progress. But I think I have a solution that could work for you.
Instead of dialing the number directly you could call into a conference with a timeLimit.
<Response>
<Dial timeLimit="30">
<Conference>YourCall</Conference>
</Dial>
</Response>
Then when their account is replenished you could modify the live call to redirect to a TwiML url that rejoins the conference call with the new timeLimit:
<?php
// Get the PHP helper library from twilio.com/docs/php/install
require_once('/path/to/twilio-php/Services/Twilio.php'); // Loads the library
// Your Account Sid and Auth Token from twilio.com/user/account
$sid = "{{ sid }}";
$token = "{{ auth_token }}";
$client = new Services_Twilio($sid, $token);
// Get an object from its sid. If you do not have a sid,
// check out the list resource examples on this page
$call = $client->account->calls->get("{{call sid}}");
$call->update(array(
"Url" => "http://youserver.com/conference.xml",
"Method" => "POST"
));
echo $call->to;

Probably easier is to use the https://www.twilio.com/docs/api/rest/change-call-state function of the Twilio REST API.The REST API is asynchronous.
In your situation you can do it as follows:
Dial timeLimit=[Max] (for an unlimited time, 4 hours is the max)
After a while, try to recharge the account.
On recharge success: Do nothing, the call persists.
On recharge failure: Disconnect by executing the change-call-state function of the Twilio REST API. You could even play an audio file or do other stuff before disconnect. For example ask the caller to verify its account because recharge failed or something.

Related

Conf call: Wait for first person to respond, then connect second person

Basic case: System will call person A. If person A picks up the phone it will call person B and the 2 will be connected.
I read several answers here such as https://stackoverflow.com/a/20976996/1907888 but it's still unclear.
Would the following work? It would call PERSON_A if person responds it will connect to conference then call PERSON_B and connect to same conference? Do I need to start the conference first?
$response = new VoiceResponse();
$dial = $response->dial('PERSON_A');
if($dial->conference('Room 1234')) {
$dial = $response->dial('PERSON_B');
$dial->conference('Room 1234');
}
Twilio developer evangelist here.
When you control calls with Twilio there are two mechanisms by which it works. There is the Twilio REST API which your application can use to make things happen, like start or change a call. Then there are webhooks, which are HTTP requests that Twilio makes to your application when things change in a call, like someone dialling your Twilio number, entering data on the phone, or an person answering an outbound call. You respond to webhooks with TwiML, a subset of XML, with instructions for what to do with the call next.
In this case, you want to place a call to person A to start with. For this, you will need the REST API to make that call. When person A answers the phone, Twilio will then make a webhook request to your application to find out what to do next. It is at this point that you can both call person B, again using the REST API, and place person A into a conference call, by responding with TwiML.
So, your initial outbound REST API call should look a bit like this:
use Twilio\Rest\Client;
// Find your Account Sid and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
$sid = getenv("TWILIO_ACCOUNT_SID");
$token = getenv("TWILIO_AUTH_TOKEN");
$twilio = new Client($sid, $token);
$call = $twilio->calls
->create($personANumber, // to
$yourTwilioNumber, // from
["url" => "http://example.com/conference.php"]
);
The URL you send when you place the call will be where Twilio sends the webhook request. So, in response to example.com/conference.php in this case, you will need to dial another person and respond with TwiML to direct person A into the conference call.
This time, instead of sending a URL, you can actually send TwiML in the REST API response. Something like this:
use Twilio\Rest\Client;
use Twilio\TwiML\VoiceResponse;
// Find your Account Sid and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
$sid = getenv("TWILIO_ACCOUNT_SID");
$token = getenv("TWILIO_AUTH_TOKEN");
$twilio = new Client($sid, $token);
$twiml = new VoiceResponse();
$dial = $twiml->dial();
$dial->conference("Conference Name");
$call = $twilio->calls
->create($personBNumber, // to
$yourTwilioNumber, // from
["twiml" => $twiml->toString()]
);
echo $twiml.toString();
In this case, I have used the same TwiML for both legs of the call, because they are both entering the same conference. You could respond with different TwiML based on what's happening.
Let me know if that helps at all.

Get response (TwiMl) Url to connect to conference call

The problem I'm trying to solve is having a Twilio phone number connect to a TwiMl, created within my PHP code, while making an outbound call with the end result having the caller and callee in the conference room together.
To set up the TwiMl I coded:
$response = '<Response>
<Play>%s</Play>
<Dial timeout=\'60\' callerId=\'%s\'>
<Conference startConferenceOnEnter="true" endConferenceOnExit="true">
conf-test
</Conference>
</Dial>
</Response>';
And to connect the callee to the call, I'm trying to use:
$client->account->calls->create(
+1XXXXXXXXXX, //To
+1XXXXXXXXXX, //From
array(
"url" => ???));
How do I get the URL from the above TwiMl into the url to connect further participants as well as the initial callee? Is this even possible, or am I forced to use a TwiMl bin and use that URL?
You can pass in TwiML using the below approach,
Pass TwiML with Call Initiation Requests
https://www.twilio.com/changelog/pass-twiml-call-initiation-requests

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.
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>.
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

Hold, unhold feature for Twilio call which is already running

I've a Twilio call already routed to an agent via TaskRouter(Task, Reservation is already created, Agent has accepted the call) and now an agent needs Hold, unhold feature for the same Twilio call.
Can someone please provide best practice for this?
Can we do this by en-queuing a call to Workflow?if yes then, how should we redirect same call to the same agent for Un-hold feature?
Please let me know if anyone has code snippet available. I'm using PHP for this
You can handle this one of a few ways but the basic process is:
First, provide Twilio some TwiML that places the call into "hold" then
when you're ready, use the CallSid of the call and the REST API to redirect the live call.
<?php
// Get the PHP helper library from twilio.com/docs/php/install
require_once('/path/to/twilio-php/Services/Twilio.php'); // Loads the library
// Your Account Sid and Auth Token from twilio.com/user/account
$sid = "YOUR_ACCOUNT_SID";
$token = "YOUR_AUTH_TOKEN";
$client = new Services_Twilio($sid, $token);
// Get an object from its sid. If you do not have a sid,
// check out the list resource examples on this page
$call = $client->account->calls->get("CALL_SID");
$call->update(array(
"Url" => "http://demo.twilio.com/docs/voice.xml",
"Method" => "POST"
));
echo $call->to;
To actually handle the "hold" you can use the <Enqueue> verb as you guessed, placing the call into a call queue. Then when you are ready, redirect that call back out of the queue to a new experience.
Or you can use <Play> and set the loop attribute to zero, which tell Twilio to loop audio indefinitely. And again, redirect the call when you are ready to remove the hold.

Twilio initiate outbound call that connects agent phone before dialing target number

I want to create a help desk web page in which an agent can click a link to initiate an outbound call to a target number. I understand how to use the Web Client to make that happen, but for an agent who doesn't have bandwidth to support VoIP, I'd like Twilio to call the agent's phone number then dial the target number.
The experience would be much like using Google Voice with Google Chat/Hangout client -- Google Voice calls your number/client, then initiates a call to the target.
Also, if both agent and target phone numbers are domestic landlines, would this scenario incur 2X the per minute landline fees?
I'm not looking for code necessarily, but rather an answer based on Twilio APIs and Twiml concepts.
Twilio evangelist here.
Sounds like you are looking to create "Click to Call". Here is some code from our docs that shows how to do this:
https://www.twilio.com/docs/howto/click-to-call
The basics are:
Use the REST API to initiate an outbound call. When that call is answered Twilio is going to make an HTTP request to some URL that you told about in your initial REST request. That URL's job is to return TwiML that contains the <Dial> verb which tells Twilio to dial the second phone number and bridge the two call legs together.
For domestic US calls, the total cost is going to be 4 cents / minute. 2 cents per each leg, since each leg is considered outbound. See Example 4 on this page:
https://www.twilio.com/help/faq/voice/how-much-am-i-charged-for-call-forwarding
Hope that helps.
Simple/Direct Twilio Calls Agent->Call
original url: https://www.twilio.com/docs/quickstart/php/rest/call-request#call-end-callback
First file loaded from browser:
use Twilio\Rest\Client;
// Step 2: Set our AccountSid and AuthToken from https://twilio.com/console
$AccountSid = "SID";
$AuthToken = "AuthTok";
// Step 3: Instantiate a new Twilio Rest Client
$client = new Client($AccountSid, $AuthToken);
try {
// Initiate a new outbound call
$call = $client->account->calls->create(
"+12125551111",// connect this number(Agent)
// that you've purchased or verified with Twilio.
"+12135554646",// caller id for call
// Set the URL Twilio will request when the call is answered.
array("url" => "http://example.com/call_them.php")
);
echo "Started call: " . $call->sid;
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
call_them.php:
<?php
header("content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
//inside dial.. actual number you want to reach
?>
<Response>
<Dial>+18185556363</Dial>
</Response>
Thank you for the great answer, #user3229526, it worked like a charm.
In order to unhardcode the number to call, just append the number you wish to call as a URL parameter in the Twilio Requst URL
array("url" => "http://example.com/call_them.php?number=1234567890")
And edit call_them.php to accept that parameter
<Response>
<Dial>
<?php echo '+1'. $_GET['number']; ?> // +1 for country code
</Dial>
</Response>

Resources