Skip to main content
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.
Available via: SDK | REST API | UI Kits

Mark Messages as Delivered

Inform the sender that you’ve received their message:
// Simplest approach - pass the message directly
CometChat.markAsDelivered(message);

When to Mark as Delivered

  1. When fetching messages: Mark the last message as delivered
  2. 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:
CometChat.markAsRead(message);

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:
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)
);

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)
);
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

PropertyMethodDescription
Message IDgetMessageId()ID of the message
SendergetSender()User who sent the receipt
Receiver IDgetReceiverId()UID or GUID
Receiver TypegetReceiverType()user or group
Receipt TypegetReceiptType()delivered or read
Delivered AtgetDeliveredAt()Delivery timestamp
Read AtgetReadAt()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)
);

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");
    }
  });
});

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 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