Unread messages
Track unread message counts for users who reconnect after being offline.
lastReadMessageTimetoken on the Membership object stores when a user last read messages on a channel. This is set automatically on join() or invite(). Update it based on user actions (scrolling, app focus, etc.) using mark as read methods.
Requires App Context and Message Persistence
Enable App Context and Message Persistence in the Admin Portal.
Get last read message
lastReadMessageTimetoken returns the timetoken of the last message a user read on a channel. Use it to display unread markers in your UI.
Method signature
This method has the following signature:
1membership.lastReadMessageTimetoken: string
Properties
| Property | Description |
|---|---|
lastReadMessageTimetokenType: string | Value of the returned timetoken. |
Sample code
Get the timetoken of the last message read by the support_agent_15 user on the support channel.
1// reference the "support_agent_15" user
2const user = await chat.getUser("support_agent_15")
3
4// get the list of all user memberships and filter out the right channel
5const membership = await user.getMemberships({
6 filter: "channel.id == 'support'"
7})
8
9//
10membership.lastReadMessageTimetoken
Get unread messages count (one channel)
getUnreadMessagesCount() returns the number of unread messages on a channel. This counts all messages after the last read timetoken, including your own messages.
Method signature
This method has the following signature:
1membership.getUnreadMessagesCount(): Promise<number | false>
Input
This method doesn't take any parameters.
Output
| Type | Description |
|---|---|
Promise<number> or Promise<false> | Retrieves from Message Persistence the number of all messages unread by a given user on a given channel from the last read message. The method returns false when there is no last read message timetoken set on the Message object. |
Sample code
Get the number of all messages unread by the support_agent_15 user on the support channel.
1// reference the "support_agent_15" user
2const user = await chat.getUser("support_agent_15")
3
4// get the list of all user memberships and filter out the right channel
5const membership = await user.getMemberships({
6 filter: "channel.id == 'support'"
7})
8
9// get the number of unread messages
10await membership.getUnreadMessagesCount()
Get unread messages count (all channels)
fetchUnreadMessagesCounts() returns unread counts for all joined channels with unread messages (channels with zero unread are excluded). Counts include all messages after the last read timetoken, including your own.
Unread counts and filtering
Filters support channel.* fields plus status, type, custom (not uuid.*). Unread counts include your own messages. See Memberships filters.
Method signature
This method has the following signature:
1chat.fetchUnreadMessagesCounts({
2 filter?: string,
3 sort?: object,
4 limit?: number,
5 page?: {
6 next?: string,
7 prev?: string
8 }
9}): Promise<{
10 countsByChannel: Array<{
11 channel: Channel;
12 membership: Membership;
13 count: number;
14 }>;
15 page: {
show all 19 linesInput
| Parameter | Description |
|---|---|
filterType: string (Memberships filter)Default: n/a | Filter expression evaluated against channel memberships only. Allowed targets: channel.* plus common fields (status, type, custom). uuid.* fields aren't supported. |
sortType: objectDefault: n/a | Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. Use asc or desc to specify the sorting direction, or specify null to take the default sorting direction (ascending). For example: {name: "asc"}. By default, the items are sorted by the last updated date. |
limitType: numberDefault: 100 | Number of objects to return in response. The default (and maximum) value is 100. |
pageType: objectDefault: n/a | Object used for pagination to define which previous or next result page you want to fetch. |
→ nextType: stringDefault: n/a | Random string returned from the server, indicating a specific position in a data set. Used for forward pagination, it fetches the next page, allowing you to continue from where you left off. |
→ prevType: stringDefault: n/a | Random string returned from the server, indicating a specific position in a data set. Used for backward pagination, it fetches the previous page, enabling access to earlier data. Ignored if the next parameter is supplied. |
Output
| Parameter | Description |
|---|---|
Promise<>Type: object | Returned object containing these fields: countsByChannel and page. |
→ countsByChannelType: Array<object> | Array of objects containing channel, membership, and count information. |
→ channelType: Channel | Channel with unread messages. |
→ membershipType: Membership | Returned Membership object showing the user-channel data. |
→ countType: number | Total number of messages unread by the current user on a given channel. |
→ pageType: object | Object containing pagination information. |
→ nextType: string | undefined | Token for fetching the next page of results. |
→ prevType: string | undefined | Token for fetching the previous page of results. |
Sample code
Get the number of all messages unread by the support_agent_15 user on all joined channels.
1// reference the "support_agent_15" user
2const user = await chat.getUser("support_agent_15")
3
4// get all messages unread by that user
5const result = await chat.fetchUnreadMessagesCounts()
6
7// access the counts for each channel
8const countsByChannel = result.countsByChannel
9
10// access pagination tokens if needed
11const { next, prev } = result.page
To avoid counting your own recently sent messages as unread, ensure your app updates the last read timetoken.
Mark messages as read (one channel)
setLastReadMessage() and setLastReadMessageTimetoken() set the last read timetoken for counting unread messages. Bind these to user actions in your app.
Setting the last read message for users lets you implement the Read Receipts feature and monitor which channel member read which message.
Method signature
These methods take the following parameters:
-
setLastReadMessage()1membership.setLastReadMessage(
2 message: Message
3): Promise<Membership> -
setLastReadMessageTimetoken()1membership.setLastReadMessageTimetoken(
2 timetoken: string
3): Promise<Membership>
Input
| Parameter | Required by setLastReadMessage() | Required by setLastReadMessageTimetoken() | Description |
|---|---|---|---|
messageType: MessageDefault: n/a | Yes | No | Last read message on a given channel with the timestamp that gets added to the user-channel membership as the custom parameter called lastReadMessageTimetoken. |
timetokenType: stringDefault: n/a | No | Yes | Timetoken of the last read message on a given channel that gets added to the user-channel membership as the custom parameter called lastReadMessageTimetoken. |
Output
| Type | Description |
|---|---|
Promise<Membership> | Returned Membership object updated with the lastReadMessageTimetoken custom parameter. |
Sample code
Set the message with the 16200000000000001 timetoken as the last read message for the support_agent_15 user on the support channel.
-
setLastReadMessage()
show all 16 lines1// reference the "support_agent_15" user
2const user = await chat.getUser("support_agent_15")
3
4// get the list of all user memberships and filter out the right channel
5const membership = await user.getMemberships({
6 filter: "channel.id == 'support'"
7})
8
9// reference the "support" channel
10const channel = await chat.getChannel("support")
11
12// return the message object with the "16200000000000001" timetoken
13const message = await channel.getMessage("16200000000000001")
14
15// assuming a single membership which matches the filter -
setLastReadMessageTimetoken()
show all 16 lines1// reference the "support_agent_15" user
2const user = await chat.getUser("support_agent_15")
3
4// get the list of all user memberships and filter out the right channel
5const membership = await user.getMemberships({
6 filter: "channel.id == 'support'"
7})
8
9// reference the "support" channel
10const channel = await chat.getChannel("support")
11
12// return the message object with the "16200000000000001" timetoken
13const message = await channel.getMessage("16200000000000001")
14
15// assuming a single membership which matches the filter
Mark messages as read (all channels)
markAllMessagesAsRead() marks all unread messages as read on all joined channels.
Method signature
This method has the following signature:
1chat.markAllMessagesAsRead({
2 filter?: string,
3 sort?: object,
4 limit?: number,
5 page?: {
6 next?: string,
7 prev?: string
8 }
9}): Promise<{
10 page: {
11 next: string,
12 prev: string
13 },
14 total: number,
15 status: number,
show all 17 linesInput
| Parameter | Description |
|---|---|
filterType: string (Memberships filter)Default: n/a | Expression used to filter the results. Returns only these messages whose properties satisfy the given expression. The filtering language is defined here. |
sortType: objectDefault: n/a | Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. Use asc or desc to specify the sorting direction, or specify null to take the default sorting direction (ascending). For example: {name: "asc"}. By default, the items are sorted by the last updated date. |
limitType: numberDefault: 100 | Number of objects to return in response. The default (and maximum) value is 100. |
pageType: objectDefault: n/a | Object used for pagination to define which previous or next result page you want to fetch. |
→ nextType: stringDefault: n/a | Random string returned from the server, indicating a specific position in a data set. Used for forward pagination, it fetches the next page, allowing you to continue from where you left off. |
→ prevType: stringDefault: n/a | Random string returned from the server, indicating a specific position in a data set. Used for backward pagination, it fetches the previous page, enabling access to earlier data. Ignored if the next parameter is supplied. |
Output
| Parameter | Description |
|---|---|
Promise<>Type: object | Returned object containing these fields: page, total, status, and memberships. |
→ pageType: object | Object used for pagination to define which previous or next result page you want to fetch. |
→ nextType: string | Random string returned from the server, indicating a specific position in a data set. Used for forward pagination, it fetches the next page, allowing you to continue from where you left off. |
→ prevType: string | Random string returned from the server, indicating a specific position in a data set. Used for backward pagination, it fetches the previous page, enabling access to earlier data. Ignored if the next parameter is supplied. |
→ totalType: number | Total number of messages marked as read. |
→ statusType: number | Status code of a server response, like 200. |
→ membershipsType: Membership[] | List of all related memberships. |
Sample code
Mark the total number of 50 messages as read and specify you want to fetch the results from the next page using a string that was previously returned from the PubNub server.
1await chat.markAllMessagesAsRead(
2 {
3 limit: 50,
4 page: {
5 next: "<returned_random_string>"
6 }
7 }
8)
Get unread messages count (all channels) (deprecated)
Deprecated
Use fetchUnreadMessagesCounts() instead.
getUnreadMessagesCounts() returns unread counts for all joined channels.
Method signature
This method has the following signature:
1chat.getUnreadMessagesCounts({
2 filter?: string,
3 sort?: object,
4 limit?: number,
5 page?: {
6 next?: string,
7 prev?: string
8 }
9}): Promise<{
10 channel: Channel,
11 membership: Membership,
12 count: number
13 }[]>
Input
| Parameter | Description |
|---|---|
filterType: string (Memberships filter)Default: n/a | Filter expression evaluated against channel memberships only. Allowed targets: channel.* plus common fields (status, type, custom). uuid.* fields aren't supported. |
sortType: objectDefault: n/a | Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. Use asc or desc to specify the sorting direction, or specify null to take the default sorting direction (ascending). For example: {name: "asc"}. By default, the items are sorted by the last updated date. |
limitType: numberDefault: 100 | Number of objects to return in response. The default (and maximum) value is 100. |
pageType: objectDefault: n/a | Object used for pagination to define which previous or next result page you want to fetch. |
→ nextType: stringDefault: n/a | Random string returned from the server, indicating a specific position in a data set. Used for forward pagination, it fetches the next page, allowing you to continue from where you left off. |
→ prevType: stringDefault: n/a | Random string returned from the server, indicating a specific position in a data set. Used for backward pagination, it fetches the previous page, enabling access to earlier data. Ignored if the next parameter is supplied. |
Output
| Parameter | Description |
|---|---|
Promise<>Type: object | Returned object containing these fields: channel, membership, and count. The method returns an array of such objects corresponding to all channel memberships. |
→ channelType: Channel | Channel with unread messages. |
→ membershipType: Membership | Returned Membership object showing the user-channel data. |
→ countType: number | Total number of messages unread by the current user on a given channel. |
Sample code
Get the number of all messages unread by the support_agent_15 user on all joined channels.
1// reference the "support_agent_15" user
2const user = await chat.getUser("support_agent_15")
3
4// get all messages unread by that user
5await chat.getUnreadMessagesCounts()