跳到主要内容

消息回应

消息回应(Message Reaction)允许用户对一条已发送成功的消息添加表情或业务自定义回应。IMLib SDK 从 26.6.0 开始提供消息回应数据接口,您可以基于这些接口实现自定义 UI,也可以配合 IMKit 内置的消息回应 UI使用。

提示

添加或移除回应需要使用消息的 messageUid。发送中、发送失败、取消发送或本地尚未生成 UID 的消息不能添加回应。

消息对象使用 messageUid,接口参数对象使用 messageUId。两者含义相同,但字段名不同。

功能概览

能力API
添加消息回应addMessageReaction
移除消息回应removeMessageReaction
批量查询消息回应摘要batchGetMessageReactionSummaries
分页查询一条消息上的回应列表getMessageReactions
分页查询指定回应的用户列表getMessageReactionUsers
监听消息回应变更addMessageReactionListener / removeMessageReactionListener

添加回应

调用 addMessageReaction 为指定消息添加一个回应。同一个用户不能对同一条消息重复添加同一个 reactionId

一条消息最多支持添加 50 个回应信息。超过上限时,接口返回错误码。

接口

TypeScript
IMEngine.getInstance().addMessageReaction(params): Promise<IAsyncResult<void>>

参数说明

参数类型说明
paramsUpdateMessageReactionParam添加回应参数,包含会话标识、消息 UID、回应 ID 和可选推送配置。

UpdateMessageReactionParam 属性说明:

属性类型说明
conversationIdentifierConversationIdentifier消息所属会话标识。
messageUIdstring消息唯一 ID。
reactionIdstring回应 ID。建议使用 emoji 字符,例如 👍。跨端自定义时需保证 Android、iOS、Web、HarmonyOS 使用同一标识。不能为空,且字符长度不能超过 16。
pushConfigPushConfig | null可选,回应操作相关推送配置。为空时使用默认推送配置。
pushTextstring可选,推送文案。
appDatastring可选,业务透传数据。

示例代码

TypeScript
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "targetId";

let params = new UpdateMessageReactionParam();
params.conversationIdentifier = conId;
params.messageUId = message.messageUid;
params.reactionId = "👍";

IMEngine.getInstance().addMessageReaction(params).then(result => {
if (EngineError.Success !== result.code) {
// 添加失败。可根据错误码处理重复添加、超出上限等情况。
return;
}
// 添加成功。
});

移除回应

调用 removeMessageReaction 移除当前用户已添加的回应。

接口

TypeScript
IMEngine.getInstance().removeMessageReaction(params): Promise<IAsyncResult<void>>

示例代码

TypeScript
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "targetId";

let params = new UpdateMessageReactionParam();
params.conversationIdentifier = conId;
params.messageUId = message.messageUid;
params.reactionId = "👍";

IMEngine.getInstance().removeMessageReaction(params).then(result => {
if (EngineError.Success !== result.code) {
// 移除失败,例如当前用户未添加过该回应。
return;
}
// 移除成功。
});

批量查询回应摘要

调用 batchGetMessageReactionSummaries 批量查询同一会话中多条消息的回应摘要。该接口适合在消息列表加载后批量补齐回应展示数据。

接口

TypeScript
IMEngine.getInstance().batchGetMessageReactionSummaries(
params: MessageReactionSummaryQueryParam
): Promise<IAsyncResult<Array<MessageReactionInfo>>>

参数说明

参数类型说明
paramsMessageReactionSummaryQueryParam摘要查询参数。

MessageReactionSummaryQueryParam 属性说明:

属性类型说明
conversationIdentifierConversationIdentifier消息所属会话标识。
messageUIdsArray<string>消息 UID 列表,单次最多 100 条。应传入当前会话中的消息 UID。

MessageReactionInfo 属性说明:

属性类型说明
messageUIdstring消息唯一 ID。
reactionsArray<MessageReaction>该消息上的回应摘要列表。

MessageReaction 属性说明:

属性类型说明
messageUIdstring消息唯一 ID。
reactionIdstring回应 ID。
hasCurrentUserReactedboolean当前登录用户是否已添加该回应。
countnumber添加该回应的用户总数。
reactionTimenumber回应时间戳,单位为毫秒。
usersArray<MessageReactionUser>摘要中携带的部分回应用户。摘要场景不保证返回全量用户。

MessageReactionUser 属性说明:

属性类型说明
userIdstring添加回应的用户 ID。
reactionTimenumber该用户添加回应的时间,单位为毫秒。

示例代码

TypeScript
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "groupId";

let params = new MessageReactionSummaryQueryParam();
params.conversationIdentifier = conId;
params.messageUIds = ["MessageUId1", "MessageUId2"];

IMEngine.getInstance().batchGetMessageReactionSummaries(params).then(result => {
if (EngineError.Success !== result.code || !result.data) {
// 查询失败。
return;
}
let reactionInfo = result.data.find((item: MessageReactionInfo) => item.messageUId === "MessageUId1");
// 使用 reactionInfo 刷新消息 UI。
});

如果某条消息没有回应,返回的数组中可能不包含该消息的 messageUId,或对应 reactions 为空。业务展示时应按“无回应”处理。

请注意:

  • 该接口用于查询同一会话内多条消息的回应摘要,messageUIds 应传入当前会话中的消息 UID。
  • 返回数组不保证与 messageUIds 入参顺序一致,建议按 messageUId 建立映射后更新 UI。
  • MessageReaction.users 只用于摘要展示,不代表该回应下的完整用户列表;如需完整用户列表,请调用 getMessageReactionUsers 分页查询。
  • Message.hasReactions 可作为是否需要查询摘要的提示字段,但最终展示应以本接口返回结果为准。

分页查询回应列表

调用 getMessageReactions 分页查询一条消息上的所有回应类型。返回的是回应类型列表,例如一条消息上有哪些 emoji 回应、每种回应的人数、当前用户是否已回应等。

接口

TypeScript
IMEngine.getInstance().getMessageReactions(
params: GetMessageReactionsParams
): Promise<IAsyncResult<GetMessageReactionsResult>>

使用说明

  • count 取值范围为 1 到 50。建议与实际列表页大小保持一致。
  • 首次查询时 pageToken 传空字符串。
  • 如果返回的 pageToken 为空字符串,表示没有下一页;不为空时,下一次查询继续传入该值。
  • reactions 中的每个 MessageReaction 代表一种回应类型,不是单个用户的一次回应。
  • MessageReaction.users 可能只包含部分用户。如需展示某个回应的完整用户列表,请调用 getMessageReactionUsers

参数说明

参数类型说明
paramsGetMessageReactionsParams分页查询参数。

GetMessageReactionsParams 属性说明:

属性类型说明
conversationIdentifierConversationIdentifier消息所属会话标识。
messageUIdstring消息唯一 ID。
countnumber每页条数,取值范围 1 到 50。
pageTokenstring翻页标识。首次查询传空字符串;查询下一页时使用上一次返回的 pageToken

GetMessageReactionsResult 属性说明:

属性类型说明
pageTokenstring下一页分页标识。为空表示没有下一页。
totalCountnumber回应总数。
reactionsArray<MessageReaction>当前页回应列表。

示例代码

TypeScript
let params = new GetMessageReactionsParams();
params.conversationIdentifier = conId;
params.messageUId = "MessageUId";
params.count = 50;
params.pageToken = "";

IMEngine.getInstance().getMessageReactions(params).then(result => {
if (EngineError.Success !== result.code || !result.data) {
// 查询失败。
return;
}
let reactions = result.data.reactions;
let nextPageToken = result.data.pageToken;
let totalCount = result.data.totalCount;
});

分页查询回应用户

调用 getMessageReactionUsers 查询某条消息中添加了指定回应的用户列表。该接口通常用于回应详情页,例如用户点击某个回应后,展示添加该回应的用户列表。

接口

TypeScript
IMEngine.getInstance().getMessageReactionUsers(
params: GetMessageReactionUsersParams
): Promise<IAsyncResult<GetMessageReactionUsersResult>>

使用说明

  • reactionId 必须与添加回应时使用的回应 ID 一致。
  • count 取值范围为 1 到 50。建议按列表分页加载数量设置。
  • 首次查询时 pageToken 传空字符串。
  • 如果返回的 pageToken 为空字符串,表示没有下一页;不为空时,下一次查询继续传入该值。
  • 返回的 users 只包含用户 ID 和添加回应时间;如需展示昵称、头像,需要业务侧再根据 userId 查询用户资料。

参数说明

参数类型说明
paramsGetMessageReactionUsersParams分页查询参数。

GetMessageReactionUsersParams 属性说明:

属性类型说明
conversationIdentifierConversationIdentifier消息所属会话标识。
messageUIdstring消息唯一 ID。
reactionIdstring回应 ID。
countnumber每页条数,取值范围 1 到 50。
pageTokenstring翻页标识。首次查询传空字符串;查询下一页时使用上一次返回的 pageToken

MessageReactionUser 属性说明:

属性类型说明
userIdstring添加回应的用户 ID。
reactionTimenumber该用户添加回应的时间,单位为毫秒。

GetMessageReactionUsersResult 属性说明:

属性类型说明
pageTokenstring下一页分页标识。为空表示没有下一页。
totalCountnumber添加该回应的用户总数。
usersArray<MessageReactionUser>当前页回应用户列表。

示例代码

TypeScript
let params = new GetMessageReactionUsersParams();
params.conversationIdentifier = conId;
params.messageUId = "MessageUId";
params.reactionId = "👍";
params.count = 50;
params.pageToken = "";

IMEngine.getInstance().getMessageReactionUsers(params).then(result => {
if (EngineError.Success !== result.code || !result.data) {
// 查询失败。
return;
}
let users = result.data.users;
let totalCount = result.data.totalCount;
let nextPageToken = result.data.pageToken;
});

监听回应变更

业务方可以通过 addMessageReactionListener 监听当前会话中的回应变更。建议在页面或业务模块不再需要监听时调用 removeMessageReactionListener 移除监听。

接口

TypeScript
addMessageReactionListener(listener: MessageReactionListener): boolean

removeMessageReactionListener(listener: MessageReactionListener): void

addMessageReactionListener 添加成功返回 true。如果 listener 为空或已注册过,返回 false

MessageReactionListener 定义:

TypeScript
interface MessageReactionListener {
onMessageReactionChanged(events: Array<MessageReactionEvent>): void;
}

监听回调可能一次返回多个事件,业务侧需要遍历 events。移除监听时必须传入添加监听时的同一个 listener 实例。

示例代码

TypeScript
let listener: MessageReactionListener = {
onMessageReactionChanged: (events: Array<MessageReactionEvent>): void => {
events.forEach((event: MessageReactionEvent) => {
if (event.operationType === MessageReactionOperationType.Cleared) {
// reactionId 可能为空。按 messageUId 清空该消息的全部回应。
return;
}
if (event.operationType === MessageReactionOperationType.Added) {
// 有用户添加了回应。
} else if (event.operationType === MessageReactionOperationType.Removed) {
// 有用户移除了回应。
}
});
}
};

let added = IMEngine.getInstance().addMessageReactionListener(listener);

// 不再需要监听时移除。
IMEngine.getInstance().removeMessageReactionListener(listener);

MessageReactionEvent 属性说明:

属性类型说明
conversationIdentifierConversationIdentifier事件所属会话。
messageUIdstring发生变更的消息 UID。
reactionIdstring回应 ID。事件类型为 Cleared 且清空整条消息全部回应时,该值可能为空。
operationTypeMessageReactionOperationType操作类型:AddedRemovedCleared
countnumber该回应当前总人数。Cleared 时为 0。
usersArray<MessageReactionUser>本次变更关联用户。

MessageReactionOperationType 枚举说明:

枚举说明
Added1添加回应。
Removed2移除回应。
Cleared3清空回应。

hasReactions 字段

Message 从 26.6.0 开始新增 hasReactions 字段,用于标识该消息是否存在回应。该字段由协议栈维护,业务侧通常只需要读取。

TypeScript
if (message.hasReactions) {
// 可按需调用 batchGetMessageReactionSummaries 查询真实摘要数据。
}

请注意:

  • hasReactions 是摘要查询的提示字段,不等同于完整回应列表。
  • 添加回应成功后,协议栈会将该字段更新为 true
  • 移除单个回应时,即使移除的是最后一个本地可见回应,也不会立即推断为 false,因为本地数据可能不完整。
  • 只有收到服务端清空通知后,协议栈才会将该字段更新为 false
  • 如果 hasReactionstrue,但 batchGetMessageReactionSummaries 返回空结果,业务展示时应按“无可见回应”处理。

常见结果码

消息回应接口失败时,会通过 IAsyncResult.code 返回 EngineError

结果码说明
EngineError.InvalidArgumentMessageUid消息 UID 为空或无效。
EngineError.ReactionIdInvalid回应 ID 无效。reactionId 不能为空,且字符长度不能超过 16。
EngineError.MessageReactionLimitReached单条消息上的回应类型数量已达到上限。
EngineError.MessageReactionUserOver单个回应下的用户数量已达到上限。

更多状态码请参考 SDK 状态码

相关文档