On this page

Read receipts

Read receipts show if channel members have viewed a message.

Required setup

Read Receipts requires Unread Message Count. First, set the last read timetoken for each user on a channel.

Get read receipts

onReadReceiptReceived() provides real-time individual read receipt events on a channel. Each event contains a single user's read status as a typed ReadReceipt object.

Not available for public chats

Read receipts are disabled in public chats by default. Control this with the emitReadReceiptEvents configuration parameter.

Method signature

1channel.onReadReceiptReceived(callback: (receipt: ReadReceipt) -> Unit): AutoCloseable

Input

* required
ParameterDescription
callback *
Type: (receipt: ReadReceipt) -> Unit
Default:
n/a
Function invoked when a read receipt event is received.

The ReadReceipt object contains:

PropertyDescription
userId
Type: String
The ID of the user who read the message.
lastReadTimetoken
Type: Long
The timetoken indicating how far the user has read in the channel.

Output

TypeDescription
AutoCloseable
Interface you can call to stop listening for read receipt events by invoking the close() method.

Sample code

Receive individual read receipt events on the support channel.

1chat.getChannel("support").async { result ->
2 result.onSuccess { channel ->
3 val subscription = channel?.onReadReceiptReceived { receipt ->
4 println("User ${receipt.userId} read up to timetoken ${receipt.lastReadTimetoken}")
5 }
6
7 // stop listening:
8 // subscription?.close()
9 }.onFailure { error ->
10 println("Failed to get channel: $error")
11 }
12}

Fetch read receipts

fetchReadReceipts() returns the current read status for all members of a channel. Use this to display read indicators when loading a conversation.

Method signature

1channel.fetchReadReceipts(
2 limit: Int? = 100,
3 page: PNPage? = null,
4 filter: String? = null,
5 sort: Collection<PNSortKey<PNMemberKey>> = listOf(),
6): PNFuture<ReadReceiptsResponse>

Input

* required
ParameterDescription
limit
Type: Int
Default:
100
Number of members to return. Default and max is 100.
page
Type: PNPage
Default:
null
Pagination object for fetching next/previous results.
filter
Type: String
Default:
null
Expression used to filter the results.
sort
Type: Collection<PNSortKey<PNMemberKey>>
Default:
listOf()
A collection to specify the sort order.

Output

TypeDescription
PNFuture<ReadReceiptsResponse>
Response containing a list of ReadReceipt objects and pagination tokens.

The ReadReceiptsResponse object contains:

PropertyDescription
receipts
Type: List<ReadReceipt>
List of read receipts, one per member.
next
Type: PNPage.PNNext?
Pagination token for the next page.
prev
Type: PNPage.PNPrev?
Pagination token for the previous page.
total
Type: Int
Total number of members matching the query.
status
Type: Int
HTTP status code of the operation.

Sample code

Fetch read receipts for all members of the support channel.

1chat.getChannel("support").async { result ->
2 result.onSuccess { channel ->
3 channel?.fetchReadReceipts()?.async { receiptsResult ->
4 receiptsResult.onSuccess { response ->
5 response.receipts.forEach { receipt ->
6 println("User ${receipt.userId} last read: ${receipt.lastReadTimetoken}")
7 }
8 }.onFailure { error ->
9 println("Failed to fetch read receipts: $error")
10 }
11 }
12 }.onFailure { error ->
13 println("Failed to get channel: $error")
14 }
15}

Get read receipts (deprecated)

Deprecated method

streamReadReceipts() is deprecated. Use onReadReceiptReceived() for real-time events or fetchReadReceipts() for current status.

streamReadReceipts() provides read status for messages on a channel. The method fetches member read status, listens for updates, and passes receipt events to your callback.

Method signature

1channel.streamReadReceipts(callback: (receipts: Map<Long, List<String>>) -> Unit): AutoCloseable

Input

* required
ParameterDescription
callback *
Type: n/a
Default:
n/a
Callback function passed as a parameter. It defines the custom behavior to be executed when receiving a read confirmation status on the joined channel.
 → receipts *
Type: Map<Long, List<String>>
Default:
n/a
The received object that maps message timetokens (as Long) to users who last read these messages.

Output

TypeDescription
AutoCloseable
Interface you can call to stop listening for message read receipts and clean up resources when they are no longer needed by invoking the close() method.

Sample code

1chat.getChannel("support").async { result ->
2 result.onSuccess { channel ->
3 val receiptStream = channel.streamReadReceipts { receipts ->
4 receipts.forEach { (messageTimetoken, users) ->
5 println("Message $messageTimetoken was read by: $users")
6 }
7 }
8 // receiptStream.close()
9 }.onFailure { error ->
10 println("Failed to get channel: $error")
11 }
12}