Quick Reference for AI Agents & Developers // Mark single message as delivered/read
CometChat . markAsDelivered ( message );
CometChat . markAsRead ( message );
// Mark entire conversation
await CometChat . markConversationAsDelivered ( "user_uid" , "user" );
await CometChat . markConversationAsRead ( "user_uid" , "user" );
// Mark as unread (requires Enhanced Messaging Status)
await CometChat . markMessageAsUnread ( message );
// Listen for receipts
CometChat . addMessageListener ( "RECEIPT_LISTENER" , new CometChat . MessageListener ({
onMessagesDelivered : ( receipt ) => updateStatus ( receipt . getMessageId (), "delivered" ),
onMessagesRead : ( receipt ) => updateStatus ( receipt . getMessageId (), "read" )
}));
// Check message status
const deliveredAt = message . getDeliveredAt ();
const readAt = message . getReadAt ();
// Get receipt history for a message
const receipts = await CometChat . getMessageReceipts ( messageId );
Message receipts let you show delivery and read status (✓ sent, ✓✓ delivered, ✓✓ read) in your chat UI.
Mark Messages as Delivered
Inform the sender that you’ve received their message:
Using Message Object
Using Parameters
// Simplest approach - pass the message directly
CometChat . markAsDelivered ( message );
const messageId = message . getId ();
const receiverId = message . getSender (). getUid (); // For user messages
const receiverType = "user" ;
const senderId = message . getSender (). getUid ();
CometChat . markAsDelivered ( messageId , receiverId , receiverType , senderId );
When to Mark as Delivered
When fetching messages : Mark the last message as delivered
When receiving real-time messages : Mark each incoming message
// After fetching message history
messagesRequest . fetchPrevious (). then (( messages ) => {
if ( messages . length > 0 ) {
const lastMessage = messages [ messages . length - 1 ];
CometChat . markAsDelivered ( lastMessage );
}
});
// In real-time listener
onTextMessageReceived : ( message ) => {
CometChat . markAsDelivered ( message );
displayMessage ( message );
}
Mark Messages as Read
Inform the sender that you’ve seen their message:
Using Message Object
Using Parameters
CometChat . markAsRead ( message );
const messageId = message . getId ();
const receiverId = message . getSender (). getUid ();
const receiverType = "user" ;
const senderId = message . getSender (). getUid ();
CometChat . markAsRead ( messageId , receiverId , receiverType , senderId );
When to Mark as Read
When the user views/scrolls to a message
When the chat window is in focus
When opening a conversation
// Mark as read when user views the conversation
function onConversationOpened ( conversation ) {
const lastMessage = conversation . getLastMessage ();
if ( lastMessage ) {
CometChat . markAsRead ( lastMessage );
}
}
Mark Entire Conversation
Mark all messages in a conversation at once:
As Delivered
As Read
Async/Await
const conversationWith = "user_uid" ; // or group_guid
const conversationType = "user" ; // or "group"
CometChat . markConversationAsDelivered ( conversationWith , conversationType ). then (
() => console . log ( "Conversation marked as delivered" ),
( error ) => console . log ( "Error:" , error )
);
const conversationWith = "user_uid" ;
const conversationType = "user" ;
CometChat . markConversationAsRead ( conversationWith , conversationType ). then (
() => console . log ( "Conversation marked as read" ),
( error ) => console . log ( "Error:" , error )
);
const markConversation = async () => {
try {
const conversationWith = "user_uid" ; // or group_guid
const conversationType = "user" ; // or "group"
// Mark as delivered
await CometChat . markConversationAsDelivered ( conversationWith , conversationType );
console . log ( "Conversation marked as delivered" );
// Or mark as read
await CometChat . markConversationAsRead ( conversationWith , conversationType );
console . log ( "Conversation marked as read" );
} catch ( error ) {
console . log ( "Error:" , error );
}
};
Mark as Unread
Mark a message as unread to revisit later:
CometChat . markMessageAsUnread ( message ). then (
( conversation ) => {
console . log ( "Marked as unread" );
console . log ( "Unread count:" , conversation . getUnreadMessageCount ());
},
( error ) => console . log ( "Error:" , error )
);
async function markAsUnread ( message ) {
try {
const conversation = await CometChat . markMessageAsUnread ( message );
console . log ( "Marked as unread" );
console . log ( "Unread count:" , conversation . getUnreadMessageCount ());
return conversation ;
} catch ( error ) {
console . log ( "Error:" , error );
throw error ;
}
}
You can only mark messages from other users as unread, not your own messages.
Mark as Unread requires the Enhanced Messaging Status feature to be enabled for your app.
Receive Receipt Events
Listen for delivery and read receipts in real-time:
const listenerID = "RECEIPT_LISTENER" ;
CometChat . addMessageListener (
listenerID ,
new CometChat . MessageListener ({
// One-on-one and group messages
onMessagesDelivered : ( messageReceipt ) => {
console . log ( "Message delivered:" , messageReceipt );
updateMessageStatus ( messageReceipt . getMessageId (), "delivered" );
},
onMessagesRead : ( messageReceipt ) => {
console . log ( "Message read:" , messageReceipt );
updateMessageStatus ( messageReceipt . getMessageId (), "read" );
},
// Group messages only - when ALL members have received/read
onMessagesDeliveredToAll : ( messageReceipt ) => {
console . log ( "Delivered to all group members" );
},
onMessagesReadByAll : ( messageReceipt ) => {
console . log ( "Read by all group members" );
}
})
);
onMessagesDeliveredToAll and onMessagesReadByAll require the Enhanced Messaging Status feature.
MessageReceipt Properties
Property Method Description Message ID getMessageId()ID of the message Sender getSender()User who sent the receipt Receiver ID getReceiverId()UID or GUID Receiver Type getReceiverType()user or groupReceipt Type getReceiptType()delivered or readDelivered At getDeliveredAt()Delivery timestamp Read At getReadAt()Read timestamp
Get Receipt History
Fetch delivery/read status for a specific message (useful for group messages):
const messageId = 123 ;
CometChat . getMessageReceipts ( messageId ). then (
( receipts ) => {
receipts . forEach (( receipt ) => {
console . log (
receipt . getSender (). getName (),
receipt . getReceiptType (),
"at" ,
receipt . getReadAt () || receipt . getDeliveredAt ()
);
});
},
( error ) => console . log ( "Error:" , error )
);
async function getReceiptHistory ( messageId ) {
try {
const receipts = await CometChat . getMessageReceipts ( messageId );
receipts . forEach (( receipt ) => {
console . log (
receipt . getSender (). getName (),
receipt . getReceiptType (),
"at" ,
receipt . getReadAt () || receipt . getDeliveredAt ()
);
});
return receipts ;
} catch ( error ) {
console . log ( "Error:" , error );
throw error ;
}
}
Check Message Status
When fetching messages, check their delivery/read status:
messagesRequest . fetchPrevious (). then (( messages ) => {
messages . forEach (( message ) => {
const deliveredAt = message . getDeliveredAt ();
const readAt = message . getReadAt ();
if ( readAt ) {
console . log ( "Read at:" , readAt );
} else if ( deliveredAt ) {
console . log ( "Delivered at:" , deliveredAt );
} else {
console . log ( "Sent" );
}
});
});
async function checkMessageStatuses () {
try {
const messages = await messagesRequest . fetchPrevious ();
messages . forEach (( message ) => {
const deliveredAt = message . getDeliveredAt ();
const readAt = message . getReadAt ();
if ( readAt ) {
console . log ( "Read at:" , readAt );
} else if ( deliveredAt ) {
console . log ( "Delivered at:" , deliveredAt );
} else {
console . log ( "Sent" );
}
});
return messages ;
} catch ( error ) {
console . log ( "Error:" , error );
throw error ;
}
}
Implementation Example
// Message status component
function getMessageStatus ( message ) {
// Only show status for sent messages (not received)
if ( message . getSender (). getUid () !== loggedInUser . getUid ()) {
return null ;
}
const readAt = message . getReadAt ();
const deliveredAt = message . getDeliveredAt ();
if ( readAt ) {
return { icon: "✓✓" , color: "blue" , label: "Read" };
} else if ( deliveredAt ) {
return { icon: "✓✓" , color: "gray" , label: "Delivered" };
} else {
return { icon: "✓" , color: "gray" , label: "Sent" };
}
}
// Update status when receipt received
function updateMessageStatus ( messageId , status ) {
const messageElement = document . querySelector ( `[data-message-id=" ${ messageId } "]` );
if ( messageElement ) {
const statusElement = messageElement . querySelector ( ".status" );
if ( status === "read" ) {
statusElement . innerHTML = "✓✓" ;
statusElement . style . color = "blue" ;
} else if ( status === "delivered" ) {
statusElement . innerHTML = "✓✓" ;
statusElement . style . color = "gray" ;
}
}
}
Best Practices
Mark delivered automatically
Mark messages as delivered as soon as they’re received, even before displaying them.
Only mark messages as read when the user actually sees them (chat window in focus, message scrolled into view).
When opening a conversation, mark the last message as read rather than marking each message individually.
Messages fetched from history will have deliveredAt and readAt fields already set.
Next Steps