Build a Free 1:1 Video Chat Application with Twilio WebRTC Go and JavaScript
Time to read: 10 minutes
Have you ever wished you could build your own video chat application to talk to a friend, family member, or colleague one-on-one?
There are so many projects you could build or enhance with video — a video chat for friends, a telemedicine application, a virtual real estate tour, a tutoring app, a dating application, and many more. When you're getting started building a new project, it's great to have a way to build for free and explore your ideas.
With Twilio WebRTC Go, you can build your own 1:1 video application where participants can video chat for free. You can build your own WebRTC-enabled video app without needing to be concerned with some of the challenges of building directly on WebRTC.
In this tutorial, you will learn how to build a 1:1 video chat application with JavaScript and set it up to run on ngrok so you can chat with a friend. The application will consist of two parts: a vanilla JavaScript client-side application that will allow you to connect to a video room, and an Express server that will grant access tokens for the participants in the video chat.
Let's get started!
Prerequisites
- A free Twilio account. (If you register here, you'll receive $10 in Twilio credit when you upgrade to a paid account!)
- Node.js (version 14.16.1 or higher) and npm installed on your machine.
- ngrok
Create the project directory and install dependencies
To get started, navigate to where you would like to set up your project. Create a new directory called explore-webrtc-go and change into that directory by running the following commands in your terminal:
Next, set up a new Node.js project with a default package.json file by running the following command:
Once you have your package.json file, you're ready to install the needed dependencies.
For this project, you will need the following packages:
- Express, a Node.js framework
- Twilio Node Helper Library, to use the Twilio APIs
- dotenv, to load the environment variables from a .env file into your application
- node-dev, to automatically restart the Node process when you modify a file
Run the following command in your terminal to install the needed packages:
If you check your package.json file now, you'll notice that the packages above have been installed as dependencies
.
Save your Twilio credentials as environment variables
Next, create a new file named .env at the root of your project and open it in your code editor. The .env file is where you will keep your Twilio account credentials. Open the .env file in your text editor and add the following variables:
You’ll need to replace the placeholder text above with your actual Twilio credentials, which can be found in the Twilio Console. Log in to the Twilio Console and find your Account SID:
Copy and paste the value for Account SID to replace the placeholder text for TWILIO_ACCOUNT_SID
.
Then, navigate to the API Keys section of the console and generate a new API Key. Copy the API Key's values for SID and Secret to replace the placeholder text for TWILIO_API_KEY_SID
and TWILIO_API_KEY_SECRET
.
It’s important to keep these private credentials secure and out of version control, so create a .gitignore file at the root of your project. Here you can list the files and directories that you want git to ignore from being tracked or committed. Open .gitignore in your code editor and add the .env file. While you're in here, add the node_modules directory as well:
Now it's time to get into writing the code to bring your video chat to life.
Create an Express server
Create a new file called server.js at the root of your project. This is the place where you will write your server-side code.
Open up server.js in your code editor. Add the following lines of code to server.js, which will load the environment variables from your .env file, start a new Express application, and set the application to run on port 5000:
Below the code you added above, add the following lines of code to start the Express server:
Now, open package.json in your code editor. Inside the scripts
section, add a start
script as shown below. You can replace the test
script that was automatically generated by npm init --yes
earlier:
To run the start
script, return to your terminal window and run the following command:
Once you have done this, you should see the following log statement in your terminal window, letting you know that the Express server is running:
Set up an ngrok tunnel
In this project, you'll be using ngrok to connect the Express application running locally on your machine to a temporary public URL. To start a new ngrok tunnel, open up a new terminal window and run the following command:
Once ngrok is running, you will see text like the below in your terminal window:
Take a look at the URLs next to Forwarding
. Now, any requests that are made to these ngrok URLs will be forwarded to your Express server.
Create the application layout and serve static files
Now that your server is running, it's time to create the rest of your application's layout. Create a new directory called public
at the root of your project. This directory will hold your static files:
Inside the public
directory, create 3 new files: app.js, index.html, and styles.css.
Open up public/index.html in your code editor and add the following code to the file:
With this HTML code, you create the layout for the video chat application, as well as include the Twilio Video library from CDN in a <script> tag. Since you are using WebRTC Go, it is a one-on-one video chat with only two participants. This means that you will only need to show two video feeds — one for the localParticipant
and one for the remoteParticipant
. This layout also includes a login
form that will let the participants enter their names and click a button to join the video call.
Return to server.js and add the following lines of code just below the variables at the top of the file:
With this code, you have set your application to use the Express JSON middleware, serve your static files from the public
directory you just created, and show your layout from index.html when a user navigates to the root endpoint of your application.
If you visit one of the ngrok forwarding URLs in your browser, you will see something that looks like the below:
Let's add some CSS to make it a bit more interesting. Open public/styles.css in your code editor, then add the following styles to the file:
If you refresh your browser window, the application so far should look more like this:
Now that you have set up a structure to hold your video chat, the next step is to use JavaScript to display a preview of your video as the local participant.
Display a preview of your video
Open public/app.js in your code editor and add the following variables at the top of the file:
The first variables refer to specific HTML elements in your UI. Setting them to variables allows you to work with them more easily. Following these, you also have variables for connected
and room
. The connected
variable describes whether the local participant is connected to a video room, and the room
variable describes that video room.
Just below your list of variables, add the following addLocalVideo
function, and then call the function, as shown in the code below:
This function uses the Twilio Programmable Video library to create a local video track, which will be attached to the localParticipant
<div>. When you navigate to the application's URL in your browser window, you should see your video preview there. (If this is your first time visiting the page, an alert message may pop up, asking if localhost:5000 can access your camera. Once you grant permission, you'll be able to see your video feed.)
Now that you have seen your video preview, you're ready to write the code that will let you join the video call.
Generate an access token and a WebRTC Go video room
In order to join a video call, you will need to generate a short-lived credential called an access token. This will happen on the server side of your application.
In addition to generating an access token, you'll also be creating the video room on the server side of the application. Using the Rooms REST API, you are able to specify what type of video room you want to create, and in this project, you'll create a Go room.
Return to server.js in your code editor and add the following variables to the file, just below the variables already in the file:
Then, just below that code, add the following lines of code to initialize the Twilio client:
When a participant navigates to your application, enters their username in the input field, then clicks Join Video Call, their name will be passed to a /token
endpoint here on the server side via a POST request. This endpoint will get the user's username and the video room's name from the request, then use your Twilio credentials and the Twilio Node Helper Library to create an access token for this user. The endpoint will also check whether the Go room exists already, and if it does not, will create a new one. Then, the endpoint will return the access token to the client side of your application. Your JavaScript code will then use this access token to connect to the video room.
In server.js, just below your app.get
block, add the following /token
endpoint:
Connect to a video room as a local participant
Now that you are able to generate access tokens, it's time to write the code that will let you join the video chat as the local participant. Return to public/app.js in your code editor.
Just below your addLocalVideo
function, create a new function called connectOrDisconnect
that will handle the event when a user clicks the Join Video Call button:
This function will check the connected
variable to see whether the user is already connected to a video room. If the user is not already connected, this function will get the user's username
from the input field in the UI and then try to connect to the video room. If the user did not enter a name in the input field, an alert message will pop up to let them know that they must complete this step before connecting.
If a user is already connected to a video room, the connected
variable will already be set to true
, which will trigger calling the disconnect
function, disconnecting the participant from the video room and resetting the UI.
You may have noticed that the function described above references individual functions called connect
and disconnect
.
The connect
function mentioned above will take the user's username
from the input field and send it in a request to the /token
endpoint you created earlier. Once the server side sends back an access token, this token is passed into another connect
function within the client-side twilio-video library linked in the first <script> tag in index.html. If the connection is successful, the local participant will be connected to the video room and this video room will be assigned to the global variable for room
. Then, the function sets up event listeners to listen for when the other participant joins the video call. Once the local participant has joined the video call, the text of the Join Video Call button changes to Leave Video Call for that participant, and the field for entering a username is hidden.
Add the following connect
function to public/app.js just below the connectOrDisconnect
function:
Next, it's time to add the disconnect
function. This function will handle disconnecting a participant from the video room when they click the Leave Video Call button. It will also remove the remote participant's video feed from the UI, set the button's text back to Join Video Call, and let the username input appear again.
Add the following disconnect
function just below your code for the connect
function:
Now, just above where you call the addLocalVideo
function at the bottom of public/app.js, add add an event listener to the login
form that will listen for the submit
event and call connectOrDisconnect
when this event occurs:
Now that you have taken care of the local participant's connection to and disconnection from the video room, it's time to add some code to handle when the other participant joins and leaves the room.
Handle the remote participant's connection and disconnection
You might have noticed in the connect
function you added above, that when a participantConnected
event occurs in the video room, the function participantConnected
gets called. A similar thing occurs for the participantDisconnected
event. You will need to add these two functions in order to handle the connection and disconnection of the remote participant.
Start by adding the participantConnected
function. This function will create a new <div> for the remote participant when they connect to the room, display their username (identity
), and attach their video and audio tracks to the <div>. The function also creates event handlers for responding to when the remote participant's tracks are subscribed to or unsubscribed from; if the participant turns off their audio or video feed, you want the application to be able to attach or detach these tracks as needed.
Add the following participantConnected
function just below your disconnect
function in public/app.js:
Next, it's time to add the participantDisconnected
function for when the remote participant leaves the video call. This function will remove the remote participant's video feed and username from the UI.
Add the following participantDisconnected
function just below your participantConnected
function:
Next, it's time to add code for when the local participant subscribes to or unsubscribes from a remote participant's audio or video tracks. Add the following trackSubscribed
and trackUnsubscribed
functions to public/app.js just below your code for participantDisconnected
:
Now you have all the code you need for this project! It's time to test everything out.
Testing your video chat application
Return to your browser window pointing to one of the ngrok forwarding URLs from earlier in the tutorial. If you refresh the page, you should see your own video feed preview there. Enter your name in the input field and click the Join Video Call button. You will see the input field disappear and the text of the button change to say Leave Video Call. You will also see your name just below your video feed.
To test out chatting with a remote participant, navigate to the ngrok forwarding URL link in a second browser window or even from a different device. Connect to the video room with a different username than the one you used in the previous steps. Once you have connected to the video room, you will be able to video chat!
What's next for your free 1:1 video chat with WebRTC Go?
You've just built a cool video chat application that you can use for free 1:1 video conversations! There are so many ways you could use an application like this. Maybe you're interested in using the 1:1 chat for a tutoring session, a quick business call, or just to catch up with a friend. If you're interested in learning even more about WebRTC Go, consider taking a look at this blog post next.
If you would like to see the code for this project in its entirety, check out the repository on GitHub here.
What will you build next? Perhaps you're interested in allowing video chat participants to mute and unmute their audio? Or maybe you want to learn how to add virtual backgrounds to your video chat? There are so many exciting things you can create. I can't wait to see what you build!
Mia Adjei is a Software Developer on the Developer Voices team. They love to help developers build out new project ideas and discover aha moments. Mia can be reached at madjei [at] twilio.com.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.