Wouldn’t it be great if you could start an audio and video chat with any co-worker from inside Salesforce?

Well, that’s now possible through a cool integration between GoInstant (a company Salesforce acquired in 2012), WebRTC and Visualforce. Before we get into how it works and share some code with you, let’s dig into the individual pieces of the puzzle.

What is GoInstant?

GoInstant is a backend-as-a-service (BaaS) for building real-time applications. It allows you to store and synchronize data very easily. Think of applications where you need multiple users communicating, or you need data being displayed to people as fast as possible. There are lots of interesting use cases for GoInstant — and you can sign-up for free to give it a try at https://goinstant.com.

What is WebRTC?

WebRTC (or Web Real-Time Communication) is a new API being made available natively in your web browser to enable video/voice calling and P2P file transfer using JavaScript and HTML5. WebRTC handles the complicated networking and audio/video components necessary for this type of real-time communication. Best of all, the WebRTC framework is available in supported browsers without the need for any plugins. To learn more, check out webrtc.org.

 

How do GoInstant and WebRTC work together?

GoInstant recently launched an integration between its core API and WebRTC to provide you with the easiest way to setup WebRTC in any application.

GoInstant provides two key pieces that WebRTC is missing — specifically, presence and signalling. Both of these are left to the application developer when using WebRTC on its own, which means you need to setup and configure a backend and handle the complexities of getting WebRTC working. GoInstant comes with ready made solutions to the lack of presence and signalling in WebRTC. Presence is built into our Rooms API, while Keys and Channels are ideal for signaling. Keys are great for keeping track of which users have their camera turned on, and Channels are perfect for the type of one-off messages used in the WebRTC session negotiation.

So GoInstant built GoRTC, a lightweight (218 SLOC) library, which makes it incredibly easy to integrate WebRTC into your application. You don’t need a server or backend whatsoever. GoRTC is also open source!

GoInstant extended their base library into what they call a widget — specifically the WebRTC widget. It has additional functionality built in that you can use out of the box, including standard audio/video controls for pausing, muting and expanding a user’s video stream.

You can see all of this come together in a slick demo of GoInstant’s WebRTC integration, where you can video and audio chat with friends: http://webrtc.goinstant.com.

Here’s how GoInstant’s WebRTC widget works:

<script type="text/javascript" src="https://cdn.goinstant.net/v1/platform.min.js"></script>
<script type="text/javascript" src="https://cdn.goinstant.net/widgets/webrtc/latest/webrtc.min.js"></script>

<!-- CSS is optional -->
<link rel="stylesheet" href="https://cdn.goinstant.net/widgets/webrtc/latest/webrtc.css" />

// Connect URL
var url = 'https://goinstant.net/YOURACCOUNT/YOURAPP';

// Connect to GoInstant
goinstant.connect(url, function(err, platformObj, roomObj) {
    if (err) {
       throw err;
    }
    // Create a new instance of the WebRTC widget
    var webrtc = new goinstant.widgets.WebRTC({
       room: roomObj
    });
    // Initialize the WebRTC widget
    webrtc.initialize(function(err) {
        if (err) {
            throw err;
        }
        // The widget should now be rendered on the page
    });
});

It’s really as easy as that. You could include similar code into your own application and have audio/video chat ready to go!

So how does this all fit with Visualforce?

We’re big fans of WebRTC (which is gaining in popularity within the enterprise space), and we were really impressed with GoInstant’s integration. But we wanted to add audio and video chat directly into Salesforce. And that’s exactly what we did.

We took the GoInstant WebRTC code (which is all open source) and integrated it into a Visualforce page. We then added a link to a person’s individual profile page so that you could audio/video chat with them when they’re online.

Here is what it looks like with a single user in a video room embedded in the Chatter Feed!

Here is what it might look like as a full Visualforce page!

 

It’s a simple implementation inside of Visualforce, but you could extend it quite a bit. You could add live audio/video chat to anything inside Salesforce — imagine being able to collaborate and chat around a sales lead, or when reviewing a quarterly report!

Let’s take a look at some of the code and what’s going on:

<apex:page showHeader="false" controller="ProfilePic" standardStylesheets="false" sidebar="false" title="Text Synchronization App" >

    <h2>Room is <span id="roomname"></span></h2>

    <c:VideoChat video-width="200px" />
    <c:VisUserList /> 
    <!-- VisUserList is a visualforce component that shows who
         is in the room.  Code is included in the gist at the 
         bottom of this article.
    -->

    <script>
        // The connection url below is available in the GoInstant dashboard. It includes your Account Name
        // and Application Name (you created both when signing up). This url tells GoInstant where your
        // application and account are located in order to connect.

        var url = 'https://goinstant.net/beb37f5b840c/Duderino';
     var userDefaults = {displayName: '{!$User.FirstName}'};
     var token = '{!userToken}';
 var objectid = "{!$CurrentPage.parameters.sfdc.userId}";
     if (objectid === "") {
            objectid = '{!$User.Id}';
        }
    $("#roomname").html(objectid + '</br>' + '{!$CurrentPage.URL}');

    var token = { user: {
 subject: '{!$User.Id}',  // Subject, required claim
       displayName: '{!$User.FirstName} {!$User.LastName}',  // Display Name, private claim
                     avatarUrl: '{!pic}'
              },
           room: objectid
                    };

     console.log("Page id: {!$CurrentPage.parameters.sfdc.userId}");
     console.log('Page url: {!$CurrentPage.URL}');

        goinstant.connect(url, token, function (err, connection, room) {
            if (err) {
                // Could not connect to GoInstant
                throw err;
            }

            var config = {
                room: room,
                listContainer: document.getElementById("userView"),
                expandContainer: document.getElementById("mainView"),
                collapsed: false,
                autoStart: true
            };

            // Create a new instance of the WebRTC widget
            var webrtc = new goinstant.widgets.WebRTC(config);

            // Initialize the WebRTC widget
            webrtc.initialize(function(err) {
                if (err) {
                    throw err;
                }
                // The widget should now be rendered on the page
                console.log(room);
            });

            // You are now connected!
            room.users.get(function(err, usersObj, context) {
                if (err) {
                    // A problem occurred during the get.
                }

                // An array containing the ids of users who have joined the room.
                var userIds = Object.keys(usersObj);

                userIds.forEach(function(id) {
                    console.log(usersObj[id].displayName + ' is in the room!');
                });
            });
            // The listener will fire every time another user joins the room
            room.on('join', function (userData) {
                console.log('user', userData.displayName, 'joined the ' + room.name);
            });

            // The listener will fire everytime a user leaves the Room
            room.on('leave', function (userData) {
                console.log('user', userData.displayName, 'left the lobby!');
            });

            // Retrieve a reference to the current users key
            var userKey = room.self();
            console.log('current users key', userKey);
            userKey.key('displayName').set('{!$User.FirstName} {!$User.LastName}');
 userKey.key('avatarUrl').set('{!pic}');

            // Now use that key to retrieve the current users data
            userKey.get(function(err, value, context) {
                if (err) {
                    // could not retrieve user data
                    throw err;
                }
                console.log('current user', value);
            });

            // The listener will be invoked every time the value of name is changed
            // by another user
            var name = room.key('name');
            var el = $('input[id="sync"]');

            name.on('set', function(value, context) {
                el.val(value);
            });

            el.on('keyup', function() {
                name.set($(this).val());
            });
        });
    </script>
</apex:page>
.

Most of the code above was cut and pasted directly out of the GoInstant sample from the documentation.

It’s really as simple as that! With just a bit of code, we can combine GoInstant, WebRTC and Visualforce to provide audio/video conferencing inside Salesforce. There are tons of possibilities, and lots of ways you could extend this code into your own Salesforce implementation or your own applications.

Here are some links to get started:

Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • http://www.oyecode.com/ Harshit Pandey

    Awesome thanks for sharing, this is Amazing !

  • shoby abdi

    Easy and awesome!

  • Sayeed Faruqi

    Dave – Thanks for posting, Any tweak to make this work on Salesforce1 mobile as global/record specific action ?

  • kishore pasumarty

    Not able to see the results

  • kishore pasumarty

    Dave – I was able to figure it out and got fixed. Does it works with communities too?

    • shoby abdi

      It does! Integrating it with a Community now.

      • kishore pasumarty

        Is any settings need to be configured in Community to make it work?

        • shoby abdi

          Not at all, just make it a Publisher Action and viola. One thing thats annoying is how to keep it from automatically starting to stream

  • Stuart Bernstein

    Any idea when this will work on the iphone?