Build a Free 1:1 Video Chat Application with Twilio WebRTC Go and Ruby
Time to read: 10 minutes
Have you ever wished you could build a video chat application to talk to a friend, family member, or colleague one-on-one? With Twilio WebRTC Go, you can build your own video application where two participants can video chat for free.
In this tutorial, you will learn how to build a 1:1 video chat application with Ruby and 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 a Ruby/Sinatra server that will grant Access Tokens for the participants in the video chat.
If you would like to skip ahead and take a look at the code, check out the project repository on GitHub here.
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!)
- Ruby version 3.0.0+
- Bundler for installing dependencies
- ngrok
Create the project directory and install dependencies
To get started, create a new directory called explore-webrtc-go-ruby and change into that directory by running the following commands in your terminal:
Next, use Bundler to initialize a new application in this directory by running the following command:
This will create a new Gemfile in your project directory.
For this project, you will need the following gems:
- Sinatra, the Ruby web framework you will use to build this project
- sinatra-contrib, for some helpful extensions
- Puma, a Ruby web server
- twilio-ruby, the helper library for interacting with the Twilio APIs
- dotenv, to load the environment variables from your .env file into your application
- rack-contrib, which includes a useful JSON body parser
Add these gems to your project by running the following command in your terminal window:
If you take a look at the Gemfile now, you will see that the 6 gems have been added and installed. (To see details about the versions of the gems used in this project, you can view the Gemfile here.)
Save your Twilio credentials safely 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. Add the following variables to your new file:
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. If you’re using GitHub, 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:
Now it's time to write the code to bring your video chat to life.
Create a Sinatra server and serve static files
Create two new files in your project directory: one called server.rb and the other called config.ru. Open server.rb in your code editor and add the following code to load requirements:
Next, create an application called VideoApp
by adding the following code to server.rb:
With the code above, you are able to serve a static HTML file from a public folder. Static files are served by default from a directory named public. When a user navigates to the root endpoint of your application, the layout from public/index.html is what they will see.
Create the public directory now by running the following command in your terminal from the root directory of the project:
Inside this folder, create and open a new file called index.html, then paste in the following code:
With this HTML code, you create a layout for the video chat application, including the Twilio Video library from CDN in a <script>
tag. Since you are using WebRTC Go for this project, you are creating 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.
In addition to the HTML file, create and open a new file, public/styles.css. Then, copy the CSS from this repository and paste it into your file.
Now that you have some HTML and CSS, open config.ru in your code editor and add the following code to the file:
This configuration will load the environment variables from your .env file and run the video application using the Puma server.
To start the application on port 5000, run the following command in your terminal:
You will see a log statement in your terminal similar to the below once the server is running:
Set up an ngrok tunnel
In this project, you'll be using ngrok to connect the Sinatra 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 similar to 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 local server.
Open the https:// ngrok forwarding URL in a browser window, and you will see a form like the one below:
Now that you have set up a structure to hold your video chat, it's time to use JavaScript to display your video feed preview in the browser.
Display a preview of your video
Create and open a new file called public/app.js. Inside this file, add the following lines of code to set up the variables you will need for this part of the project:
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, paste in 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>
. If you refresh the page in your browser window, the browser will ask for your permission to turn on the camera. Once you grant permission, you will be able to see your video feed preview.
Generate an access token and a WebRTC Go video room
Now that you have a video preview set up, it's time to write the code that will let you join the video call. To join a video call, you will need a short-lived credential called an Access Token. In addition to generating the Access Token, you'll also be creating the video room on the server side using the Rooms REST API so you can specify that you would like to create a go
room.
In server.rb, add the following /token endpoint to the VideoApp
class, just below the entry endpoint but before the final end
statement:
When a participant enters their name in the application's input field and clicks the Join Video Call button, their name and the video room name will be passed to the /token endpoint via a POST
request. The endpoint will then use your Twilio credentials and the Twilio Ruby helper library to create an access token for this user and a Go video room that this token will be associated with. Then the token will be returned to the client side of your application. The JavaScript code you will write in the next step will use this token to connect to the video room.
Let's move on to these JavaScript steps next.
Connect to a video room as a local participant
Now that you are able to generate access tokens, it's time to write code that will let you join the video chat as a local participant. Return to public/app.js in your code editor.
Just below your addLocalVideo
function definition, 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 identity
from the username 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
that don’t exist yet.
The connect
function mentioned above will take the user's identity
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.
Connect a remote participant to the video room
You may have noticed, in the connect
function you added before, 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 creates a new <div>
for each remote participant when they connect to the room, displays their username (identity
), and attaches their video and audio tracks to the <div>
. The function also creates event listeners for when these remote participants publish or unpublish their tracks — if someone starts or stops sharing their media, your application can attach or detach these tracks from the UI as needed.
Add the following participantConnected()
function just below your disconnect
function in public/app.js:
Now that you have code for participantConnected()
, add the following participantDisconnected()
function just below that. This function removes the remote participant's video feed and username from the UI:
Next, you will need 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 the ngrok forwarding URL from earlier in the tutorial. Hard refresh the page to request the updated HTML and JS files, and then you will 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 from a different device. You may even want to share the link with a friend. Connect to the video room with a different username than the one you used in the previous steps. Once you have both 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. Take a look at this WebRTC Go overview post if you would like to learn even more about what you can do with Go rooms.
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.