Dominik Myszkowski
Dominik Myszkowski

Reputation: 302

Transform a Twilio call into conference

I have an application (Node.js backend and React frontend) which provides a feature of outgoing and incoming calls using Twilio. I would like to add a functionality of voice coaching (optional third person joining actively, passively or whispering (talking only to one other party). I assume I have to transform normal calls into voice conferences to do so and then add a conference participant if required.

The hard part for me is a way to transform a call (or move to) into conference so that there is a conference between Twilio app and a normal mobile phone user (and optional third party - coach). How can this be achieved? My question is regarding both outgoing and incoming calls.

My code for outgoing calls (fired from frontend):

Frontend:

const params = { To: '+48123456789, fromNumber: '+480987654321 };    
let call = await device.connect(params);

Backend:

const response = new VoiceResponse();
const dial = response.dial({ callerId: fromNumber, record: "record-from-answer", recordingStatusCallback: "/twilio/voice/record" });
dial.number(req.body.To);
res.set("Content-Type", "text/xml");
res.send(response.toString());

Incoming calls - backend:

const response = new VoiceResponse();
const dial = response.dial({
  callerId: req.body.From,
  answerOnBridge: true,
  record: "record-from-answer",
  recordingStatusCallback: "/twilio/voice/record",
});
const client = dial.client();
client.identity('[email protected]');
res.set("Content-Type", "text/xml");
res.send(response.toString());

Upvotes: 1

Views: 1973

Answers (2)

Dominik Myszkowski
Dominik Myszkowski

Reputation: 302

After a long battle, I discovered the soulution myself, maybe someone will find it useful. The solution was to create an additional call (to external number) in the same request, after creating a conference and dropping user into it. The calls should provide a TWIML redirecting to the conference once the call is made. Here is a code:

const response = new VoiceResponse();
const dial = response.dial({ callerId: fromNumber, record: "record-from-answer", recordingStatusCallback: "/twilio/voice/record" });
dial.conference(conferenceId, {
  startConferenceOnEnter: true,
  endConferenceOnExit: true,
  beep: false,
  //waitUrl: "",
});
res.set("Content-Type", "text/xml");
res.send(response.toString());
client.calls.create({
  to: To,
  from: fromNumber,
  twiml:
    '<Response><Dial><Conference startConferenceOnEnter="true" endConferenceOnExit="true" beep="false">' +
    conferenceId +
    "</Conference></Dial></Response>",
});

Here is a solution I found by myself for an incoming call:

const fromNumber = req.body.From;
const toNumber = req.body.To;
const identity = await phoneController.getUserIdentityForPhoneCall(toNumber);
console.log("Calling client: " + identity);
const client = phoneController.getTwilioClient();
const response = new VoiceResponse();
const dial = response.dial({
  callerId: req.body.From,
  answerOnBridge: true,
  record: "record-from-answer",
  recordingStatusCallback: "/twilio/voice/record",
});
const conferenceId = "call_" + req.body.CallSid;
const params = {
  startConferenceOnEnter: true,
  endConferenceOnExit: true,
  beep: false,
};
dial.conference(params, conferenceId);
res.set("Content-Type", "text/xml");
res.send(response.toString());
console.log("dialing client: " + "client:" + identity);
client.calls.create({
  to: "client:" + identity,
  from: fromNumber,
  callerId: fromNumber,
  twiml:
    '<Response><Dial><Conference startConferenceOnEnter="true" endConferenceOnExit="true" beep="false">' +
    conferenceId +
    "</Conference></Dial></Response>",
});

Upvotes: 4

ToeFrog
ToeFrog

Reputation: 101

The best option would most likely be to put them in a <Conference> at the start of the call. Put the incoming call in the conference, then using the REST API, you can initiate the outgoing call to the second party. When they answer you add them into the same conference.

If you can't do that you'll need to use the REST API to redirect each call into the conference. Redirect tells Twilio to get new TwiML to execute for a specific call SID. The TwiML would look something like this:

<Response>
  <Dial>
    <Conference>NewConferenceCall</Conference>
  </Dial>
</Response>

You can also take a look at the docs for Modifying Live Calls.

You can use your existing code and do something like this:

response.dial().conference('NewConferenceCall');

That will initiate a conference call rather than a standard voice call. Once you have a conference call with your callers in, you can add a new participant by making a POST request to the participants endpoint.

Upvotes: 2

Related Questions