Add Message Actions
With the Message Actions feature, you can add actions to messages that are already published. These actions can be useful for delivery acknowledgments, read receipts, and reactions such as emojis. You can provide any custom reaction as long as it's a string. You'll have to use your own emoji library as this isn't included in the PubNub SDKs.
Add Message Actions
Add an action on a message (returns the added action in the response).
pubnub.addMessageAction(
{
channel: 'chats.room1'
messageTimetoken: '15610547826970040',
action: {
type: 'reaction',
value: 'smiley_face',
}
},
function(status, response) {
console.log(status, response);
}
);
extension MyAppMessageAction: MessageAction {}
let action = MyAppMessageAction(type: "reaction", value: "smiley_face")
pubnub.addMessageAction(
channel: "chats.room1",
message: action,
messageTimetoken: 15_610_547_826_969_050
) { 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)")
}
})
PNAddMessageActionRequest *request =
[PNAddMessageActionRequest requestWithChannel:@"chats.room1"
messageTimetoken:@(1234567890)];
request.type = @"reaction";
request.value = @"smile";
[self.pubnub addMessageActionWithRequest:request
completion:^(PNAddMessageActionStatus *status) {
if (!status.isError) {
}
else {
}
}];
pubnub.addMessageAction().channel("chats.room1")
.messageAction(new PNMessageAction()
.setType("reaction")
.setValue("smiley_face")
.setMessageTimetoken(15701761818730000L)
)
.async(new PNCallback<PNAddMessageActionResult>() {
@Override
public void onResponse(PNAddMessageActionResult result, PNStatus status) {
if (!status.isError()) {
System.out.println(result.getType());
System.out.println(result.getValue());
System.out.println(result.getUuid());
System.out.println(result.getActionTimetoken());
System.out.println(result.getMessageTimetoken());
}
else {
status.getErrorData().getThrowable().printStackTrace();
}
}
});
pubnub.AddMessageAction()
.Channel("chats.room1")
.MessageTimetoken(5610547826969050)
.Action(new PNMessageAction { Type = "reaction", Value = "smiley_face" })
.Execute(new PNAddMessageActionResultExt((result, status) =>
{
}));
msg_action = PNMessageAction()
msg_action.type = "reaction"
msg_action.value = "smiley_face"
msg_action.message_timetoken = str(int(time.time()))
pubnub.add_message_action()\
.channel("chats.room1")\
.message_action(msg_action)\
.pn_async(message_action_callback)
Receiving Message Actions
In order to receive an action on a message, the receiving client should be listening to an event of type messageAction
, and should subscribe to a channel in which the message action is being added. There is no need to subscribe any differently to a channel for receiving a message action.
Removing Message Actions
You may need to remove a previously added action on a message (returns an empty response).
pubnub.removeMessageAction(
{
channel: 'chats.room1'
messageTimetoken: '15610547826970040',
actionTimetoken: '15610547826970041',
},
function(status, response) {
});
pubnub.removeMessageActions(
channel: "chats.room1",
message: 15_610_547_826_969_050,
action: 15_610_547_826_970_051
) { 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)")
}
})
PNRemoveMessageActionRequest *request =
[PNRemoveMessageActionRequest requestWithChannel:@"chats.room1",
messageTimetoken:@(1234567890)];
request.actionTimetoken = @(1234567891);
[self.pubnub removeMessageActionWithRequest:request
completion:^(PNAcknowledgmentStatus *status) {
if (!status.isError) {
}
else {
}
}];
pubnub.removeMessageAction()
.channel("chats.room1")
.messageTimetoken(15701761818730000L)
.actionTimetoken(15701775691010001L)
.async(new PNCallback<PNRemoveMessageActionResult>() {
@Override
public void onResponse(PNRemoveMessageActionResult result, PNStatus status) {
if (!status.isError()) {
// result has no actionable data
// it's enough to check if the status itself is not an error
}
else {
status.getErrorData().getThrowable().printStackTrace();
}
}
});
pubnub.RemoveMessageAction()
.Channel("chats.room1")
.MessageTimetoken(15701761818730000)
.ActionTimetoken(15701775691010001)
.Execute(new PNRemoveMessageActionResultExt((result, status) =>
{
}));
pubnub.remove_message_action()
.channel('chats.room1')
.action_timetoken(15901706735798836) # Some action timetoken
.message_timetoken(15901706735798837) # Some message timetoken
.pn_async(message_action_callback)
Retrieving Actions
You can retrieve messages and the associated message actions or you can just retrieve the message actions only. Get a list of message actions in a channel (returns a list of actions in the response).
pubnub.getMessageActions(
{
channel: 'chats.room1',
start: '15610547826970041',
end: '15610547826970040',
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 {
}
}];
pubnub.getMessageActions()
.channel("chats.room1")
.async(new PNCallback<PNGetMessageActionsResult>() {
@Override
public void onResponse(PNGetMessageActionsResult result, PNStatus status) {
if (!status.isError()) {
List<PNMessageAction> actions = result.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());
}
}
else {
status.getErrorData().getThrowable().printStackTrace();
}
}
});
pubnub.GetMessageActions()
.Channel("chats.room1")
.Execute(new PNGetMessageActionsResultExt((result, status) =>
{
}));
Return Type: PNGetMessageActionsResult
{
"MessageActions":[{
"MessageTimetoken":15610547826969050,
"Action":{
"type":"reaction",
"value":"smiley_face"
},
"Uuid":"pn-5903a053-592c-4a1e-8bfd-81d92c962968",
"ActionTimetoken":15717253483027901
}],
"More": {
"Start": 15610547826970050,
"End": 15645905639093361,
"Limit": 2
}
}
pubnub.get_message_actions()
.channel('chats.room1')
.start(15901706735798837) # Some start timetoken or None
.end(15901706735798836) # Some end timetoken or None
.pn_async(message_action_callback)
Deleting Messages
There is a setting to allow delete from history requests which you must enable by checking the Enable Delete-From-History for your PubNub API Keys in the Admin Portal. Only clients (typically, your server) that initialize the PubNub object with the secret key (in addition to the publish and subscribe keys) can invoke the Delete Messages API.
pubnub.deleteMessages(
{
channels: 'chats.room1',
start: "15526611838554309",
end: "15526611838554310",
},
function (status, response) {
console.log(status, response);
}
);
pubnub.deleteMessageHistory(
from: "chats.room1",
start: 15526611838554310,
end: 15526611838554309
) { result in
switch result {
case let .success(response):
print("Successful Message Deletion Response: \(response)")
case let .failure(error):
print("Failed Message Deletion Response: \(error.localizedDescription)")
}
}
[self.client deleteMessagesFromChannel:@"chats.room1"
start:@15526611838554310 end:@15526611838554309
withCompletion:^(PNAcknowledgmentStatus *status) {
if (status.isError) {
// handle error condtion
}
else {
// confirm delete success
}
}];
pubnub.deleteMessages()
.channels(Arrays.asList("chats.room1"))
.start(15526611838554310L)
.end(15526611838554309L)
.async(new PNCallback<PNDeleteMessagesResult>() {
@Override
public void onResponse(PNDeleteMessagesResult result, PNStatus status) {
// handle success or failure of the delete
}
});
pubnub.DeleteMessages().Channel("chats.room1")
.Start(15526611838554310)
.End(15526611838554309)
.Execute(new PNDeleteMessageResultExt((result, status) => {
if (status != null && status.Error) {
Console.WriteLine(status.ErrorData.Information);
}
else if (result != null) {
Console.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(result));
}
}
));
envelope = PubNub(pnconf).delete_messages().channel('chats.room1') \
.start(15526611838554310) \
.end(15526611838554309) \
.sync()
Bulk Message Delete
You can delete all the messages stored in a channel. In the above example, the start
and end
timetoken parameter values are 1/10 nanosecond (last digit of timetoken) apart to delete the message stored at the end
parameter's timetoken value.
Parameters | Behavior |
---|---|
start & end | Delete messages between those timetokens (only one message if values differ by 1) |
start only | Delete all messages before (not at) that timetoken |
end only | Delete all messages after (and at) that timetoken |
none | Delete ALL messages |
Warning
There is no undo for the Delete Message API.