Delivered and Seen Receipts
Product deprecation notice
Effective April 30th, 2026, Vonage In-App Messaging will no longer be available. Access for new users will be closed, and the service will be discontinued for all existing users.
If you have any questions regarding this product’s discontinuation, please contact your account manager or our support team.
Overview
This guide covers delivered and seen receipts within a conversation.
Before you begin, make sure you added the SDK to your app and you are able to create a conversation.
NOTE: A step-by-step tutorial to build a chat application is available here.
This guide will make use of the following concepts:
Conversation Events:
message:deliveredevents that fire on a Conversation, after you are a Membermessage:seenevents that fire on a Conversation, after you are a Member
Set Message Status to Delivered
There is a method that will set a Message status to delivered. The following code snippet will set a messages's status to delivered once a message event happens in the conversation.
public void onMessageEvent(@NonNull NexmoMessageEvent messageEvent) {
messageEvent.markAsDelivered(new NexmoRequestListener() {
@Override
public void onError(@NonNull NexmoApiError error) { ... }
@Override
public void onSuccess(@Nullable Object result) { ... }
});
}
if (conversation.myMember.memberUuid != event.fromMemberId) {
[conversation sendMarkDeliveredMessage:event.uuid completionHandler:nil];
}
Message Delivered Receipt
Given a conversation you are already a member of, message:delivered events will be received when Message events are set to delivered in the context of the current conversation:
private NexmoMessageEventListener messageListener = new NexmoMessageEventListener() {
@Override
public void onTextEvent(@NonNull NexmoTextEvent textEvent) {}
@Override
public void onAttachmentEvent(@NonNull NexmoAttachmentEvent attachmentEvent) {}
@Override
public void onEventDeleted(@NonNull NexmoDeletedEvent deletedEvent) {}
@Override
public void onSeenReceipt(@NonNull NexmoSeenEvent seenEvent) {}
@Override
public void onDeliveredReceipt(@NonNull NexmoDeliveredEvent deliveredEvent) {
String userName = deliveredEvent.getEmbeddedInfo().getUser().getName();
Log.d("TAG", "Event " + deliveredEvent.initialEventId() + "delivered to User " + userName);
}
@Override
public void onTypingEvent(@NonNull NexmoTypingEvent typingEvent) {}
};
conversation.addMessageEventListener(messageListener);
Add NXMConversationDelegate as an extension to a ViewController or similar, and implement conversation(_ conversation: NXMConversation, didReceive event: NXMMessageStatusEvent):
Note: The first method below is required when implementing NXMConversationDelegate:
Have a ViewController, or similar, conform to NXMConversationDelegate and implement conversation:didReceiveMessageStatusEvent::
Note: The first method below is required when implementing NXMConversationDelegate:
- (void)conversation:(NXMConversation *)conversation didReceive:(NSError *)error {
NSLog(@"Conversation error: %@", error.localizedDescription);
}
- (void)conversation:(NXMConversation *)conversation didReceiveMessageStatusEvent:(NXMMessageStatusEvent *)event {
if (event.status == NXMMessageStatusTypeDelivered) {
NSLog(@"Received delivered event: %li", (long)event.referenceEventUuid);
}
}
Set Message Status to Seen
There is a method that will set a Message status to seen. The following code snippet will set a messages's status to seen once a message event happens in the conversation.
public void onMessageEvent(@NonNull NexmoMessageEvent messageEvent) {
messageEvent.markAsSeen(new NexmoRequestListener() {
@Override
public void onError(@NonNull NexmoApiError error) { ... }
@Override
public void onSuccess(@Nullable Object result) { ... }
});
}
if (conversation.myMember.memberUuid != event.fromMemberId) {
[conversation sendMarkSeenMessage:event.uuid completionHandler:nil];
}
Message Seen Receipt
Given a conversation you are already a member of, message:seen events will be received when Message events are set to seen in the context of the current conversation:
private NexmoMessageEventListener messageListener = new NexmoMessageEventListener() {
@Override
public void onTextEvent(@NonNull NexmoTextEvent textEvent) {}
@Override
public void onAttachmentEvent(@NonNull NexmoAttachmentEvent attachmentEvent) {}
@Override
public void onEventDeleted(@NonNull NexmoDeletedEvent deletedEvent) {}
@Override
public void onSeenReceipt(@NonNull NexmoSeenEvent seenEvent) {
String userName = seenEvent.getEmbeddedInfo().getUser().getName();
Log.d("TAG", "Event " + seenEvent.initialEventId() + "seen by User " + userName);
}
@Override
public void onDeliveredReceipt(@NonNull NexmoDeliveredEvent deliveredEvent) {}
@Override
public void onTypingEvent(@NonNull NexmoTypingEvent typingEvent) {}
};
conversation.addMessageEventListener(messageListener);
Add NXMConversationDelegate as an extension to a ViewController or similar, and implement conversation(_ conversation: NXMConversation, didReceive event: NXMMessageStatusEvent):
Note: The first method below is required when implementing NXMConversationDelegate:
Have a ViewController, or similar, conform to NXMConversationDelegate and implement conversation:didReceiveMessageStatusEvent::
Note: The first method below is required when implementing NXMConversationDelegate:
- (void)conversation:(NXMConversation *)conversation didReceive:(NSError *)error {
NSLog(@"Conversation error: %@", error.localizedDescription);
}
- (void)conversation:(NXMConversation *)conversation didReceiveMessageStatusEvent:(NXMMessageStatusEvent *)event {
if (event.status == NXMMessageStatusTypeSeen) {
NSLog(@"Received seen event: %li", (long)event.referenceEventUuid);
}
}