This content originally appeared on Twilio Blog and was authored by Viral Gandhi
Ahoy! As you might know, Twilio works on a pay-as-you-go model and so does Twilio Video, meaning it charges per minute per participant for each video room. Hence, in most business cases it is not a good idea to start a video room until one of the following is true:
- The host joins.
- There are more than one participant in the room.
- You can validate the schedule of the meeting before you start.
In this article you are going to learn how to build a cost effective lobby (waiting) area feature for your Twilio Video application using Twilio Sync.
What you’ll build
The example scenario I will consider in this article is where the video room starts when a host joins the room. But this approach can also apply to starting a video room when more than one participant joins, or if it is a scheduled meeting and the backend application validates the schedule before meeting.
Here’s an example of what a lobby for a guest participant might look like before the host participant joins the room.
And now you see that a guest joined the video room after the host joined and started the room.
Prerequisites
- A developer environment where you can run Node.js code
- A Twilio account - sign up for a free one here
- Basic idea about creating video rooms via Javascript SDK
- Basic knowledge of Twilio Sync
Let's start building!
Here is a visual overview of the steps the application will follow once you have completed building this feature.
Twilio Sync
The Twilio Sync feature provides a way to maintain real-time (millisecond level) state synchronization. There are three ways you can use Twilio Sync: Sync Document, Sync List and Sync Map. I will be using the Sync Document feature to receive status of the video room on the client side.
Implementation Steps
Follow the steps below to build your lobby feature. You can find code repo here.
Create Sync service
Create the Twilio Sync Service by clicking on Create new Sync Service from Console or via the Sync API . I used the name, “SyncServiceForWaitingRoom.”
Make a note of the Sync Service SID because you will use these in the following steps.
Create Sync document
Create a separate Sync document for every meeting you create and if a non-host participant is joining before the host of the meeting. Note that the host and non-host participants are logically different user types. You would need to write business logic for such role-based access. Twilio does not model participant roles natively.
Keep the friendly name of the Sync document the same as the video room unique name. This will help clients to subscribe to the events from the relevant room easily.
The code snippet below is from get_token.js file for your understanding. Check to see if the Sync document exists.
async function isSyncDocExists(docName) {
let res = false;
let status = false;
try {
res = await client.sync.v1.services(process.env.SYNC_SERVICE_SID)
.documents(docName)
.fetch()
status = true;
} catch (error) {
console.log(error);
}
return { status, data: res };
}
Create a Sync Document with room: not_started data. This parameter will be monitored on the updated event on the client side to check if the video room has started.
async function createSyncDoc(docName) {
let res = false;
let status = false;
try {
res = await client.sync.v1.services(process.env.SYNC_SERVICE_SID)
.documents
.create({ uniqueName: docName, data: { room: 'not_started' } })
status = true;
} catch (error) {
console.log(error);
}
return { status, data: res };
}
Get Token
Expose the API endpoint as /get_token to serve tokens (for Video and Sync). Each participant would request this API to get the tokens and this API endpoint will check if the video room exists. If yes, then there’s no need to pass the Sync token as a response to the client application. Otherwise, the client can expect an access token with both Sync and Video grants.
exports.handler = async function(context, event, callback) {
let roomName = event.roomname;
let videoRoomStatus = false;
let AccessToken = require('twilio').jwt.AccessToken;
const SyncGrant = AccessToken.SyncGrant;
let isSyncDocExists;
const accessToken = new twilio.jwt.AccessToken(
context.ACCOUNT_SID, context.API_KEY_SID, context.API_KEY_SECRET
);
accessToken.identity = event.username;
const videoGrant = new twilio.jwt.AccessToken.VideoGrant({
room: roomName
});
accessToken.addGrant(videoGrant);
if(event.role == 'host' || event.role == 'co_host'){ //If host or co-host joined the room
//update sync document
isSyncDocExists = await ifSyncDocExists(roomName);
if(isSyncDocExists.status === false){
await createSyncDoc(roomName);
}
await updateSyncDoc(roomName);
videoRoomStatus = true;
}else{ //If any guest joins the room
let isRoomExists = await isVideoRoomExists(roomName);
if(isRoomExists.status === true){ //Check if room exists
videoRoomStatus = true;
}else{ //If room does not exists then check if Sync document exists
videoRoomStatus = false;
isSyncDocExists = await ifSyncDocExists(roomName);
if(isSyncDocExists.status != true){
await createSyncDoc(roomName);
}
}
}
if(!videoRoomStatus){ //create and add Sync grant only when Video room does not exists
let syncGrant = new SyncGrant({
serviceSid: context.SYNC_SERVICE_SID,
});
accessToken.addGrant(syncGrant);
}
return callback(null, {
token: accessToken.toJwt(),
videoRoom: videoRoomStatus
});
}
Subscribe to the Sync document from client
Using a token, the client application subscribes to the document with the same friendlyName as the video room unique name for the updated event and it will monitor for event.data.room = started. As soon as the client receives this updated event, it makes participants join the room using Video.connect().
Below you see the code snippet from app.js:
try {
syncClient = new Twilio.Sync.Client(data.token);
syncClient.document(roomname)
.then(function (document) {
// Listen to updates on the Document
document.on('updated', async function (event) { //Received Document update event.
if (event.data.room == 'started') { //If room is 'started' then make participant join the video room
meetingRoomNotStarted.style.display = "none";
container.style.display = "block"
addLocalVideo();
room = await Twilio.Video.connect(data.token);
room.participants.forEach(participantConnected);
room.on('participantConnected', participantConnected);
room.on('participantDisconnected', participantDisconnected);
connected = true;
updateParticipantCount();
}
});
})
.catch(function (error) {
console.error('Unexpected error', error)
});
} catch (error) { console.log(error) };
Update Sync document
Whenever a host participant requests a token to API /get_token video room, create the new meeting room with the given Identity and update the Sync document with friendlyName as video room unique name.
Below you see the code snippet from get_token.js:
async function updateSyncDoc(docName) {
let res = false;
let status = false;
try {
res = await client.sync.v1.services(process.env.SYNC_SERVICE_SID)
.documents(docName)
.update({ data: { room: 'started' } });
status = true;
} catch (error) {
console.log(error);
}
return { status, data: res };
}
Unsubscribe Sync Document
Unsubscribe to the Sync document to not receive further events from the same Sync document. This needs to be done on the client side as document.close().
See the code sample from app.js during room disconnect():
const disconnect = async () => {
if(syncClient != undefined){
//Close subscription of sync Document for guests participants
var document = await syncClient.document(room.name);
document.close();
}
room.disconnect();
while (container.lastChild.id != 'local') {
container.removeChild(container.lastChild);
}
button.innerHTML = 'Join';
connected = false;
updateParticipantCount();
};
Next steps for your video waiting room
Congratulations!! You have learned how to add a lobby (waiting) area feature on your Twilio Video app. Doing so will give your participants a positive experience while they wait for the meeting to start, and it’ll save you the cost of paying for a meeting that isn’t in session.
Below are a few things to consider as you implement and evolve this feature to suit your business needs.
- Based on business use cases and As-Is infrastructure, you can also replace Twilio Sync with plain Websockets for the lobby area feature.
- You can also consider adding business logic validating the schedule of a meeting before you create a video room. If a participant tries to join the meeting room before the scheduled time, then that participant can wait in the lobby area.
- Lobby areas can also be used for advertising, marketing, or giving important information while participants are waiting for the get video meeting to start.
- It is highly recommended to use the Status callback event webhook for Twilio Video and perform necessary cleanup actions on room-ended or other relevant events, such as deleting the Sync document and recording compression related activities.
For assistance with any aspect of your Twilio implementation, reach out to Twilio Professional Services. We have plenty of solutions like this one in our back pocket and we can’t wait to help you build!
Viral Gandhi is a Strategic Onboarding Engineer at Twilio Professional Services. He mainly helps customers to get onboarded with Twilio products and implement them in their solution. He can be reached at vigandhi [at] twilio [dot] com.
This content originally appeared on Twilio Blog and was authored by Viral Gandhi
Viral Gandhi | Sciencx (2022-09-12T16:28:21+00:00) Create a Video Lobby Feature. Retrieved from https://www.scien.cx/2022/09/12/create-a-video-lobby-feature/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.