Message receipts and reactions
Message receipts enable users to track delivery of messages in a channel. Receipts are most useful in direct one-to-one chats, or in small group chats to indicate that users have read a particular message. They're not commonly used in high-occupancy chats, or in broadcasts with many users.
There are two kinds of receipts:
- Delivered receipts indicate that the message has been delivered to a user
- Read receipts indicate that a user has read the message
User ID / UUID
User ID is also referred to as UUID
/uuid
in some APIs and server responses but holds the value of the userId
parameter you set during initialization.
Add a receipt
Use the addMessageAction
method to add a receipt on a channel by passing the timetoken of a message. Set the value to message_delivered
or message_read
to indicate if the message was delivered and received by the user, or if it was read.
Your application needs to implement client-side logic to determine when receipts should be added. Add receipts when the user comes and goes from a channel, or periodically after every few messages. For efficiency, assume that when a message is marked read, all messages published before that message are also read by the user.
- JavaScript
- Swift
- Java
- Unity
pubnub.addMessageAction(
{
channel: 'ch-1'
messageTimetoken: '15610547826970040',
action: {
type: 'receipt',
value: 'read',
},
},
function(status, response) {
}
);
extension MyAppMessageAction: MessageAction {}
let action = MyAppMessageAction(type: "receipt", value: "read")
pubnub.addMessageAction(
channel: "ch-1",
message: action,
messageTimetoken: 15610547826970040
) { result in
switch result {
case let .success(response):
print("Successfully Message Action Add Response: \(response)")
case let .failure(error):
print("Error from failed response: \(error.localizedDescription)")
}
show all 16 linespubnub.addMessageAction()
.channel("ch-1")
.messageAction(new PNMessageAction()
.setType("receipt")
.setValue("read")
.setMessageTimetoken(15610547826970040L)
)
.async(result -> {
result.onSuccess(res -> {
System.out.println(res.getType());
System.out.println(res.getValue());
System.out.println(res.getUuid());
System.out.println(res.getActionTimetoken());
System.out.println(res.getMessageTimetoken());
}).onFailure(exception -> {
show all 18 linesMessageActionAdd messageAct = new MessageActionAdd();
messageAct.ActionType = "receipt";
messageAct.ActionValue = "read";
pubnub.AddMessageActions().Channel("ch-1").MessageAction(messageAct).MessageTimetoken(15610547826970040).Async((result, status) => {
if (!status.Error) {
Debug.Log("result.ActionTimetoken: " + result.ActionTimetoken);
Debug.Log("result.ActionType: " + result.ActionType);
Debug.Log("result.ActionValue: " + result.ActionValue);
Debug.Log("result.MessageTimetoken: " + result.MessageTimetoken);
Debug.Log("result.UserID: " + result.UserId);
} else {
Debug.Log(status.Error);
Debug.Log(status.ErrorData.Info);
}
show all 17 linesRemove a receipt
Use the removeMessageAction()
method to remove a receipt from a message by providing an actionTimetoken
and messageTimetoken
for the original message.
- JavaScript
- Swift
- Java
- Unity
pubnub.removeMessageAction(
{
channel: 'ch-1'
messageTimetoken: '15610547826970040',
actionTimetoken: '15610547826999081',
},
function(status, response) {
}
);
pubnub.removeMessageActions(
channel: "ch-1",
message: 15610547826970040,
action: 15610547826999081
) { result in
switch result {
case let .success(response):
print("Successfully Message Action Remove Response: \(response)")
case let .failure(error):
print("Error from failed response: \(error.localizedDescription)")
}
})
pubnub.removeMessageAction()
.channel("ch-1")
.messageTimetoken(15610547826970040L)
.actionTimetoken(15610547826999081L)
.async(result -> { /* check result */ });
pubnub.RemoveMessageActions().ActionTimetoken(15610547826999081).Channel("ch-1").MessageTimetoken(15610547826970040).Async((result, status) => {
if (!status.Error) {
// result has no actionable data
} else {
Debug.Log(status.Error);
Debug.Log(status.ErrorData.Info);
}
});
Fetch receipts in channel
Receipts are stored in history alongside messages when they are added by a user.
Use the getMessageActions
method to fetch receipts in a channel. The method works much like other PubNub history methods, and allows you to pass a start and end timetoken and fetch all message actions that were published during that time. Your app can parse through these actions and update the message state locally.
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
pubnub.getMessageActions(
{
channel: 'chats.room1',
start: '15901706735798836',
end: '15901706735370016',
limit: 100,
},
function(status, response) {
console.log(status, response);
}
);
pubnub.fetchMessageActions(
channel: "chats.room1") { result in
switch result {
case let .success(response):
print("Successfully Message Action Fetch Response: \(response)")
case let .failure(error):
print("Error from failed response: \(error.localizedDescription)")
}
})
PNFetchMessageActionsRequest *request =
[PNFetchMessageActionsRequest requestWithChannel:@"chats.room1"];
request.start = @(1234567891);
request.limit = 100;
[self.pubnub fetchMessageActionsWithRequest:request
completion:^(PNFetchMessageActionsResult *result, PNErrorStatus *status) {
if (!status.isError) {
}
else {
}
show all 16 linespubnub.getMessageActions()
.channel("chats.room1")
.async(result -> {
result.onSuccess(res -> {
List<PNMessageAction> actions = res.getActions();
for (PNMessageAction action : actions) {
System.out.println(action.getType());
System.out.println(action.getValue());
System.out.println(action.getUuid());
System.out.println(action.getActionTimetoken());
System.out.println(action.getMessageTimetoken());
}
}).onFailure(exception -> {
exception.printStackTrace();
});
show all 16 linespubnub.GetMessageActions()
.Channel("chats.room1")
.Execute(new PNGetMessageActionsResultExt((result, status) =>
{
}));
Return Type: PNGetMessageActionsResult
{
"MessageActions":[{
"MessageTimetoken":15610547826970040,
"Action":{
"type":"reaction",
"value":"smiley_face"
},
"Uuid":"pn-5903a053-592c-4a1e-8bfd-81d92c962968",
"ActionTimetoken":15610547826999081
}],
}
pubnub.get_message_actions()
.channel('chats.room1')
.start(15901706735798836) # Some start timetoken or None
.end(15901706735370016) # Some end timetoken or None
.pn_async(message_action_callback)
Fetch messages with receipts
Use the fetchMessages
method with the includeMessageActions
parameter set to fetch past messages in a channel along with receipts that were added to those messages. When you're fetching messages with their receipts, you can only fetch on a single channel at a time.
Message Receipt Events
PubNub triggers events to notify clients when receipts are added to or removed from messages. To receive these events, clients should be subscribed to the channel, and add a messageAction
listener in the code.
Event | Description |
---|---|
Message Reaction Added | Generated when a message action is added to a message. |
Message Reaction Removed | Generated when a message action is removed from a message. |
Message Reaction Added:
{
"channel":"my_channel",
"subscription":null,
"timetoken":"15610547826970040",
"publisher":"user-1",
"message":{
"source":"actions",
"version":"1.0",
"action":"added",
"data":{
"type":"receipt",
"value":"read",
"messageTimetoken":"15610547826970040",
"actionTimetoken":"15610547826999081"
}
show all 17 linesMessage Reaction Removed:
{
"channel":"my_channel",
"subscription":null,
"timetoken":"15610547826970040",
"publisher":"user-1",
"message":{
"source":"actions",
"version":"1.0",
"action":"removed",
"data":{
"type":"receipt",
"value":"read",
"messageTimetoken":"15610547826970040",
"actionTimetoken":"15610547826999081"
}
show all 17 lines