I'm using the Twilio JavaScript Voice SDK and TwiML App handled by PHP to make an outbound voice call.
My first implementation was to dial the number directly..
Client side...
device.connect({
params: {
callee_name: name,
callee_number: phoneNumber,
}
}).then((call) => {
call.on('accept', (acceptedCall) => {
console.log('in accept');
let callSid = acceptedCall.parameters.CallSid;
});
});
Server side...
$voiceResponse = new VoiceResponse;
$dial = $voiceResponse->dial('', ['callerId' => $callerId]);
$dial->number($calleeNumber,[
'statusCallbackEvent' => 'initiated ringing answered completed',
'statusCallback' => $statusCallbackUrl
]);
$xml = $voiceResponse->asXml();
$response = new Response($xml, Response::HTTP_OK, ['context-type' => 'text/xml']);
return $response;
This works fine. With this approach, however, capabilities such as call forwarding, coaching and many others are simply not possible. To get access to these capabilities I have to put the call into a conference. So one approach is put the call into conference when I need those functions. However, as noted in this answer https://stackoverflow.com/a/22919470/7422838 it is best to put the outbound call in conference from the start. So, for example, if your are recording the call, the recording will not be in two pieces when you put the call in conference.
So how to do this? My current approach is this:
Client side...
device.connect({
params: {
callee_name: name,
callee_number: phoneNumber,
}
}).then((call) => {
call.on('accept', (acceptedCall) => {
let callSid = acceptedCall.parameters.CallSid;
$.ajax({
url: dialFromConferenceUrl,
data: {
call_sid: callSid,
callee_name: name,
callee_number: phoneNumber,
}
});
});
});
Server side, in the voice.XML callback
$voiceResponse = new VoiceResponse;
$dial = $voiceResponse->dial('', ['callerId' => $callerId]);
$dial->conference($conferenceSid,[
'statusCallbackEvent' => 'start end join leave mute hold',
'statusCallback' => $statusCallbackUrl
]);
$xml = $voiceResponse->asXml();
$response = new Response($xml, Response::HTTP_OK, ['context-type' => 'text/xml']);
return $response;
Server side, in the call from conference handler...
$client->conferences($conferenceSid)
->participants
->create($mainPhone,$calleePhone
[
'label' => $calleeType,
'statusCallback' => $conferenceStatusUrl,
'statusCallbackEvent' => ['initiated', 'ringing', 'answered', 'completed']
]);
So all this works, but it seems very inelegant and klugey. I'm making 2 server round trips to do, from the client's perspective, a single operation: make an outbound call through a conference room. Sure there are multiple components to this operation: (1) create conference room; (2) connect client to conference room; (3) dial 2nd party and add as participant to conference room. But why can't all of these component operations be done server-side, with a single query from the client?
I suspect they can be, which is why I am asking this question.