Build an app with information-rich “Who’s online” feature

Being able to see “who’s online” is an important feature for many applications. For instance, chat rooms, teams collaborating in real time on a document, audiences in a live video stream, users viewing the same web page, and players within an online game. All benefit from the visibility of who they’re interacting with.
Presence channels are the go-to solution for Pusher users working on those scenarios. This channel type notifies subscribed connections about other users joining or leaving the channel. With our User Authentication feature, it is even easier to use Presence channels. User Authentication helps automate development around identifying users trying to connect and subscribe. To learn how we use and define these Pusher-specific terms, check out the Pusher Glossary.
Let’s take a look at an application that takes advantage of the two features in tandem.
How to use Presence channels with User Authentication
Let’s take an example of the chat room use case. How can you use User Authentication and Presence channels to implement the “who’s online” feature with rich user information?
The user_info
you choose to provide can be any identifiable. Any user-specific details that are relevant to your application. You may want users to be able to see contact information, social pages, a role, icon, nickname, or anything else.
In this case, we’re interested in seeing users’ icons, names, and the admin authority they have in the channel.
Imagine that the chat application we want to build has the following features:
- The user logs into the chat app
- When the user joins a chat room, they can view the other users in that chat room
- The application has different types of chat rooms with different functionalities. From “business” or “hobbies”.
- In “hobbies” chat rooms, the user can see the name and icon of each user indicating their presence in the room
- In “business” chat rooms, the name and icon are also displayed in addition to a flag for the admin of this chat room
The following sections will take you through the steps needed to integrate Pusher with our example chat application. Then implement the “who’s online” feature for the two chat rooms.
Step 1: Initialize Pusher
You can use Pusher on any client device. Whether it’s a mobile phone with Android or iOS operating system, or on any web browser. We’ll be using pusher-js which is the JavaScript client SDK for Pusher for web browsers.
If you don’t have a Pusher account yet, sign up. Now let’s get started!
Here’s how to initialize the SDK.
Client side – JavaScript
const Pusher = require('pusher-js');
const pusher = new Pusher(APP_KEY, {
cluster: APP_CLUSTER,
userAuthentication: {
endpoint: '/pusher/user-auth',
}
channelAuthorization: {
endpoint: '/pusher/auth',
},
});
Code language: JavaScript (javascript)
NOTE: You need to enter the APP_KEY
and APP_CLUSTER
which you get when you create a new Channels app on pusher.com. To get the app key and app cluster, log in to the Pusher dashboard, click the Channels project you’re working on > App Keys.
Step 2: User authentication
Pusher allows you to indicate which user is currently logged in. This is handy for many user-related features like server-to-user messaging and terminating user connections.
In this example, User Authentication will be used as an add-on feature to Presence Channels. This is to provide more details about the user connected.
On the client side, you need to initiate the user authentication flow:
Client side – JavaScript
Code language: JavaScript (javascript)pusher.signin();
This will result in an HTTP call to the user authentication endpoint `/pusher/user-auth`
configured above in `userAuthentication`. You need to implement this endpoint in your server code.
Here’s an example implementation for this endpoint in Node.js using the Node.js SDK for Pusher:
Server side – Node.js
const Pusher = require("pusher")
const express = require("express")
const bodyParser = require("body-parser");
const pusher = new Pusher({
appId: APP_ID,
key: APP_KEY,
secret: APP_SECRET,
cluster: APP_CLUSTER,
});
const app = express()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post("/pusher/user-auth", async function (req, res) {
// Find the logged in user. This step comes from your
// system depending on Headers or Cookies
user = whoIsLoggedIn();
const userData = {
id: user.id,
user_info: {
name: user.name,
icon: user.icon,
}
}
const socketId = req.body.socket_id;
const auth = pusher.authenticateUser(socketId, userData);
res.send(auth);
});
app.listen(9000);
Code language: PHP (php)
NOTE: You need to enter the APP_ID
, APP_KEY
, APP_SECRET
, and APP_CLUSTER
. You get these when you create a new Channels app on pusher.com. To get the app key and app cluster, log in to the Pusher dashboard, click the Channels project you’re working on > App Keys.
When the user authentication endpoint is called, your server should be able to identify the currently logged in user using cookies or headers. You can further configure the HTTP call to the user authentication endpoint using 'userAuthentication'
fields on the client SDK.
After identifying the logged in user, your server needs to provide a `userData`
object with the ID of the user. Additionally, you can provide more information about the user in the `user_info
` field. For example, their name and a link to their icon. The information is shared with other members of Presence channels when this new user joins.
Here’s a sequence diagram to illustrate the Presence channels and user authentication process workflow.

Step 3: Presence channels and who’s online
Each chat room in this application will be represented by a Presence Channel which is named using `presence-`
. For example, the chat room called “gaming” will use the channel `presence-gaming`
.
The client side of your application can subscribe to a Presence channel via the client SDK as follows:
Client side – JavaScript
const presence_gaming = pusher.subscribe('presence-gaming');
Code language: JavaScript (javascript)
Subscribing to a Presence channel will result in an HTTP call to the channel authorization endpoint `/pusher/auth`
configured above in `channelAuthorization`
. You need to implement this endpoint in your server code. Here’s an example implementation for this endpoint in Node.js:
Server side – Node.js
app.post("/pusher/auth", async function (req, res) {
const socketId = req.body.socket_id;
const channel = req.body.channel_name;
const auth = pusher.authorizeChannel(socketId, channel);
res.send(auth);
});
Code language: JavaScript (javascript)
Through this endpoint, you can allow or deny access to Presence channels depending on the logged in user. The code example allows access to all Presence channels. You can modify the code according to your needs.
On the client side, you can bind functions to be called when a user joins or leaves a Presence channel as follows.
Client side – JavaScript
presence_gaming.bind("pusher:member_added", (member) => {
console.log(`Member added: ${JSON.stringify(member)}`);
});
presence_gaming.bind("pusher:member_removed", (member) => {
console.log(`Member removed: ${JSON.stringify(member)}`);
});
Code language: JavaScript (javascript)
The `member`
object will look like this:
{
"id": "<id>",
"info": {
"name": "<name>",
"icon": "<icon>"
}
}
Code language: JSON / JSON with Comments (json)
Notice that this `member`
object comes from the `userData`
object during user authentication.
For example, a user named Emily is the first one to join the Presence channel `presence-gaming`
. Then another user named John joins the same channel. Emily will be notified with the `pusher:member_added`
event which contains a `member`
object with information about John. Now Emily knows that someone else is in the channel with her, and who they are.
You can also access all the members in a Presence channel as follows:
Client side – JavaScript
presence_gaming.members
Code language: CSS (css)
How to provide channel-specific user information to Presence channels
Providing user information during user authentication using the `userData` object is convenient as it will be shared in all presence channels that the user joins.
However, there are cases where the user information needs to be different for specific Presence channels. This use case is also supported by providing a channel-specific user information through the channel authorization endpoint as follows:
Server side – Node.js
app.post("/pusher/auth", async function (req, res) { const socketId = req.body.socket_id;
const channel = req.body.channel_name;
const channelData = {
user_id: `<id>`,
user_info: {
name: `<name>`,
icon: `<icon>`
}
}
const auth = pusher.authorizeChannel(socketId, channel, channelData);
res.send(auth);
});
Code language: JavaScript (javascript)
Notice that the call to `authorizeChannel`
has an additional parameter called `channelData`
. You can pass a channel specific user object using this parameter.
In the example application we’re developing for this blog post, this channel-specific user information feature is useful for the business type of chat rooms. Because the user information needs to indicate the admin of this chat room so that people know who to contact in case an admin is needed.
The server side can provide a different set of information for business channels. On the other hand, the hobbies channels can keep using the user information retrieved from User Authentication.
Here’s a code example:
Server side – Node.js
app.post("/pusher/auth", async function (req, res) {
const socketId = req.body.socket_id;
const channel = req.body.channel_name;
if (channel.startsWith(`presence-business-`)) { // Find the logged in user. This step comes from your
// system depending on Headers or Cookies
user = whoIsLoggedIn();
const channelData = {
user_id: user.id,
user_info: {
name: user.id,
icon: user.icon,
isAdmin: user.isAdmin,
}
}
const auth = pusher.authorizeChannel(socketId, channel, channelData);
} else {
const auth = pusher.authorizeChannel(socketId, channel);
}
res.send(auth);
});
Code language: JavaScript (javascript)
Build your next “who’s online” project using Presence Channels
Pusher Channels helps you to build fully-featured presence views and implement different use cases related to “who’s online”. Presence channels can be used to send realtime messages about the members of the channel, with User Authentication providing the context which identifies who the user is. You can also offer channel-specific information for each user if needed.
To get started with your next live presence project, sign up. If you need any help, reach out to our support team.
August 24, 2022
Ready to begin?
Start building your realtime experience today.
From in-app chat to realtime graphs and location tracking, you can rely on Pusher to scale to million of users and trillions of messages