Twilio Voice conference from Browser using PHP - twilio

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.

Related

Listen live calls on Twilio

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.

Twilio call hold is not working as expected

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.

How do I mark a call as completed once I transfer it to another number using Twilio API

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.

Twilio forward incoming calls based on the incoming phone number

I recently ported my home landline number to Twilio. For now, I created a very basic call forwarding TwiML Bin to forward any incoming calls to this former landline number to my cell phone:
<Response>
<Dial>mycellnumber</Dial>
</Response>
What I'd like to do is have some logic to forward incoming calls to a different cell based on the incoming caller matching a number in a contact list, and default forwarding if the incoming number is not on a contact list.
For example, if the incoming call is from a number on the contact list for Cell-X then forward the call to Cell-X, else if on the contact list for Cell-Y forward to Cell-Y, else maybe go to cloud voice mail or another number.
Is there a way to do something like this as a TwiML Bin or in the Studio or is it too complicated? Maybe TaskRouter? This is residential so I'd like it to be invisible to the caller as opposed to something like an IVR solution where the caller is prompted to press a number for the person they want to reach.
I've not had any luck finding a call forwarding solution with logic like this by looking through the Twilio docs or by searching for examples. Please help!
You could do this with a Twilio function.
Let's say that your Cell-X list looks something like this:
const cellXContactList = ["+17782001001", "+17782001002", "+17782001003"];
and your Cell-Y list looks something like this:
const cellYContactList = ["+17782001004", "+17782001005", "+17782001006"];
then you could distribute incoming calls with something like this:
if (cellXContactList.length && cellXContactList.indexOf(event.From) !== -1) {
// caller number found in Cell-X contact list
destinationPhoneNumber = "+17781001001";
} else if (cellYContactList.length && cellYContactList.indexOf(event.From) !== -1) {
// caller number found in Cell-Y contact list
destinationPhoneNumber = "+17781001002";
}
Below is the entire code for the function (replace with your phone numbers):
// forward calls based on the incoming phone number
exports.handler = function (context, event, callback) {
// reference the Twilio helper library
const twiml = new Twilio.twiml.VoiceResponse();
// contacts lists
const cellXContactList = ["+17782001001", "+17782001002", "+17782001003"];
const cellYContactList = ["+17782001004", "+17782001005", "+17782001006"];
// if not in any contact list forward to this number
let destinationPhoneNumber = "+17781001000";
if (cellXContactList.length && cellXContactList.indexOf(event.From) !== -1) {
// caller number found in Cell-X contact list
destinationPhoneNumber = "+17781001001";
} else if (cellYContactList.length && cellYContactList.indexOf(event.From) !== -1) {
// caller number found in Cell-Y contact list
destinationPhoneNumber = "+17781001002";
}
twiml.dial({}, destinationPhoneNumber);
// return the TwiML
callback(null, twiml);
};
You can create Twilio functions in your Twilio console at (https://www.twilio.com/console/functions/manage). Start with a "Blank" functions template, then replace with the code above.
Once you've created and published your function, you can configure your Twilio number to run it when "A CALL COMES IN" (https://www.twilio.com/console/phone-numbers/incoming).

Retrieve Key Input before recording a users call when making calls within Twilio

We have currently developed a phone system for our call centre using Twilio (mainly c#, angular2 and typescript). Our company is currently in the UK but we have now started expanding out to the USA and because of laws in the US it looks like we'd need the ability to choose when we turn on the call recording. In the US people have to consent to recording the call before you can start recording them. I am trying to - when we make an outbound call via twilio to first play a message and get the user to input a key on their dialer to consent to recording the call before continuing with the call. I have attempted to use the gather and say verbs after we have dialled out but this doesn't seem to work. Code below:
`
public override void ApplyAction(TwilioResponse response)
{
var attributes = this.GetAttributes<DialAttributes>("attribute-");
attributes.callerId = this.PhoneNumber;
response.Dial(new Number(this.ReceiverPhoneNumber), attributes);
response.Gather(
new
{
timeout = 10,
finishOnKey = '*'
});
response.Say("We record all calls - please press the star key to consent to call recording");
}`
Twilio developer evangelist here.
The problem is that you are performing the <Dial> before the <Gather>
and <Say>. If you want the user to approve the call first you need to nest the <Say> in the <Gather> and provide an action URL for the <Gather>. When the user presses a button as part of the <Gather> Twilio will make an HTTP request to the action URL with the results in the Digits parameter. Then you should return the <Dial> as the response to that request, if the user signifies agreement. This way you ask them first and then connect the call.
Let me know if that helps.

Resources