跳到主要内容

逐条消息已读功能

逐条消息已读功能支持针对单、群聊内的每条消息分别标记已读状态,以满足特定场景需求。

提示
  • 使用逐条消息已读功能,需要 SDK 版本 ≥ 5.20.0;且需要提交工单申请逐条消息已读功能,否则相关接口将返回错误码。
  • 功能仅支持单聊、群聊会话类型。

发送允许回执的消息

调用 sendMessage 向会话中发送消息时,通过配置 needReceipt 参数,以通知接收方在已读时发送回执;可参考 ISendMessageOptions 说明。

注意

SDK 对于 needReceipt 参数进行了严格校验,若错误配置其值为 truesendMessage 将返回 [35056],开发者需自行按如下可能原因进行排查:

  1. 检查是否已申请开启逐条消息已读功能;
  2. 检查会话类型是否为单聊(ConversationType.PRIVATE)或群聊(ConversationType.GROUP),目前不支持其他会话类型;
  3. 检查消息是否为状态消息,或消息为非存储消息类型(isPersited = false);
  4. 发送群聊消息时,检查是否为群定向消息;即 ISendMessageOptionsdirectionalUserIdList 有值。

发送方通过监听 Events.MESSAGE_RECEIPT_RESPONSE_V5 事件,可以获取到消息接收方的回执动态通知;通知数据结构参考 ReadReceiptResponseV5

JavaScript
RongIMLib.addEventListener(RongIMLib.Events.MESSAGE_RECEIPT_RESPONSE_V5, (list) => {
list.forEach((data) => {
console.log('会话信息:', data.identifier);
console.log('消息 UID:', data.messageUId);
console.log('变更用户列表:', data.users);
console.log('总人数:', data.totalCount);
console.log('已读人数:', data.readCount);
console.log('未读人数:', data.unreadCount);
});
});

接收方消息检查

IAReceivedMessage 数据中新增 needReceipt 属性,以用于确定是否需要在阅读该消息后向对方发送已读回执;

JavaScript
// 接收在线消息
RongIMLib.addEventListener(RongIMLib.Events.MESSAGES, (msgList) => {
msgList.forEach((item) => {
console.log('消息 UID:', item.messageUId);
console.log('消息是否需要回执:', item.needReceipt);
});
});

新增 sendReceipt 属性,该属性仅在获取历史消息列表接口中有效,用于确定本端登录用户是否已对消息发送过回执。

JavaScript
// 获取历史消息
RongIMLib.getHistoryMessage(RongIMLib.ConversationType.GROUP, '<GroupID>').then(({ code, data }) => {
if (code !== RongIMLib.ErrorCode.SUCCESS) {
console.log('获取历史消息列表失败', code);
return;
}
const { list, hasMore } = data;
list.forEach((item) => {
console.log('消息是否需要回执:', item.needReceipt);
console.log('是否已发送回执:', item.sendReceipt);
});
});

接收方发送已读回执

通过调用 sendReadReceiptResponseV5 接口,可以批量对同一会话中的多条消息进行已读标记。

JavaScript
const conversation = {
conversationType: RongIMLib.ConversationType.GROUP,
targetId: '<Group-ID>'
};

// 待响应回执的消息 UID 列表
const messageUIds = ['<消息 UID>']

RongIMLib.sendReadReceiptResponseV5(conversation, messageUIds).then(({ code }) => {
console.log(code)
});

发送方查询消息已读状态

查询已读、未读人数

您可以通过 getMessageReadReceiptInfoV5 查询消息的已读和未读人数。

JavaScript
const conversation = {
conversationType: RongIMLib.ConversationType.GROUP,
targetId: '<Group-ID>'
};

// 待查询消息 ID 列表
const messageUIds = ['<消息 UID>']

RongIMLib.getMessageReadReceiptInfoV5(conversation, messageUIds),then(({ code, data }) => {
if (code !== RongIMLib.ErrorCode.SUCCESS) {
console.log('查询失败:', code)
return;
}

data.forEach((item) => {
console.log("消息 UID:", item.messageUId);
console.log('总人数:', data.totalCount);
console.log('已读人数:', data.readCount);
console.log('未读人数:', data.unreadCount);
});
});

分页查询已读、未读人员列表

您可以通过 getMessagesReadReceiptUsersByPageV5 ,分页查询消息的已读和未读人员列表。

JavaScript
// 消息所属会话信息
const conversation = {
conversationType: RongIMLib.ConversationType.GROUP,
targetId: '<Group-ID>'
};

const messageUId = '<消息 UID>';
// 查询参数
const opts = {
pageToken: '' // 分页游标,首页可不传,后续使用前次查询返回的 pageToken 数据
pageCount: 10, // 查询数量
readStatus: 0, // 0 - 查询已读列表 或 1 - 查询未读列表
order: 0, // 排序:0 - 按阅读时间降序查询,1 - 按阅读时间升序查询
};

RongIMLib.getMessagesReadReceiptUsersByPageV5(conversation, messageUId, opts).then(({ code, data }) => {
if (code !== ErrorCode.SUCCESS) {
console.log('查询失败:', code)
return;
}

console.log('pageToken:', data.pageToken); // 用于下页查询,值为空时表示没有更多数据可查
console.log('totalCount:', data.totalCount); // 人员总数
// 遍历用户列表
data.users.forEach((user) => {
console.log('用户 ID:', user.userId);
console.log('用户读取时间:', user.timestamp); // 0 表示该用户未读
console.log('是否为被 @ 用户:', user.isMentioned);
});
});

查询指定人员是否已读

您可以通过 getMessagesReadReceiptByUsersV5 查询指定人员是否已读。

JavaScript
// 消息所属会话信息
const conversation = {
conversationType: RongIMLib.ConversationType.GROUP,
targetId: '<Group-ID>'
};
const messageUId = '<消息 UID>';
// 用户列表
const userIdList = ['UserId-01', 'UserId-02'];

RongIMLib.getMessagesReadReceiptByUsersV5(conversation, messageUId, userIdList).then(({ code, data }) => {
if (code !== ErrorCode.SUCCESS) {
console.log('查询失败:', code)
return;
}

// 返回值中 data.totolCount 与 data.pageToken 作为预留字段,可忽略
data.users.forEach((user) => {
console.log('用户 ID:', user.userId);
console.log('用户读取时间:', user.timestamp); // 0 表示该用户未读
console.log('是否为被 @ 用户:', user.isMentioned);
});
});