I would like to know how many people are currently connected to a room when using Twilio Video.
Twilio has a REST API to get a room resource, but it does not return current number of participants.
https://www.twilio.com/docs/api/video/rooms-resource#get-by-sid
Only way i see is to subscribe to status callback to "participant connected" and disconnected events and manually keep track of how many participants are connected or left the room.
Is there a better way to do this ?
You can use twilio server side sdk, Let me share NodeJS example so you get better idea on implementation.
First lets define function that init twilio client and fetch connected participants of room.
async function getConnectedParticipants(roomName) {
var Twilio = require('twilio');
var apiKeySid = "YOUR_TWILIO_API_KEY_SID_HERE";
var apiKeySecret = "YOUR_TWILIO_API_SECRET_HERE";
var accountSid = "YOUR_TWILIO_ACCOUNT_SID_HERE";
var client = new Twilio(apiKeySid, apiKeySecret, {accountSid: accountSid});
var list = await client.video.rooms(roomName)
.participants
.list({status: 'connected'});
return list;
}
Now let's use our function that return you connected participants.
var connectedParticipants = await getConnectedParticipants("YourRoomName");
// print all connected participants
console.log('connectedParticipants', connectedParticipants);
Note: I have used async and await in this example, please check more on that before implementation.
Twilio developer evangelist here.
Keeping a server side list of the participants' identities based on the participant connected and disconnected events is probably the best way to work this out right now.
One alternative is to get this information from the front end. The JavaScript library allows you to query the participants in a room. You could periodically, or based on events, query that property and send it to your server via Ajax too.
Let me know if that helps.
Update
The Rooms API now allows you to retrieve information on participants that have connected to a room. To get the currently connected users in a room using Node.js, for example, the code would look like:
var client = new Twilio(apiKeySid, apiKeySecret, {accountSid: accountSid});
client.video.rooms(roomSid).participants
.list({status: 'connected'}, (err, participants) => {
if (err) { console.error(err); return; }
console.log(participants.length);
});
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 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.
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.
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).
How can I get a conference participant's phone number using the Twilio API? I am using the official Twilio PHP Library.
Hello Twilio Developer Evangelist here. 👋
What you can do is to fetch all active participants with a snippet like this (you can find more details in the docs for the conference participants.
<?php
// Update the path below to your autoload.php,
// see https://getcomposer.org/doc/01-basic-usage.md
require_once '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;
// Find your Account Sid and Auth Token at twilio.com/console
// DANGER! This is insecure. See http://twil.io/secure
$sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$token = "your_auth_token";
$twilio = new Client($sid, $token);
$participants = $twilio->conferences("CFXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
->participants
->read(array(), 20);
foreach ($participants as $record) {
print($record->callSid);
// "CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
Now, when you did this you'll see that the participant record does not include the phone number of the participant. But what it includes is the call_sid. The call sid helps you to identify the caller and retrieve call details.
There you have two options (I described something similar just recently here).
1. Persist the call information when you route callers into the conference
What you could do when you route people into the conference is to persist their numbers and call sids in your application. This way you could have a registry with all the people that entered your conference and access their phone numbers quickly when you need them.
2. Make another API call to get the call details and caller number
When you have the call SID what you can always do is to fetch the call details one by one.
<?php
$call = $twilio->calls("CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
->fetch();
print($call->from);
The first approach saves you API calls with the cost of maintaining your own persistence layer. The second approach makes more API calls but it is easier to set up.
As always, it depends on the situation.
I hope that helps. :)