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
| Parameter | Description |
|---|---|
callback *Type: (receipt: ReadReceipt) -> UnitDefault: n/a | Function invoked when a read receipt event is received. |
The ReadReceipt object contains:
| Property | Description |
|---|---|
userIdType: String | The ID of the user who read the message. |
lastReadTimetokenType: Long | The timetoken indicating how far the user has read in the channel. |
Output
| Type | Description |
|---|---|
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
| Parameter | Description |
|---|---|
limitType: IntDefault: 100 | Number of members to return. Default and max is 100. |
pageType: PNPageDefault: null | Pagination object for fetching next/previous results. |
filterType: StringDefault: null | Expression used to filter the results. |
sortType: Collection<PNSortKey<PNMemberKey>>Default: listOf() | A collection to specify the sort order. |
Output
| Type | Description |
|---|---|
PNFuture<ReadReceiptsResponse> | Response containing a list of ReadReceipt objects and pagination tokens. |
The ReadReceiptsResponse object contains:
| Property | Description |
|---|---|
receiptsType: List<ReadReceipt> | List of read receipts, one per member. |
nextType: PNPage.PNNext? | Pagination token for the next page. |
prevType: PNPage.PNPrev? | Pagination token for the previous page. |
totalType: Int | Total number of members matching the query. |
statusType: 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
| Parameter | Description |
|---|---|
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
| Type | Description |
|---|---|
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}