消息回应
消息回应(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 个回应信息。超过上限时,接口返回错误码。
接口
IMEngine.getInstance().addMessageReaction(params): Promise<IAsyncResult<void>>
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
params | UpdateMessageReactionParam | 添加回应参数,包含会话标识、消息 UID、回应 ID 和可选推送配置。 |
UpdateMessageReactionParam 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
conversationIdentifier | ConversationIdentifier | 消息所属会话标识。 |
messageUId | string | 消息唯一 ID。 |
reactionId | string | 回应 ID。建议使用 emoji 字符,例如 👍。跨端自定义时需保证 Android、iOS、Web、HarmonyOS 使用同一标识。不能为空,且字符长度不能超过 16。 |
pushConfig | PushConfig | null | 可选,回应操作相关推送配置。为空时使用默认推送配置。 |
pushText | string | 可选, 推送文案。 |
appData | string | 可选,业务透传数据。 |
示例代码
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 移除当前用户已添加的回应。
接口
IMEngine.getInstance().removeMessageReaction(params): Promise<IAsyncResult<void>>
示例代码
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 批量查询同一会话中多条消息的回应摘要。该接口适合在消息列表加载后批量补齐回应展示数据。
接口
IMEngine.getInstance().batchGetMessageReactionSummaries(
params: MessageReactionSummaryQueryParam
): Promise<IAsyncResult<Array<MessageReactionInfo>>>
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
params | MessageReactionSummaryQueryParam | 摘要查询参数。 |
MessageReactionSummaryQueryParam 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
conversationIdentifier | ConversationIdentifier | 消息所属会话标识。 |
messageUIds | Array<string> | 消息 UID 列表,单次最多 100 条。应传入当前会话中的消息 UID。 |
MessageReactionInfo 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
messageUId | string | 消息唯一 ID。 |
reactions | Array<MessageReaction> | 该消息上的回应摘要列表。 |
MessageReaction 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
messageUId | string | 消息唯一 ID。 |
reactionId | string | 回应 ID。 |
hasCurrentUserReacted | boolean | 当前登录用户是否已添加该回应。 |
count | number | 添加该回应的用户总数。 |
reactionTime | number | 回应时间戳,单位为毫秒。 |
users | Array<MessageReactionUser> | 摘要中携带的部分回应用户。摘要场景不保证返回全量用户。 |
MessageReactionUser 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
userId | string | 添加回应的用户 ID。 |
reactionTime | number | 该用户添加回应的时间,单位为毫秒。 |
示例代码
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 回应、每种回应的人数、当前用户是否已回应等。
接口
IMEngine.getInstance().getMessageReactions(
params: GetMessageReactionsParams
): Promise<IAsyncResult<GetMessageReactionsResult>>
使用说明
count取值范围为 1 到 50。建议与实际列表页大小保持一致。- 首次查询时
pageToken传空字符串。 - 如果返回的
pageToken为空字符串,表示没有下一页;不为空时,下一次查询继续传入该值。 reactions中的每个MessageReaction代表一种回应类型,不是单个用户的一次回应。MessageReaction.users可能只包含部分用户。如需展示某个回应的完整用户列表,请调用getMessageReactionUsers。
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
params | GetMessageReactionsParams | 分页查询参 数。 |
GetMessageReactionsParams 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
conversationIdentifier | ConversationIdentifier | 消息所属会话标识。 |
messageUId | string | 消息唯一 ID。 |
count | number | 每页条数,取值范围 1 到 50。 |
pageToken | string | 翻页标识。首次查询传空字符串;查询下一页时使用上一次返回的 pageToken。 |
GetMessageReactionsResult 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
pageToken | string | 下一页分页标识。为空表示没有下一页。 |
totalCount | number | 回应总数。 |
reactions | Array<MessageReaction> | 当前页回应列表。 |
示例代码
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 查询某条消息中添加了指定回应的用户列表。该接口通常用于回应详情页,例如用户点击某个回应后,展示添加该回应的用户列表。
接口
IMEngine.getInstance().getMessageReactionUsers(
params: GetMessageReactionUsersParams
): Promise<IAsyncResult<GetMessageReactionUsersResult>>
使用说明
reactionId必须与添加回应时使用的回应 ID 一致。count取值范围为 1 到 50。建议按列表分页加载数量设置。- 首次查询时
pageToken传空字符串。 - 如果返回的
pageToken为空字符串,表示没有下一页;不为空时,下一次查询继续传入该值。 - 返回的
users只包含用户 ID 和添加回应时间;如需展示昵称、头像,需要业务侧再根据userId查询用户资料。
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
params | GetMessageReactionUsersParams | 分页查询参数。 |
GetMessageReactionUsersParams 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
conversationIdentifier | ConversationIdentifier | 消息所属会话标识。 |
messageUId | string | 消息唯一 ID。 |
reactionId | string | 回应 ID。 |
count | number | 每页条数,取值范围 1 到 50。 |
pageToken | string | 翻页标识。首次查询传空字符串;查询下一页时使用上一次返回的 pageToken。 |
MessageReactionUser 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
userId | string | 添加回应的用户 ID。 |
reactionTime | number | 该用户添加回应的时间,单位为毫秒。 |
GetMessageReactionUsersResult 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
pageToken | string | 下一页分页标识。为空表示没有下一页。 |
totalCount | number | 添加该回应的用户总数。 |
users | Array<MessageReactionUser> | 当前页回应用户列表。 |
示例代码
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 移除监听。
接口
addMessageReactionListener(listener: MessageReactionListener): boolean
removeMessageReactionListener(listener: MessageReactionListener): void
addMessageReactionListener 添加成功返回 true。如果 listener 为空或已注册过,返回 false。
MessageReactionListener 定义:
interface MessageReactionListener {
onMessageReactionChanged(events: Array<MessageReactionEvent>): void;
}
监听回调可能一次返回多个事件,业务侧需要遍历 events。移除监听时必须传入添加监听时的同一个 listener 实例。
示例代码
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 属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
conversationIdentifier | ConversationIdentifier | 事件所属会话。 |
messageUId | string | 发生变更的消息 UID。 |
reactionId | string | 回应 ID。事件类型为 Cleared 且清空整条消息全部回应时,该值可能为空。 |
operationType | MessageReactionOperationType | 操作类型:Added、Removed、Cleared。 |
count | number | 该回应当前总人数。Cleared 时为 0。 |
users | Array<MessageReactionUser> | 本次变更关联用户。 |
MessageReactionOperationType 枚举说明:
| 枚举 | 值 | 说明 |
|---|---|---|
Added | 1 | 添加回应。 |
Removed | 2 | 移除回应。 |
Cleared | 3 | 清空回应。 |
hasReactions 字段
Message 从 26.6.0 开始新增 hasReactions 字段,用于标识该消息是否存在回应。该字段由协议栈维护,业务侧通常只需要读取。
if (message.hasReactions) {
// 可按需调用 batchGetMessageReactionSummaries 查询真实摘要数据。
}
请注意:
hasReactions是摘要查询的提示字段,不等同于完整回应列表。- 添加回应成功后,协议栈会将该字段更新为
true。 - 移除单个回应时,即使移除的是最后一个本地可见回应,也不会立即推断为
false,因为本地数据可能不完整。 - 只有收到服务端清空通知后,协议栈才会将该字段更新为
false。 - 如果
hasReactions为true,但batchGetMessageReactionSummaries返回空结果,业务展示时应按“无可见回应”处理。
常见结果码
消息回应接口失败时,会通过 IAsyncResult.code 返回 EngineError。
| 结果码 | 说明 |
|---|---|
EngineError.InvalidArgumentMessageUid | 消息 UID 为空或无效。 |
EngineError.ReactionIdInvalid | 回应 ID 无效。reactionId 不能为空,且字符长度不能超过 16。 |
EngineError.MessageReactionLimitReached | 单条消息上的回应类型数量已达到上限。 |
EngineError.MessageReactionUserOver | 单个回应下的用户数量已达到上限。 |
更多状态码请参考 SDK 状态码。