Sample chat app
We've created a sample direct (1:1) chat app to show you what you can use our Chat SDK for.
Underneath, the app uses a set of basic Chat SDK methods to initialize the SDK, create a sample channel and users, and let you send messages. On the outside, the app comes with a custom UI layer added to show what a final chat app could look like - how you present your own apps, however, is entirely up to you.
Run and test the app first, then read on to understand how it works.
Prerequisites
To run the chat app, make sure to have the following:
-
yarn (>=1.22.19)
-
Node.js (>=18.10.0)
-
Code editor (for example, Visual Studio Code)
-
Publish and subscribe keys to initialize the PubNub object in your app and send and receive messages through the PubNub Network.
Keys setup and configuration
To get both keys, sign in or create an account on the Admin Portal. The autogenerated Demo Keyset in My First App already contains the configuration required to complete this guide (enabled App Context and selected region closest to your location). Follow this guide if you need help creating the keys.
Run the chat app
Check how to set up a 1:1 chat app by running a ready sample React app or adding the Chat SDK to your own app.
- Run a sample React app
- Add Chat SDK to your app
-
Download the
getting-started
app from thejs-chat
repository - the monorepo that houses the source code of the Chat SDK. -
Unpack the archive into the folder of your choice.
-
Open the terminal, navigate to the
js-chat-master
root folder, and install the dependencies.yarn
-
Go to the
lib
folder that contains the TypeScript sources.cd lib
-
Build the app.
yarn build
-
Go to the
samples/getting-started
folder with the app's source code.cd ../samples/getting-started
-
Add required configuration.
Open the app in the code editor and navigate to the
.env.example
file undersamples/getting-started
. Duplicate the file in the same location, rename the copy to.env
, and use it to specify values for your publish and subscribe keys from your app's keyset on the Admin Portal.VITE_PUBNUB_PUB_KEY=
// for example: VITE_PUBNUB_PUB_KEY=pub-c-jbgh67-a796-c36-z81-17dvbf4
VITE_PUBNUB_SUB_KEY=
// for example: VITE_PUBNUB_SUB_KEY=sub-c-jb46h67-z796-g36-z91-19vdfb1Both keys are referenced in the
src/App.tsx
file containing the whole app's source code.const chat = await Chat.init({
publishKey: import.meta.env.VITE_PUBNUB_PUB_KEY,
subscribeKey: import.meta.env.VITE_PUBNUB_SUB_KEY,
userId: randomizedUsers[0].id,
})To associate a sender/current user with the PubNub messages, you must configure the
userId
parameter for your user ID in the database. If you wish, modify the default value for the chat user.For simplicity, the getting started app sets a static
userId
that randomly selects one of the two default users (to simulate a 1:1 conversation). However, if you implement chat in your app, you should generate auserId
per user, device, and server and reuse it for their lifetime. Using separate User IDs in real-life apps is particularly important as it impacts your overall billing and the way your app works. -
Run the app in the terminal.
yarn dev
-
When the app compiles successfully, you will see the link to the localhost in the terminal.
-
You can open the app in two separate browser windows - if you get randomly assigned two different users, simulate a real-life chat conversation.
A sample conversation between a support agent and a customer may look as follows:
-
Open the terminal in the location of your app files and add the Chat SDK package.
yarn add @pubnub/chat
-
Open your application source files in your favorite code editor. Copy the snippet below into your app source file (for example,
src/App.tsx
). To set the placeholder values forsubscribeKey
andpublishKey
with your publish and subscribe keys from the keyset on the Admin Portal, copy the.env.example
file and rename it to.env
. Then use the copy to set values forVITE_PUBNUB_SUB_KEY
andVITE_PUBNUB_PUB_KEY
.
-
Add the app's CSS styles, for example, in
src/App.css
.
-
Run the app in the terminal.
yarn dev
-
When the app compiles successfully, you will see the link to the localhost in the terminal.
-
You can open the app in two separate browser windows - if you get randomly assigned two different users, simulate a real-life chat conversation.
A sample conversation between a support agent and a customer may look as follows:
How this works
Let's walk you through all the Chat SDK methods this app uses to show you what you need to create your own chat. This section analyzes the src/App.tsx
file that contains the app's source file.
Initialize chat
Initialize Chat SDK, providing your publish and subscribe keys from the Admin Portal.
const chat = await Chat.init({
subscribeKey: import.meta.env.VITE_PUBNUB_SUB_KEY,
publishKey: import.meta.env.VITE_PUBNUB_PUB_KEY,
userId: randomizedUsers[0].id,
})
For this app, you must set these envs for VITE_PUBNUB_SUB_KEY
and VITE_PUBNUB_PUB_KEY
in the separate .env
file (copy of the .env.example
file).
Set up users
This sample app uses two hardcoded sample users - a support agent and a customer.
const userData = [
{
id: "support-agent",
data: { name: "John (Support Agent)", custom: { initials: "SA", avatar: "#9fa7df" } },
},
{
id: "supported-user",
data: { name: "Mary Watson", custom: { initials: "MW", avatar: "#ffab91" } },
},
]
When you run the app, you get randomly assigned an ID of one of these two users (support-agent
or supported-user
). Based on the provided details, the user metadata gets created (createUser()
), updated (update()
), and retrieved (getUser()
) from PubNub's App Context.
const randomizedUsers = Math.random() < 0.5 ? userData : userData.reverse()
...
const currentUser = await chat.currentUser.update(randomizedUsers[0].data)
const interlocutor =
(await chat.getUser(randomizedUsers[1].id)) ||
(await chat.createUser(randomizedUsers[1].id, randomizedUsers[1].data))
The advantage of having that random logic here is that if you open the app in another browser window and get assigned another user, you can simulate a real-life discussion.
For production apps, you would assign a fixed User ID that becomes the app's current user. User ID identifies your client when communicating with PubNub and is used by PubNub to calculate pricing.
Create channel
Now, you need a channel where these two users can talk and receive messages from each other.
The Chat SDK supports the following channel types:
To simulate a conversation between two users, you'll need a direct channel type.
The ID of the communication channel is hardcoded to Support Channel
. When you run the app for the first time, you create the direct (1:1) channel (createDirectConversation()
) on the PubNub server.
const { channel } = await chat.createDirectConversation({
user: interlocutor,
channelData: { name: "Support Channel" },
})
To receive messages from another user, you must be subscribed to the channel, or "connected," as we call it. This guide uses the Chat SDK connect()
method to listen for messages, called by the Getting Started app within useEffect()
to update its messages state.
useEffect(() => {
if (!channel) return
return channel.connect((message) => setMessages((messages) => [...messages, message]))
}, [channel])
Send messages
The app handles:
- Incoming messages through the
setMessages()
function that uses theconnect()
method to receive messages from another user and then add these messages to the collective message list. - Outgoing messages through the
handleSend()
function that uses thesendText()
method to publish messages on the channel.
useEffect(() => {
if (!channel) return
return channel.connect((message) => setMessages((messages) => [...messages, message]))
}, [channel])
...
async function handleSend(event: React.SyntheticEvent) {
event.preventDefault()
if (!text || !channel) return
await channel.sendText(text)
setText("")
}
The Getting Started app that this guide is based on only supports sending text messages. The Chat SDK, however, also supports files and rich message features like links, @user mentions, or channel references that are similar in logic to @user mentions.
Show time indicator
Another addition to the basic setup is the time indicator in the app. The Chat SDK comes with utility methods handling Unix timestamp to PubNub message timetoken conversion (and vice versa). Our sample chat app converts a message timetoken to a "short" time style, like 08:25
.
<time>
{TimetokenUtils.timetokenToDate(message.timetoken).toLocaleTimeString([], {
timeStyle: "short",
})}
</time>
Add look and feel
The UI for the app is completely customized, and it's up to you to decide what you want your chat to look like. Check the CSS styles used to beautify this sample chat app if interested.
Next steps
You can extend this basic chat app by adding other features, like message reactions, typing indicator, mentions, and many more.
You can also try running another sample and see what a group chat in React Native can look like.
Head to the Features section to explore everything the Chat SDK offers.