
Adding PubNub Chat to an Agora Video Web App
Digital communication is ubiquitous in society, and more teams are looking to add voice, video, and text chat features to their products. Agora and PubNub offer tools that enable teams to quickly and easily build real-time applications that utilize voice, video, and text chat features to connect their users in more meaningful ways.
In this tutorial, I will show you how to integrate the PubNub Web SDK to add text-based chat to a web app that uses the Agora Web SDK for voice and video communication.
For the TL;DR crowd check out the live demo. *Agora and PubNub accounts are required.
Prerequisites
- A simple web server (I like to use Live Server)
- An Agora developer account (see How To Get Started with Agora)
- A PubNub developer account (https://bit.ly/2JgzK11)
- An understanding of HTML, CSS, JS
- An understanding of how Bootstrap and JQuery function (minimal knowledge needed)
Project Setup
To start, let’s use the code from my tutorial “Building a group video chat web app” as our base project. This project has all the features for basic video chat: toggles for camera and mic, and buttons to join and leave the call.
Build
The build phase of this tutorial covers modifying the input form to add inputs for the PubNub keys, adding the chat UI, integrating a PubNub client, connecting the PubNub client to a channel, and using the client to send and receive messages in the channel.
Update the Form
In the “Building a group video chat web app” tutorial, I hard-coded the App ID, channel name, token, and UID values in the agora-interface.js
file. But in the base project I have since updated the code to include an input form to enter the App ID, token, and channel name.
This project uses the existing modal form and adds new inputs to the join modal for the PubNub keys. Open index.html
and update the modalForm
to include text input for the PubNub publish and subscribe keys.
Add the Chat UI
Next, we add the chat UI directly below the join modal. The chat uses a floating action button to toggle the chat window. The chat window has a div to display the messages, as well as a textarea
for inputting the message and a send button.
I used this CodePen demo as a guide for the chat UI.
Init the Agora and PubNut Clients
In the base project, when the user clicks the Join Channel button, it gets the App ID, token, channel name, and UID and passes them to the initCleintandJoinChannel
function that initializes the Agora client and joins a channel. We want to add similar functionality to our PubNub integration. To do this, update the on-click
event listener to also get the PubNub key values and pass them to the function initPubNub
, which we use to initialize the PubNub client.
PubNub Interface
Now that the Join Channel button expects the initPubNub
function, we need to declare it. Let’s start by creating pubnub-interface.js
, to handle the PubNub client events. Within the initPubNub
function, create a new PubNub client, add event listeners, and subscribe to the channel.
You’ll notice in the code above the message
event listener. The message
event is triggered when a message is received in the channel (including both local and remote messages). For this reason, we have an if
statement to check for whether the message was sent by the local or the remote user, and only pass messages from remote users to addRemoteMsg
. We discuss the addRemoteMsg
function later, when we implement the chat UI code. In this demo, we only print
to the console
when a local message is received in the channel, but you can easily extend this demo by implementing a “delivered” message to the user. This provides a visual differentiation to the user, between “sent” and “delivered” states.
Next, in the pubnub-interface.js
file add a publishMessage
function. This function is used within the chat UI to send messages into the PubNub channel. The publishMessage
function accepts two parameters: the message
to be sent into the PubNub channel and a callback
function, to update the chat UI after the message is sent.
Control the Chat UI
Now that we have our chat UI and the ability to send messages, we need to connect the two. Create a chat.js
file, which we use to add event listeners to toggle the chat UI, send messages, and display the messages in the chat channel.
First, get a reference for the send button and the input textarea
. Everytime the user clicks the sendBtn
, we want to get the contents of the textarea, convert line breaks into HTML using <br/>
, and then publish the message into the PubNub channel and also add it as a local message to the chat area.
You’ll notice two functions, resizeTextArea
and scrollToBottom
, which are used to update the UI. The resizeTextArea
function sets the height of the textarea
based on the input. We call this function when we clear the chat and after every keyup
event. The scrollToBottom
function scrolls to the bottom of the chat area so that the window appears to react dynamically as new messages populate the chat.
The last part of the chat UI that we need to handle is to hide and show the chat UI. For this example, we use a floating action button (FAB) which is represented by the chatToggleBtn
that the user clicks to hide and show the chat window (chatMsgwindow
). Within our button we have an icon that we change depending on whether the chat is visible or hidden. Whenever we make the chat window visible, we want to scroll to the bottom of the chat to the latest message.
Disable Keyboard Shortcuts
In the base project, there are keyboard shortcuts to mute
or unmute
the audio and video, to start
and stop
screen-sharing, and to quit the call. We need to update the keyboard listeners in ui.js
to ignore keyboard shortcuts when the chat window is visible. We also want to add a key listener to send the text input when the user taps the Return
key.
To allow the user to input multiline messages, we use Shift+Return
input for a new line and Return
key input for sending the message.
Testing
To test our video chat app we must spin up a simple web server (I like to use Live Server). The web server requirement is due to browser restrictions when accessing the camera on the device. For local testing purposes localhost://
is white-listed by browsers. But to test with friends, we can use a service like Ngrok to generate a secure HTTPS
url. Ngrok is a freemium service that creates this tunnel out from your local machine and provides an HTTPS
url for use. In my experience, this is one of the simplest ways to run an HTTPS
secured web server on your local machine.
When the server is ready, open your browser to localhost:xxxx
(xxxx denotes the port number) and input your Agora and PubNub credentials, along with the channel name and the UID.

If you want to test before you build, you can check out the live demo here.
Done!
And just like that we are done! In case you weren’t coding along or want to see the complete finished product, all the code is available on GitHub.
Other Resources
For more information about the Agora applications, take a look at the Agora Video Call Quickstart Guide and Agora API Reference. For more information about PubNub applications, check out the PubNub Chat Overview.
I also invite you to join the Agora Developer Slack community.