Twilio,How to unhold the call - twilio

I need help in uhholding the call.I have tried two method.
1. use enqueue verb when i press the hold button I have user the update call method
<Response>
<Enqueue waitUrl="urltoplaytheholdmusic">1111</Enqueue>
</Response>
(and when I press the unhold button I used the same update method and used.)
<Response>
<Queue >1111</Queue>
</Response>
but when used the queue verb call gets disconnected.
2. So I tried an other way to just play the music when I press the hold button.
<Response><Say>We are putting you on hold Please wait!</Say><Play loop="0">https://api.twilio.com/cowbell.mp3</Play></Response>
Now I don't know what to do to unhold the call.
question:reference question
this all i am doing.
when I make call I have used the js liberay for that and used this function
function call(dial_number, from_phone) {
params = {
"to_phone": to_phone,
"from_phone": from_phone,
"from_id": current_user_id,
"to_id": user_id
};
connection = Twilio.Device.connect(params);
connection._onAnswer = function(conn) {
console.log(conn.callsid);
/*get parentcall sid when make the call*/
Sid = {
parent_callSid: conn.callsid,
type: 'outgoing'
};
};
}
And to put the call on hold I have used this line of code
function holdaction() {
jQuery.ajax({
url: 'url',
type: 'POST',
data: 'sid=' + parentSid + '&admin_no=' + encodeURIComponent(jQuery('#twilio_from_number').val()) + '&action=' + hold_action,
dataType: 'json',
success: function(data) {}
});
}
This gets the callsid by using the parentcallsid from my db call this functionto put the call on hold
function update_call($callSid, $action, $admin_no = '') {
$rr = array(
"url" => "holdactionurl?type=".$action.
'&admin_no='.$admin_no,
"method" => "POST"
);
$call = $this->client->calls($callSid)->update($rr);
return $call->to;
}
And on holdactionurl I have used this-
<Response>
<Enqueue waitUrl="wait_url">first_queue</Enqueue>
</Response>
And on wait_url I have used this-
<Response>
<Say>You are on hold </Say>
<Redirect>wait_url</Redirect>
</Response>
And I for unholding the call I (means the same number which have put the call on hold) used the same holdaction method with different parameter and the xml code for that is-
<Response>
<Dial>
<Queue>first_queue1</Queue>
</Dial>
</Response>
I know I m doing this wrong but I can't figure out the right way so I will much appreciate If you can help me figure it out what I m doing wrong

Twilio developer evangelist here.
Thanks for answering my questions in the comments. I think I know where we are right now.
As you say, you have followed my answer here. In this, the caller gets put into a queue unique to the agent that they called. The agent, meanwhile, is redirected to a loop (in my example it just said "You have a caller on hold" over and over).
In your question here, you talk about redirecting the caller that has been queued to the following TwiML:
<Response>
<Queue>1111</Queue>
</Response>
The <Queue> verb is used to dial from people outside of the queue to the next person in the queue. So in this case, you're trying to get the queued caller to dial themselves, which can't work.
Instead, you need to do the redirect on the agent, directing them out of the loop they've been placed into and calling the person out of the queue.
So, you don't dequeue the caller by moving them from <Enqueue> to <Queue>, you dequeue a caller by getting someone else to dial <Queue>
Let me know if that helps at all.
Update
From your code I believe this is what's happening.
In your server update_call function you are moving the outgoing call into a queue, effectively putting your agent on hold. I assume this means the other end is losing the connection and this is your problem. If that's not the case, just let me know.
Anyway, what we need to do is find the child call and push that off to a queue. I would split up your update_call function to perform two different things. Firstly, get the childCallSid and redirect it to the holdactionurl.
function holdChildCall($parentCallSid, $action, $admin_no = '') {
$childCalls = $this->client->calls->read(array("ParentCallSid" => $parentCallSid));
$childCallSid = $childCalls[0]->sid;
$rr = array(
"url" => "holdactionurl?type=".$action.
'&admin_no='.$admin_no,
"method" => "POST"
);
$call = $this->client->calls($childCallSid)->update($rr);
return $call->to;
}
If you try this now then the called end, the child call, will get redirected to your Queue but your caller, your agent, the parent call, will get cut off. We need to stop that happening which we can do by adjusting the initial TwiML. Your comment below says that currently your TwiML looks like this:
<Response>
<Dial callerId="callerid">
<Number statusCallbackEvent="initiated ringing answered completed" statusCallback="urltohadlestatus">user_number</Number>
</Dial>
</Response>
You need to update the <Dial> here to give it more TwiML to drop into once the child call is dropped. Add a redirect after the <Dial>.
<Response>
<Dial callerId="callerid">
<Number statusCallbackEvent="initiated ringing answered completed" statusCallback="urltohadlestatus">user_number</Number>
</Dial>
<Redirect>/admin_on_hold</Redirect>
</Response>
You can call the url whatever you want, I've called it /admin_on_hold for now. You need some TwiML at that URL that keeps the caller on the line too. You could use something similar to your existing hold notification:
<Response>
<Say>You have a caller on hold. </Say>
<Pause length="5"></Pause>
<Redirect>wait_url</Redirect>
</Response>
Now when you press hold your child call, the called person, will be queued up and wait with a hold message. And your agent, the caller, the parent call, will also hear a message to say that they are keeping a caller on hold.
Now we need to reconnect the two callers. We do this by redirecting the agent call, the parent call, to the <Queue>, this will pop the child call off the queue and reconnect them. We can actually use the existing update_call function for this. Make sure you are passing the parent call SID and the $action that produces the <Queue> TwiML from holdactionurl with the same queue name that you used to <Enqueue> the caller in the first place.
function update_call($parentCallSid, $action, $admin_no = '') {
$rr = array(
"url" => "holdactionurl?type=".$action.
'&admin_no='.$admin_no,
"method" => "POST"
);
$call = $this->client->calls($parentCallSid)->update($rr);
return $call->to;
}
Does this make sense? You need to make sure you redirect the child call to TwiML that uses <Enqueue>, add the extra <Redirect> after <Dial> so that your agent doesn't hang up and then when you unhold redirect the agent call to the TwiML that uses <Queue>.

Related

Twilio call forwarding one after another - how to disconnect if person picks up the call

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say> Connecting call to Pinto </Say>
<Dial record ="record-from-answer" timeout="10" hangupOnStar ="true">
<Number>XXXXXXXX</Number>
</Dial>
<Say> Pinto is not picking up the call, now connecting call to Management </Say>
<Dial record ="record-from-answer" timeout="10" hangupOnStar ="true">
<Number>XXXXXXXX</Number>
</Dial>
<Say> No one is picking up right now. Please text us at +12022171828 </Say>
</Response>
Above is the call forwarding flow for one after another.
What I'm looking here is,
If 1st user attended the call, then it should not initiate the call to 2nd number and also it should not say text message which is at last line
If 1st user disconnected, then redirect call to 2nd number - if 2nd number not picking up the call then it should say text message which is at last line
if 1st user disconnected, then redirect call to 2nd number - if 2nd number picked up the call then it should not say text message which is at last line
Also I want to Implement Transcribe & Transcribe call back by using TwiML.
So, please help me like how we need to do with that?
To carry out this flow, you cannot perform the entire thing in one TwiML response. Instead, you will need to provide the <Dial> element with URL in the action attribute so that once the first call completes, Twilio makes a webhook to find out what to do next.
So, your first TwiML response should look like:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say> Connecting call to Pinto </Say>
<Dial record="record-from-answer" timeout="10" hangupOnStar="true" action="/complete">
<Number>XXXXXXXX</Number>
</Dial>
</Response>
Above I've added action="/complete" to the <Dial> and this means we need an application to be able to respond to HTTP requests to /complete as well. We also need this to be an application and not a static response as we need to work out whether the call was answered or not and decide on what to do next and what TwiML to respond with.
We can do this because one of the parameters that Twilio sends to the action URL is DialCallStatus. This parameter can be "completed", "busy", "no-answer", "failed" or "canceled" and this tells you what happened in that first call.
So, in your case, you will want to check the DialCallStatus and if it is "completed" then you do not need to return the next <Say> and <Dial>. If, however, the DialCallStatus is one of the other statuses, you do want to return the next <Say> and <Dial>. That <Dial> should include another action URL that makes the same choice at the end of the second <Dial>.
I'm not sure what language you are building with, but a pseudo-code idea of this would look like this:
post '/complete' do
if params["DialCallStatus"] != "completed"
return "<Response><Hangup/></Response>"
else
return "<Response><Say>Pinto is not picking up the call, now connecting call to Management</Say><Dial ....></Response>"
end
end

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

Twilio how to disconnect the call when an agent transferred the call to another agent

E.g.->If agent A makes a call to a user and now agent A transfers the call the agent B now how can i disconnect agent A from the call and let user and B still on the call.
1.When I make the call I use this TwiML.
<Response>
<Dial callerId="id">
<Number statusCallback="statusCallbackurl" statusCallbackMethod="POST">ag1_num</Number>
</Dial>
<Redirect>music_url</Redirect>
</Response>
2.I am transferring the call by using update method and dialing the other agent by using this code-
function transfer_call($Sid,&ag2_num){
$childCalls = $this->client->calls->read(array("ParentCallSid" => $Sid));
$childSid = $childCalls[0]->sid;
$rr = array(
"url" => "tr_url".$ag2_num,
"method" => "POST"
);
$call = $this->client->calls($childSid)->update($rr);
return $call->to;
}
and on the tr_url I used TwiML-
<Response>
<Dial>ag2_num</Dial>
<Redirect>disconnectedcallurl-usingemptyqueue(todisconnectthefirstagent)</Redirect>
</Response>
and to disconnect the call I called this method and pass the callsid-
function disconnect_call($callsid){
$rr = array("status" => "completed");
$call = $this->client->calls($callsid)->update($rr);
echo $call->direction;
}
I use the call sid to disconnect the agent from the call and it disconnect the whole call.
Twilio developer evangelist here.
In the comments you say you are using the disconnect_call method straight after the transfer and you are using the same sid for both. This means that you transfer the call, which hangs up from the first agent, but then you instantly hang up the transferred call too, so it never calls the second agent.
You shouldn't need to disconnect the first agent, transferring the call away from them will do that. Remove your call to disconnect_child and try again.

Twilio, How to transfer a in-progress call to another number

How to transfer a in-progress call to another number.The concept that I m using is to use the update method when the call is in in-progress and dial the number that I wanted To connect and It is working but the connection with the first caller is breaking/
Code for the process of transferring call-
1.process for dialing call-
<Response>
<Dial callerId="callerid">
<Number statusCallbackEvent="initiated ringing answered completed" statusCallback="urltohadlestatus">user_number</Number>
</Dial>
</Response>
2. process to process to transfer the call-
I have used the update method to transfer the call.
function update_call1($CallSid, $admin_no) {
$rr = array(
"url" => "trurl?admin_no=".$admin_no,
"method" => "POST"
);
$call = $this->client->calls($CallSid)->update($rr);
return $call->to;
}
and used this TwiML
<Response>
<Dial>admin_number_call_to_be_transfered</Dial>
</Response>
what this does is transfer the call but when admin receives it,It disconnects the call.
And what I need like when jack make call to jenny and now jack want to transfer the call to jhonny and when call is transferred to jhonny, jack shound be disconnected from the call.
Twilio developer evangelist here.
You have two options here. Once the call is transferred away, the other caller will drop if it has nothing else to do. There are two ways you can achieve this.
You can either put the callers in a <Conference>. Then when the caller is transferred the other call remains in the conference room. There is a good tutorial on warm transfers using this technique, which might help.
Alternatively, if the side of the call that is dropping out right now is the one that generated the call from the Twilio REST API you can add more TwiML below the <Dial> verb to have the call continue. For example:
<Response>
<Dial>OTHER_NUMBER</Dial>
<Say loop="0">You are still on the call.</Say>
</Response>
Will just keep saying "You are still on the call" once the other end is transferred away.
You can also achieve this with the action attribute for <Dial>. Using the action attribute means that Twilio will make a webhook request to the URL you specify and use the TwiML from that response to carry on the call.

Resources