Build a Video Chat Application with Twilio, Rails, and Javascript (Part 1) www.bacancytechnology.com
Introduction
Want to develop your own video chat app? But, not sure where to start? Don’t worry at all! We are here with a tutorial that will help you build your own video chat application. Don’t limit yourself, and start exploring with us! Here, we will learn with an example and build a one-to-one video chat application with Twilio, Rails, and Javascript. With this application, you can easily video chat with your family and friends.
Tutorial Goal
Before building the Twilio video chat application, look at the video below to have a rough idea of the demo. The video chat app development will consist of three major sections – User Interface using Javascript + HTML + CSS, Twilio Basic Set-Up, and Business Logic to Build a Video Chat App. https://youtu.be/IoGb6jo9bgs
Prerequisites
Twilio account Ruby version 2.6.2 Node version 14.8.0 Rails version 6 Bundler to install dependencies
Basic Project Set-Up and Dependencies Installation
2.6.2 ruby version 6.0.4.1 Rails version 14.8.0 node version. Before getting started with the demo application, here’s my system set up- Create a new rails application using the below commands rails new twilio-video-call cd twilio-video-call Then, run the following command to install dependencies – bootstrap, jQuery, and popper.js yarn add bootstrap@4.3.1 jquery popper.js
After this, add the following code in the config/webpack/environment.js file. const { environment } = require('@rails/webpacker') const webpack = require("webpack") environment.plugins.append("Provide", new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', Popper: ['popper.js', 'default'] })) module.exports = environment // config/webpack/environme nt.js file
Go to app/assets/stylesheets/application.css and add the following line above the require_tree and require_self lines. *= require bootstrap And add this code in application.js require("jquery") import $ from 'jquery'; window.jQuery = $; window.$ = $;
Add a Room using Scaffold
Now, it’s time to create a Model, View, and Controller using Scaffold once we have a basic setup. Use the below command to do the same. rails g scaffold room name:string After that, go to the migration file and add the unique_name and room_sid field to the migration. We will use this in the future. Now your migration will look like this. class CreateRooms <ActiveRecord::Migration[6.0] def change create_table :rooms do |t| t.string :name t.string :unique_name t.string :room_sid t.timestamps end end end
Go to the config/routes.rb file and add the root path for your app. root to: "rooms#index" After that, migrate the database using. rails db:migrate After that, go to this URL http://localhost:3000/. Congratulations! If you see this screen, your app is working. Now let’s create the random string as a unique name for each room. Add this code to the room.rb model.
before_create :add_uniqe_name def add_uniqe_name unless self.unique_name.present? self.unique_name = (0...15).map { ('a'..'z').to_a[rand(26)] }.join end end // room.rb This will create a unique random string for the unique_name field whenever a new room is generated. Moving on further with the tutorial to build a video chat application with Twilio, Rails, and JS. Here, we are done with creating a room. Now, let’s set up a Twilio account and store its credentials.
Add Twilio Gem and Create Twilio Account
For that, we are going to use Twilio Programmable video. For this, we need a Twilio account. Click here to create an account if you don’t have any. Add Gems into gemfile gem 'twilio-ruby' gem 'dotenv-rails' Run bundle bundle install
Add Twilio Credentials
After that, go to your Twilio dashboard and copy the ACCOUNT SID and AUTH TOKEN. For storing credentials, we are going to use dotenv. Create a .env file in the root directory of the project. And Add the following line in config/application.rb. dotenv::Railtie.load For this tutorial, I’m going to create that file in the twilio-video-call folder. If you use git for version control, don’t forget to add this file in gitignore.
Go to the API Key section and click the red plus sign to create a new API key. Give your key a recognizable name representing the project you’re working on in the Friendly Name text field and leave the Key Type Standard. Click the button that says Create API Key. Assign those keys to API_KEY_SID and API_KEY_SECRET. Add those credentials in the .env file.
Business Logic to Build a Video Chat Application with Twilio, Rails
// controllers/rooms_controller.rb def show @client = Twilio::REST::Client.new(ENV['ACCOUNT_S ID'], ENV['AUTH_TOKEN']) unless @room.room_sid.present? # create room in twilio twilio_room = @client.video.rooms.create(type: 'peer-to- peer',unique_name: @room.unique_name) @room.update(room_sid: twilio_room.sid) end identity = (0...5).map { ('a'..'z').to_a[rand(26)] }.join @room_name = @room.unique_name Create Twilio Room Change the Show action’s code with the following code.
#create token to access Twilio room @token = Twilio::JWT::AccessToken.new(ENV['ACCOU NT_SID'], ENV['API_KEY_SID'],ENV['API_KEY_SECR ET'], identity: identity) #create video grant for token grant = Twilio::JWT::AccessToken::VideoGrant.new grant.room = @room_name @token.add_grant grant @token = @token.to_jwt end This code will first check the presence of sid (unique id used for Twilio unique rooms) in the database. If it is not available, it will generate the room in Twilio and store the sid in the database.
We are creating a unique string as a unique identifier for the Twilio room. (You can use the logged-in user’s name for it.) It will create the Twilio token and video grant.
User Interface for Video Chat App
For building a user interface, open views/rooms/show.html.erb and use the below code. You can change the styling part as you like. // views/rooms/show.html.erb.
<div class="row"> <div class="col-9"> <div id="remote-video"> </div> </div> <div class="col-3"> <div id="local-video"> </div> </div> </div> <div class="row buttons-panel mb-5"> <div class="col-12 d-flex justify-content- center align-items-center"> <button class="btn btn-danger p-3 rounded-circle d- none" id="call-end-btn> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-telephone-x-fill" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.885.511a1.745 1.745 0 0 1 2.61.163L6.29 2.98c.329.423.445.974.315 1.494l-.547 2.19a.678.678 0 0 0 .178.643l2.457 2.457a.678.678 0 0 0 .644.178l2.189-.547a1.745 1.745 0 0 1 1.494.315l2.306 1.794c.829.645.905 1.87.163 2.611l-1.034 1.034c-.74.74-1.846 1.065- 2.877.702a18.634 18.634 0 0 1-7.01-4.42 18.634 18.634 0 0 1-4.42-7.009c-.362-1.03-.037- 2.137.703-2.877L1.885.511zm9.261 1.135a.5.5 0 0 1 .708 0L13 2.793l1.146-1.147a.5.5 0 0 1 .708.708L13.707 3.5l1.147 1.146a.5.5 0 0 1-.708.708L13 4.207l-1.146 1.147a.5.5 0 0 1-.708-.708L12.293 3.5l-1.147-1.146a.5.5 0 0 1 0-.708z"/> </svg> </button> </div> </div>
Add the following css style code in app/assets/stylesheets/rooms.scss buttons-panel{ position: fixed; bottom: 0; width: 100%; } #remote-video{ border-radius: 15px; video{ width: 100%; height: 770px; border-radius: 15px; } } #local-video{ border-radius: 15px; video{ border-radius: 15px; width: 100%; height: 300px; } }
Connecting Twilio Rooms
Let’s write the code for connecting Twilio rooms. Include the Twilio js in the show.html.erb file <%= javascript_include_tag 'https://media.twiliocdn.com/sdk/js/video/r eleases/2.3.0/twilio-video.min.js' %> Create a video_call.js file in the javascript/packs folder and include that file from application.js. And add the following code in that file.
// video_call.js , window.joinRoom = async function(room, token){ const Video = Twilio.Video; const localTracks = await Video.createLocalTracks({ audio: true, video: { height: 1080, frameRate: 24, width: 1980 }, }); try { room = await Video.connect(token, { name: room, tracks: localTracks, bandwidthProfile: { video: { mode: 'collaboration',
, maxTracks: 10, dominantSpeakerPriority: 'high', renderDimensions: { high: {height:1080, width:1980}, standard: {height:720, width:1280}, low: {height:176, width:144} } } }, dominantSpeaker: true, maxAudioBitrate: 16000, preferredVideoCodecs: [{ codec: 'VP8', simulcast: true }], networkQuality: {local:1, remote: 4} }); } catch (error) { console.log(error); } const localMediaContainer = document.getElementById("local-video"); localTracks.forEach((localTrack) => { l
, ocalMediaContainer.appendChild(localTrac k.attach()); }); // display video/audio of other participants who have already joined room.participants.forEach(onParticipantCo nnected); room.on("participantConnected", onParticipantConnected); room.on("participantDisconnected", onParticipantDisconnected); $("#call-end-btn").removeClass("d-none"); $("#call-end-btn").on("click",function() { onLeaveButtonClick(room); }) };
, window.onParticipantConnected = function(participant){ var remote_div = document.getElementById('remote-video'); const participantDiv = document.createElement('div'); participantDiv.id = participant.sid; const trackSubscribed = (track) => { participantDiv.appendChild(track.attach()); }; participant.on("trackSubscribed", trackSubscribed); participant.tracks.forEach((publication) => { if (publication.isSubscribed) { trackSubscribed(publication.track); } }); remote_div.appendChild(participantDiv);
, const trackUnsubscribed = (track) => { track.detach().forEach((element) => element.remove()); }; participant.on("trackUnsubscribed", trackUnsubscribed); }; window.onParticipantDisconnected = function(participant){ const participantDiv = document.getElementById(participant.sid); participantDiv.parentNode.removeChild(pa rticipantDiv); }; window.onLeaveButtonClick = function(room){ room.localParticipant.tracks.forEach((publi cation) => {
, const track = publication.track; track.stop(); const elements = track.detach(); elements.forEach((element) => element.remove()); }); room.disconnect(); window.location = '/'; }; This function will generate the local video and audio track and publish it in the Twilio cloud for the specific room using a token. And display your local video in DOM. It will do the same for other remote users of the same room and display the remote user’s video in your DOM.
, When you click on the disconnect button, It will remove your video locally and from the Twilio room and redirect you to the index page. Now call this function from your show page of the room. Add the below code in views/rooms/show.html.erb <script> $(document).ready(function() { setTimeout( function() { joinRoom("<%= @room_name %>","<%= @token %>"); }, 2000); }); </script>
, Now go to your root path and create a room. After that, go to the show page of that room and wait 3-4 sec while Twilio js is loaded from CDN. Copy that URL and paste it into the incognito tab, and Here we go. Your video call app is ready. The entire source code is available here: twilio-video-chat-app
, Conclusion
, I hope the tutorial was helpful, and you have decided to build your video chat application with Twilio, Rails, and JS. If you’re a ROR enthusiast, then the ROR tutorials page is for you! Visit the Ruby on Rails tutorials page; feel free to clone the github repository and play around with the code. Write to us if you have any questions or suggestions. Even after following the tutorial, you might face some real-time errors and problems. In such scenarios, it would be advisable to hire experienced developers. Looking for skilled and dedicated ROR developers to integrate a video chat feature into your application? Without wasting a second, contact us to hire ROR developer.
, Thank You www.bacancytechnology.com

Build a video chat application with twilio, rails, and javascript (part 1)

  • 1.
    Build a Video Chat Application withTwilio, Rails, and Javascript (Part 1) www.bacancytechnology.com
  • 2.
  • 3.
    Want to developyour own video chat app? But, not sure where to start? Don’t worry at all! We are here with a tutorial that will help you build your own video chat application. Don’t limit yourself, and start exploring with us! Here, we will learn with an example and build a one-to-one video chat application with Twilio, Rails, and Javascript. With this application, you can easily video chat with your family and friends.
  • 4.
  • 5.
    Before building theTwilio video chat application, look at the video below to have a rough idea of the demo. The video chat app development will consist of three major sections – User Interface using Javascript + HTML + CSS, Twilio Basic Set-Up, and Business Logic to Build a Video Chat App. https://youtu.be/IoGb6jo9bgs
  • 6.
  • 7.
    Twilio account Ruby version2.6.2 Node version 14.8.0 Rails version 6 Bundler to install dependencies
  • 8.
  • 9.
    2.6.2 ruby version 6.0.4.1Rails version 14.8.0 node version. Before getting started with the demo application, here’s my system set up- Create a new rails application using the below commands rails new twilio-video-call cd twilio-video-call Then, run the following command to install dependencies – bootstrap, jQuery, and popper.js yarn add bootstrap@4.3.1 jquery popper.js
  • 10.
    After this, addthe following code in the config/webpack/environment.js file. const { environment } = require('@rails/webpacker') const webpack = require("webpack") environment.plugins.append("Provide", new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', Popper: ['popper.js', 'default'] })) module.exports = environment // config/webpack/environme nt.js file
  • 11.
    Go to app/assets/stylesheets/application.css andadd the following line above the require_tree and require_self lines. *= require bootstrap And add this code in application.js require("jquery") import $ from 'jquery'; window.jQuery = $; window.$ = $;
  • 12.
  • 13.
    Now, it’s timeto create a Model, View, and Controller using Scaffold once we have a basic setup. Use the below command to do the same. rails g scaffold room name:string After that, go to the migration file and add the unique_name and room_sid field to the migration. We will use this in the future. Now your migration will look like this. class CreateRooms <ActiveRecord::Migration[6.0] def change create_table :rooms do |t| t.string :name t.string :unique_name t.string :room_sid t.timestamps end end end
  • 14.
    Go to theconfig/routes.rb file and add the root path for your app. root to: "rooms#index" After that, migrate the database using. rails db:migrate After that, go to this URL http://localhost:3000/. Congratulations! If you see this screen, your app is working. Now let’s create the random string as a unique name for each room. Add this code to the room.rb model.
  • 15.
    before_create :add_uniqe_name def add_uniqe_name unlessself.unique_name.present? self.unique_name = (0...15).map { ('a'..'z').to_a[rand(26)] }.join end end // room.rb This will create a unique random string for the unique_name field whenever a new room is generated. Moving on further with the tutorial to build a video chat application with Twilio, Rails, and JS. Here, we are done with creating a room. Now, let’s set up a Twilio account and store its credentials.
  • 16.
  • 17.
    For that, weare going to use Twilio Programmable video. For this, we need a Twilio account. Click here to create an account if you don’t have any. Add Gems into gemfile gem 'twilio-ruby' gem 'dotenv-rails' Run bundle bundle install
  • 18.
  • 19.
    After that, goto your Twilio dashboard and copy the ACCOUNT SID and AUTH TOKEN. For storing credentials, we are going to use dotenv. Create a .env file in the root directory of the project. And Add the following line in config/application.rb. dotenv::Railtie.load For this tutorial, I’m going to create that file in the twilio-video-call folder. If you use git for version control, don’t forget to add this file in gitignore.
  • 20.
    Go to theAPI Key section and click the red plus sign to create a new API key. Give your key a recognizable name representing the project you’re working on in the Friendly Name text field and leave the Key Type Standard. Click the button that says Create API Key. Assign those keys to API_KEY_SID and API_KEY_SECRET. Add those credentials in the .env file.
  • 21.
    Business Logic to Build aVideo Chat Application with Twilio, Rails
  • 22.
    // controllers/rooms_controller.rb def show @client= Twilio::REST::Client.new(ENV['ACCOUNT_S ID'], ENV['AUTH_TOKEN']) unless @room.room_sid.present? # create room in twilio twilio_room = @client.video.rooms.create(type: 'peer-to- peer',unique_name: @room.unique_name) @room.update(room_sid: twilio_room.sid) end identity = (0...5).map { ('a'..'z').to_a[rand(26)] }.join @room_name = @room.unique_name Create Twilio Room Change the Show action’s code with the following code.
  • 23.
    #create token toaccess Twilio room @token = Twilio::JWT::AccessToken.new(ENV['ACCOU NT_SID'], ENV['API_KEY_SID'],ENV['API_KEY_SECR ET'], identity: identity) #create video grant for token grant = Twilio::JWT::AccessToken::VideoGrant.new grant.room = @room_name @token.add_grant grant @token = @token.to_jwt end This code will first check the presence of sid (unique id used for Twilio unique rooms) in the database. If it is not available, it will generate the room in Twilio and store the sid in the database.
  • 24.
    We are creatinga unique string as a unique identifier for the Twilio room. (You can use the logged-in user’s name for it.) It will create the Twilio token and video grant.
  • 25.
  • 26.
    For building auser interface, open views/rooms/show.html.erb and use the below code. You can change the styling part as you like. // views/rooms/show.html.erb.
  • 27.
    <div class="row"> <div class="col-9"> <divid="remote-video"> </div> </div> <div class="col-3"> <div id="local-video"> </div> </div> </div> <div class="row buttons-panel mb-5"> <div class="col-12 d-flex justify-content- center align-items-center"> <button class="btn btn-danger p-3 rounded-circle d- none" id="call-end-btn> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-telephone-x-fill" viewBox="0 0 16 16">
  • 28.
    <path fill-rule="evenodd" d="M1.885.511a1.745 1.7450 0 1 2.61.163L6.29 2.98c.329.423.445.974.315 1.494l-.547 2.19a.678.678 0 0 0 .178.643l2.457 2.457a.678.678 0 0 0 .644.178l2.189-.547a1.745 1.745 0 0 1 1.494.315l2.306 1.794c.829.645.905 1.87.163 2.611l-1.034 1.034c-.74.74-1.846 1.065- 2.877.702a18.634 18.634 0 0 1-7.01-4.42 18.634 18.634 0 0 1-4.42-7.009c-.362-1.03-.037- 2.137.703-2.877L1.885.511zm9.261 1.135a.5.5 0 0 1 .708 0L13 2.793l1.146-1.147a.5.5 0 0 1 .708.708L13.707 3.5l1.147 1.146a.5.5 0 0 1-.708.708L13 4.207l-1.146 1.147a.5.5 0 0 1-.708-.708L12.293 3.5l-1.147-1.146a.5.5 0 0 1 0-.708z"/> </svg> </button> </div> </div>
  • 29.
    Add the followingcss style code in app/assets/stylesheets/rooms.scss buttons-panel{ position: fixed; bottom: 0; width: 100%; } #remote-video{ border-radius: 15px; video{ width: 100%; height: 770px; border-radius: 15px; } } #local-video{ border-radius: 15px; video{ border-radius: 15px; width: 100%; height: 300px; } }
  • 30.
  • 31.
    Let’s write thecode for connecting Twilio rooms. Include the Twilio js in the show.html.erb file <%= javascript_include_tag 'https://media.twiliocdn.com/sdk/js/video/r eleases/2.3.0/twilio-video.min.js' %> Create a video_call.js file in the javascript/packs folder and include that file from application.js. And add the following code in that file.
  • 32.
    // video_call.js , window.joinRoom =async function(room, token){ const Video = Twilio.Video; const localTracks = await Video.createLocalTracks({ audio: true, video: { height: 1080, frameRate: 24, width: 1980 }, }); try { room = await Video.connect(token, { name: room, tracks: localTracks, bandwidthProfile: { video: { mode: 'collaboration',
  • 33.
    , maxTracks: 10, dominantSpeakerPriority: 'high', renderDimensions:{ high: {height:1080, width:1980}, standard: {height:720, width:1280}, low: {height:176, width:144} } } }, dominantSpeaker: true, maxAudioBitrate: 16000, preferredVideoCodecs: [{ codec: 'VP8', simulcast: true }], networkQuality: {local:1, remote: 4} }); } catch (error) { console.log(error); } const localMediaContainer = document.getElementById("local-video"); localTracks.forEach((localTrack) => { l
  • 34.
    , ocalMediaContainer.appendChild(localTrac k.attach()); }); // display video/audioof other participants who have already joined room.participants.forEach(onParticipantCo nnected); room.on("participantConnected", onParticipantConnected); room.on("participantDisconnected", onParticipantDisconnected); $("#call-end-btn").removeClass("d-none"); $("#call-end-btn").on("click",function() { onLeaveButtonClick(room); }) };
  • 35.
    , window.onParticipantConnected = function(participant){ var remote_div= document.getElementById('remote-video'); const participantDiv = document.createElement('div'); participantDiv.id = participant.sid; const trackSubscribed = (track) => { participantDiv.appendChild(track.attach()); }; participant.on("trackSubscribed", trackSubscribed); participant.tracks.forEach((publication) => { if (publication.isSubscribed) { trackSubscribed(publication.track); } }); remote_div.appendChild(participantDiv);
  • 36.
    , const trackUnsubscribed =(track) => { track.detach().forEach((element) => element.remove()); }; participant.on("trackUnsubscribed", trackUnsubscribed); }; window.onParticipantDisconnected = function(participant){ const participantDiv = document.getElementById(participant.sid); participantDiv.parentNode.removeChild(pa rticipantDiv); }; window.onLeaveButtonClick = function(room){ room.localParticipant.tracks.forEach((publi cation) => {
  • 37.
    , const track =publication.track; track.stop(); const elements = track.detach(); elements.forEach((element) => element.remove()); }); room.disconnect(); window.location = '/'; }; This function will generate the local video and audio track and publish it in the Twilio cloud for the specific room using a token. And display your local video in DOM. It will do the same for other remote users of the same room and display the remote user’s video in your DOM.
  • 38.
    , When you clickon the disconnect button, It will remove your video locally and from the Twilio room and redirect you to the index page. Now call this function from your show page of the room. Add the below code in views/rooms/show.html.erb <script> $(document).ready(function() { setTimeout( function() { joinRoom("<%= @room_name %>","<%= @token %>"); }, 2000); }); </script>
  • 39.
    , Now go toyour root path and create a room. After that, go to the show page of that room and wait 3-4 sec while Twilio js is loaded from CDN. Copy that URL and paste it into the incognito tab, and Here we go. Your video call app is ready. The entire source code is available here: twilio-video-chat-app
  • 40.
  • 41.
    , I hope thetutorial was helpful, and you have decided to build your video chat application with Twilio, Rails, and JS. If you’re a ROR enthusiast, then the ROR tutorials page is for you! Visit the Ruby on Rails tutorials page; feel free to clone the github repository and play around with the code. Write to us if you have any questions or suggestions. Even after following the tutorial, you might face some real-time errors and problems. In such scenarios, it would be advisable to hire experienced developers. Looking for skilled and dedicated ROR developers to integrate a video chat feature into your application? Without wasting a second, contact us to hire ROR developer.
  • 42.