I am using Twilio to call my customers from my Twilio client and want to put the user on hold whenever is needed. For that i am calling RESTAPI whenever user clicks on the "Hold" Button.
But after calling the method call is getting disconnected for My Twilio client and playing Hold sound for my customer. Can you please suggest something for this. Both the below approaches are not working
var response = new VoiceResponse();
var dial = new Dial();
dial.Conference("Customer Waiting Room", beep: Conference.BeepEnum.False);
response.Append(dial);
var call = Twilio.Rest.Api.V2010.Account.CallResource.Read(parentCallSid: callSid).ToList();
Twilio.Rest.Api.V2010.Account.CallResource.Update(new Twilio.Rest.Api.V2010.Account.UpdateCallOptions(call[0].Sid) { Twiml = response.ToString() });
return Content(response.ToString(), "application/xml");
Alternative:
var response = new VoiceResponse();
response.Say("You have a caller on hold.");
var call = Twilio.Rest.Api.V2010.Account.CallResource.Read(parentCallSid: callSid).ToList();
response.Enqueue("admin");
Twilio.Rest.Api.V2010.Account.CallResource.Update(new Twilio.Rest.Api.V2010.Account.UpdateCallOptions(call[0].ParentCallSid) { Twiml = response.ToString() });
Twilio developer evangelist here.
You have a direct call setup between your agent and you customer. When you move your customer call away from that, then your agent call will move on to the next TwiML instruction. If there are no further TwiML instructions available for your agent, then they will get disconnected.
To overcome this, you need to consider what you want your agent to do while your customer is on hold. It might be better, for example, to have your call take place in a conference. That way, when you put your customer on hold, the agent can remain in the conference.
Otherwise, you should provide further TwiML instructions after your agent's <Dial> so that they continue the call after the customer leg goes away.
Related
I'm trying to create an interactive dashboard that shows Twilio calls with the ability to listen to any ongoing calls. Is it possible? And what is the best approach I should take?
I saw two methods on the documentation which are Twiml Voice: and Twiml Voice: . Conference doesn't suit with my scenario because incoming calls are not ringing. And I couldn't find a way to listen to voice Streams on the documentation.
Note: Currently inbound calls are handled by Twilio function and WebSocket and outbound calls are handled by Twilio JavaScript SDK.
Thanks in advance.
If you want to listen to a live Voicecall you could try the Stream as IObert suggests. Or, you must use the Conference feature and add yourself as a "Coach." Don't be put off by the name Conference. Think of it as a Voicecall with many more helpful features. You can create a conference from an outbound call like this:
string accountSid = "ACxxxxxx";
string authToken = "xxxxx";
TwilioClient.Init(accountSid, authToken);
var voiceresponse = new VoiceResponse();
var say = new Say("Setting up your conference.");
var dialConference = new Dial();
dialConference.Conference(
name: "Your Conference"
startConferenceOnEnter: true,
endConferenceOnExit: true
);
voiceresponse.Append(say);
voiceresponse.Append(dialConference);
var twiml = voiceresponse.ToString();
var call = CallResource.Create(
twiml: new Twilio.Types.Twiml(twiml),
to: new Twilio.Types.PhoneNumber("E164 Number to Dial"),
from: new Twilio.Types.PhoneNumber("E164 Your Twilio Number")
);
Then once you have a conference started, you can add the second call from either an inbound or outbound call. With an inbound call, use Twiml to send the call to the conference. With an outbound call, use the REST API to add a Conference Participant.
From the client side, using the Twilio Javascript Client, you would then connect your device to the Conference with the correct Conference Twiml parameters which is explained here:
https://www.twilio.com/docs/voice/sdks/javascript/twiliodevice#deviceconnectconnectoptions
const device = new Device(token);
let call = await device.connect({
params: {
To: 'Your Conference'
}
});
I use a slightly different method...I use a button on the client that when you click it makes an outbound call to the "coach" using the Conference Participant REST API. The coach answers and is added with mute = true. The "coach" uses the Twilio Client for WebRTC but the same process will work with a "regular" phone line with a phone number. Using the Twilio Client in this way allows the coach to listen on their computer speakers which is convenient.
The harder part is you will need to keep track of which calls are active on the client side. Otherwise, you won't have an accurate list of which calls or conferences are active. Repeatedly polling the Twilio REST API for active calls is not recommended by Twilio and is super slow compared to using the webhooks to notify of call status changes.
I am trying to create a voice call from twilio to a number using programmable voice.
I also intend to gather recipient's speech transcribed. However, the documentation contains examples and tutorials only for inbound voice calls.
This is what I have tried-
Initiating voice call:
client.calls
.create({
twiml: `<Response><Gather input="speech" action="https://ngrok-url-for-my-local-server/voice" method="POST" speechTimeout="5"><Say>Hey there, How are you?</Say><Pause length="4" /></Gather></Response>`,
to: toPhoneNumber,
from: myPhoneNumber,
})
.then((call) => {
console.log(call.sid)
console.log(call)
})
.catch((e) => {
console.log(e)
})
Code in handler for gathering speech-
const VoiceResponse = twiml.VoiceResponse
const res = new VoiceResponse()
res.gather()
console.log(res.toString())
However I am not getting anything useful in the console.
Can anybody point me to a useful tutorial or example or tell me what I should do ?
You need to first make the call and then modify the call to gather.
When you make the call using the new VoiceResponse() call you will be returned a SID for the call. Next, use that SID to modify a call that is in progress by redirecting to the Twiml to gather the digits.
You will have three legs:
Make the outbound call (you provided this code in your questions).
Modify the active outbound call by using the call's SID to redirect to a Gather twiml.
After the gather has finished tell the call what do to using the action parameter of the gather. Here is an example.
If you are trying to go for a conference bridge type feature where you press * to move into an admin type menu, you will need a more complex solution involving a conference call.
I have successfully implemented Voice calls functionality in my php application using JS SDK.
Now, I need to implement Call Monitoring and barge in features, that I believe are only available using Twilio Conference.
My current code looks like
$response = new VoiceResponse();
$dial = $response->dial('');
//If Incoming call, redirect the call to my browser client
if($phonenumber == $mytwiliophonenumber)
{
$dial->client($browserclientname);
}
//If outgoing, make the call to the phone number
else
{
$dial->number($phonenumber);
}
Now, what is the easiest way to change this to conference?
I have read that I need to dial the conference, but it is not working.
$dial->conference('anyconferencename');
Any guidance?
A conference has a fundamental difference to connecting two callers together in a regular dial. A conference acts as a room that participants join individually, rather than when you use client or number which places an outbound call leg to the client or number you are dialling.
If you have your user dial into a conference using $dial->conference you will need to create another leg to call the other person into the conference too. You can do this using the conference participants API.
So, instead of your current code, you could update to something like this:
$response = new VoiceResponse();
$dial = $response->dial('');
//If Incoming call, redirect the call to my browser client
if($phonenumber == $mytwiliophonenumber)
{
$participant = "client:" . $browserclientname;
}
//If outgoing, make the call to the phone number
else
{
$participant = $phonenumber;
}
$conferenceName = 'conferencename';
$twilio->conferences($conferenceName)
->participants
->create($mytwiliophonenumber, // from
$participant, // to
);
$dial->conference($conferenceName);
In this option, regardless of whether the call is inbound or outbound, the caller is placed in a conference call. And another call is generated to add the other participant to the conference call too.
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.
The code below intercepts a call in progress and transfer the call to a new number (This piece works as expected).
The question is:
Should I mark the original call as "completed"
How do I do this?
$call_sid = $_SESSION['CallSid'];
$sid = 'xxxxxxxxxxxxxxxxxxxxxxx';
$token = 'xxxxxxxxxxxxxxxxxxxxxxx';
$twilio = new \Twilio\Rest\Client($sid, $token);
$call = $twilio->calls($call_sid)->update(['twiml' => '<Response><Say>Redirecting to Buba</Say><Dial callerId="+18888880592">+14888068886</Dial></Response>']);
//TODO cancel this CALL SID. Status=completed??
print($call->to);
The Twilio call legs are kept up via Twilio Markup Language (TwiML). If you modify one call leg which appears to be what you are doing, if there is another call leg (no conference involved) that is part of that call, that leg will begin processing any TwiML after the <Dial> that originally connected the two parties. If there is no TwiML after the <Dial>, Twilio will hangup that call leg, so no action required on your side.
You should be able to see this behavior in your call logs.