Create a multi-tab chat popup
Estimated reading time: 9 minutesThis article will describe the implementation of a web-based chat popup app, having real-time messaging, voice, and video calls that can be opened and viewed simultaneously on multiple-tabs.
Many developers and teams have built chatbots, custome support services, etc using mesibo. Mesibo Messenger is a simple web app, that demonstrates using mesibo APIs to build such applications which supports popups running on a single tab with a single mesibo connection. But, what if you want to build apps where the app runs on multiples tabs?
For example, let’s say you are building a customer support chat app - that will be used by support agents to answer incoming queries from customers. Support teams are generally very busy and may be chatting with multiple customers at any instant. So, a support agent using your chat popup app, needs to open seperate tabs for each customer simulataneously and reply to each of the customers questions.
You can build a chat support app for the above scenario by using Mesibo Chat Popup as a starting point. But, you need to open multiple tabs for the same user. The first approach that you might think of to implement this, would be to open the same page on multiple tabs and initialize mesibo on each tab. But, when you initialize mesibo in one tab, you open a single connection to mesibo servers. This means, when you try to initialize mesibo on another tab, you are attempting to connect to mesibo with the same user. But at any instant, there can be only one mesibo connection per user. So, your earlier connection will be closed by mesibo and you will be logged out on the other tab. You need a way to retain messages while switching between multiple tabs, and this plain approach, clearly will not work.
One way to overcome this problem would be to create new users with every tab. But, this is not recommended. Logically, you only have one user at your end and so, it would be inefficient to have duplicate users. You will also have more latency and bandwidth needs, as you have more connections. Every message sent from each tab on a seperate connection, will have to go to mesibo servers and receive the delivery/read status. Instead you can maintain a single connection to mesibo with
Chat Popup Features
The chat popup app has fully functional real-time messaging, voice, and video calling. Some of the key features are
- Multi-tab support
- One-to-One Messaging, Voice and Video Call
- Group Messaging
- Read receipts
- Send Files
- Record and Send live audio from microphone
- Send photos captured live using Webcam
- Chat history
- Link Preview
You can download and modify the complete source code of the chat popup app from Github
Prerequisites
Before we dive into building a multi-tab chat popup, ensure that you’ve read the following.
- Get Started Guide.
- Tutorial on Writing your First mesibo Enabled Application.
- First Javscript App.
- Mesibo Sample Web apps: Sample Js App, Messenger
- For multi-tab support, we will use the concept of Shared Workers. You can learn about how you can initialize and connect to mesibo on a shared worker, switching between active workers/tabs here
It is expected that you are already familiar with the mesibo Javascript API and you have created basic apps using mesibo API. If you have not, ensure that you read the get-started and first-app tutorial mentioned above and try simple apps before proceeding with this tutorial.
Let’s get started.
Download the source code
Download the chat popup app source from Github
git clone https://github.com/mesibo/messenger-javscript.git
Configure Mesibo
Edit mesibo/config.js
and provide the AUTH TOKEN
& APP ID
.
Obtain the AUTH TOKEN
and APP ID
for a user from Mesibo Console. You can also generate the token for the Web app from Mesibo Demo App Token Geneartor. Provide APP ID
as console
.
See the Preparation Guide to learn about creating users
const MESIBO_ACCESS_TOKEN = "xxxxxxx";
const MESIBO_APP_ID = "xxxx";
const MESIBO_API_URL = "https://app.mesibo.com/api.php"
If you are hosting mesibo-backend on your server, you need to change the API URL to point to your server.
Configure Popup
Configure the following for setting the displayed user avatar and destination user(to which all messages will be sent to) in mesibo/config.js
.
const POPUP_DISPLAY_NAME = "xxxx"
const POPUP_DISPLAY_PICTURE = "images/profile/default-profile-icon.jpg"
const POPUP_DESTINATION_USER = 'xxxx';
Initialize Mesibo
As discussed here the initialization of mesibo API functions and callbacks will be handled by a Web Worker defined in mesibo-worker.js
.
So, in your app script initialize mesibo as follows:
// Instead of directly accessing Mesibo APIs like so,
// $scope.mesibo = new Mesibo();
// use a wrapper API that uses a shared worker
$scope.mesibo = new MesiboWorker($scope);
$scope.mesiboNotify = $scope;
//Initialize Mesibo
$scope.mesibo.setAppName(MESIBO_APP_ID);
$scope.mesibo.setCredentials(MESIBO_ACCESS_TOKEN);
$scope.mesibo.setListener($scope);
$scope.mesibo.setDatabase("mesibo");
$scope.mesibo.start();
When you call MesiboWorker.start
, a start
message is sent to the shared worker
//mesibo-worker.js
MesiboWorker.prototype.start = function(){
var post = {op: "start"};
this.mesibo_worker.port.postMessage(post);
}
On the shared worker end, we will then initialize mesibo
//mesibo-shared.js
if(op == "start"){
send_mesibo_init(port);
}
send_mesibo_init = function(port) {
if(mesibo_api_init) {
mesibo_api_init = false;
//initialize mesibo
send_to_port(port, "init", null);
active_port = port;
}
}
In our shared worker, We will only initialize and connect to mesibo once — when a tab connects for the first time. After that, the tab that connected via that port is set to be active. This active mesibo port is used to connect to mesibo, send messages, make calls, etc directly through Mesibo APIs.
//mesibo-worker.js
case "init":
console.log("Received init message from shared worker");
this._mesibo_init();
break;
Sending Messages
For example, to send a message you call the sendMessage
function and a message is posted to the shared worker for a sendMessage
operation.
//mesibo-worker.js
MesiboWorker.prototype.sendMessage = function(p, id, m){
var post = {op: "sendMessage", id: id, message: m, params: p};
this.mesibo_worker.port.postMessage(post);
}
The shared worker receives this message and forwards the message parameters to the active port. Also, all the other connected tabs will be notified of the message sent through a Mesibo_OnMessage
callback.
//mesibo-shared.js
if(op == "sendMessage") {
// send it to active port to send message
send_to_port(active_port, null, data);
//Inform all the tabs about new message
var p = {};
p.m = data.params;
p.data = new TextEncoder().encode(data.message);
console.log("inform everyone..", p);
send_to_all("Mesibo_OnMessage", p);
}
Now, only the active port will get the sendMessage
call and will inturn call Mesibo API function sendMessage
to the required destination.
//mesibo-worker.js
case "sendMessage":
// send message for this and other tab
if(this.mesibo_api)
this.mesibo_api.sendMessage(o.params, o.id, o.message);
break;
Receiving Messages
Similar to sending messages being handled by the active port, only the active port will receive the messages from Mesibo through the Mesibo_OnMessage
callback. The active port must forward this to all other connected ports. The active port connected to mesibo, forwards all such data(like Mesibo_OnConnectionStatus
, Mesibo_OnMessageStatus
, etc) received through callbacks.
//mesibo-worker.js
MesiboNotifyForward.prototype.Mesibo_OnMessage = function(m, data) {
console.log("Forwarding Mesibo_OnMessage: from " + m.peer + " id: " + m.id);
var p = {op: "Mesibo_OnMessage", data:{'m':m, 'data': data} };
this.worker.port.postMessage(p);
this.client_notify.Mesibo_OnMessage(m, data);
}
Once the shared worker gets this it sends it to all connected ports.
//mesibo-shared.js
if(op.startsWith("Mesibo_On")) {
send_to_all(null, data);
}
Similarly, you can define worker functions for sending files, making calls, etc. You also need to switch the active tab when a currently active tab is closed.
Launch the Popup
Open the page index.html
in your browser. Click on the floating circle in the bottom-right corner to launch the popup window. You can open index.html
simultaneously in as many tabs as you like