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

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.

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

Twilio,How to unhold the call

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

How can I handle reaching voicemail using Twilio's <dial> verb

I know that on making a call Twilio can detect an answering machine, and react differently.
However if I use the <dial> verb, there's no obvious place to add this feature, even though it's essentially the same thing.
My intended flow is:
Customer enters their phone number
Twilio calls Customer and plays a voice message
Twilio dials an agent number, likely a mobile
If the Agent picks up, connect the customer to the agent
If the Agent busies the call or does not answer, call will likely go to Agent's voicemail.
Terminate call to Agent
Record voicemail from Customer
Email voicemail to Agent
From the official docs on the <Dial> verb (emphasis mine):
This is the simplest case for Dial. Twilio will dial 415-123-4567. If someone answers, Twilio will connect the caller to the called party. If the caller hangs up, the Twilio session ends. If the line is busy, if there is no answer, or if the called party hangs up, <Dial> exits and the <Say> verb is executed for the caller before the call flow ends.
<?xml version="1.0" encoding="UTF-8"?>
<!-- page located at http://example.com/simple_dial.xml -->
<Response>
<Dial>415-123-4567</Dial>
<Say>Goodbye</Say>
</Response>
Placing a <Record> verb after the <Say> verb sounds like what you are looking for. You can change the timeout from the default value of 30s like this:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial timeout="9001">415-123-4567</Dial>
<Say>Please leave a message</Say>
<Record action="/process_new_voicemail" />
</Response>
I am sure this is late, but hopefully it helps some one out. It sounds like you may just need to screen the call.
Basically, you can ask the "agent" that you dialed to accept the call and hang up if you do not receive input.
I am not sure what language you are using, but here is a great php/Laravel tutorial to explain:
https://www.twilio.com/docs/tutorials/walkthrough/ivr-screening/php/laravel
The key part is here:
$dialCommand = $response->dial(
['action' => route('agent-voicemail', ['agent' => $agent->id], false),
'method' => 'POST']
);
$dialCommand->number(
$numberToDial,
['url' => route('screen-call', [], false)]
);
Notice that the dial command uses the 'action' to specify a location that is sent a POST request should the call end i.e POST to /agent-voicemail.
Then, the number is dialed along with a 'url' parameter this is the location that will be requested after the agent has picked up but before connecting the two parties.
The /screen-call route then asks the agent to accept the call, if no input is received it hangs up and will make a POST request to the initial setup /agent-voicemail route.
This method will handle your scenario because if it goes to voicemail no input will be received and the call will end.

Gather after caller hangs up

Is it possible to play a recording and then gather digits from the receiver of a call after a call ends (the caller hangs up)?
Similar to: https://www.twilio.com/docs/api/twiml/gather just that it's the receiver and not the caller who ask and that it happens when the call ends.
Thanks!
Morten
Twilio Evangelist here. Thanks for the clarification.
You can do this, but you need to use a conference call. Imagine Alice is calling Jack. Normally, you would use TwiML like this:
<Response>
<Dial>
+15551234567
</Dial>
</Response>
What you need to do is dial Alice into a conference call:
<Response>
<Dial>
<Conference>Alice and Jack</Conference>
</Dial>
</Response>
Then you need to make an outbound API call to dial Jack into the conference. In Ruby this would be something like this:
require 'twilio-ruby'
client = Twilio::REST::Client.new "account-sid", "account-token"
cient.account.calls.create to: "+15551234567", from: "some-twilio-number", url: "Your app URL"
This will use the same TwiML as above to join Jack into the conference. You'll need to look at the details for a <Conference> to avoid/select holding music, and to prevent the conference ending when Alice hangs up. Something like this:
<Response>
<Dial>
<Conference endConferenceOnExit="false" beep="false" waitUrl="http://some-twilml-no-hold-music">
Alice and Jack
</Conference>
</Dial>
</Response>
Now, you will also need to use the callbacks for when the call ends (you should also set this on your Twilio Number in the Dashboard, or through the API.
Now, you can take the Call SID of whoever remains in the conference call (you'll get this when you receive the initial request for the TwiML), and use the REST API to modify that call, redirecting them to new TwiML:
require 'twilio-ruby'
client = Twilio::REST::Client.new "account-sid", "account-token"
call = client.account.calls.get "my-call-sid"
call.redirect_to url: "http://new-url-of-twiml", method: "POST"
This allows you to redirect the call to TwiML such as:
<Response>
<Gather action="http://some-url-to-send-digits-to">
<Play>http://some-mp3-or-wav-file</Play>
</Gather>
</Response>
Twilio will play the MP3/WAV file, while listening for any key (DTMF) tones the user enters. You'll need to configure your <Gather> depending on how many keys you want to listen for etc. But that's very straight forward.
Hope this helps!

Resources