tencent cloud

即时通信 IM

动态与公告
产品动态
公告
产品简介
产品概述
基本概念
应用场景
功能介绍
账号系统
用户资料与关系链
消息管理
群组相关
公众号系统
音视频通话 Call
使用限制
购买指南
计费概述
价格说明
购买指引
续费指引
停服说明
退费说明
开发指引
Demo 专区
开通服务
体验 Demo
快速跑通
下载中心
SDK & Demo 源码
更新日志
聊天互动(含 UI)
TUIKit 组件介绍
快速开始
全功能接入
单功能接入
AI 集成
构建基础界面
更多特性
定义外观
国际化界面语言
推送服务(Push)
服务概述
名词解释
开通服务
快速跑通
厂商通道
数据统计
排查工具
客户端 API
服务端 API
推送回调
高级功能
更新日志
错误码
常见问题
智能客服
功能概述
快速入门
集成指引
管理员操作手册
客服操作手册
更多实践
直播间搭建
AI 聊天机器人方案
超大娱乐协作社群
Discord 实现指南
游戏内集成 Chat 指南
类 WhatsApp Channel 搭建方案
发送红包
Chat 应对防火墙限制相关
无 UI 集成
快速开始
集成 SDK
初始化
登录登出
消息相关
会话相关
群组相关
社群话题
用户管理
离线推送
云端搜索
本地搜索
公众号
客户端 API
JavaScript
Android
iOS & macOS
Swift
Flutter
Electron
Unity
React Native
C 接口
C++
服务端 API
生成 UserSig
REST API
第三方回调
控制台指南
新版控制台介绍
创建并升级应用
基本配置
功能配置
账号管理
群组管理
公众号管理
回调配置
用量统计
资源包查看指南
实时监控
开发辅助工具
访问管理
高级功能
常见问题
uni-app 常见问题
购买相关问题
SDK 相关问题
账号鉴权相关问题
用户资料与关系链相关问题
消息相关问题
群组相关问题
直播群相关问题
昵称头像相关问题
协议与认证
服务等级协议
安全合规认证
IM 政策
隐私政策
数据隐私和安全协议
平滑迁移方案
平滑迁移完整版
平滑迁移简化版
错误码
联系我们

Android&iOS&Windows&Mac

PDF
聚焦模式
字号
最后更新时间: 2025-08-12 10:12:59

功能描述

消息回应功能是指对某条消息进行互动回应,典型的场景就是表情回应。表情回应是通过表情符号对消息进行互动,我们可以在回应详情中看到具体的回应人数和回应人列表。
说明
该功能仅对专业版、专业版Plus或企业版客户开放,购买专业版、专业版Plus或企业版后可使用。
该功能仅增强版 SDK 7.4 及以上版本支持。

效果展示

您可以使用本功能实现如下的表情回应效果:




接口说明

您可以基于 SDK API 实现表情回应能力,主要操作如下:
调用 addMessageReaction 接口为一条消息添加一个 emoji,添加成功后,emoji 下就会存储当前操作用户。
调用 removeMessageReaction 接口删除已经添加的 emoji,删除成功后,emoji 下就不再存储当前操作用户。
调用 getMessageReactions 接口批量拉取多条消息的 emoji 列表,其中每个 emoji 都包含了当前使用者总人数以及前 N(默认 10)个使用者用户资料。
调用 getAllUserListOfMessageReaction 接口分页拉取消息 emoji 的全量使用者用户资料。
监听 onRecvMessageReactionsChanged 回调,感知 emoji 的使用者信息变更,该回调会携带 emoji 最新的使用者信息(包含使用者总人数以及前 N 个使用者用户资料)。
具体的使用说明参见下文所述。

添加消息回应

调用addMessageReaction (Java / Swift / Objective-C / C++) 接口可以添加消息回应。
添加消息回应接口入参详解如下:
属性
含义
说明
message
消息对象
消息必须是发送成功的状态。
reactionID
消息回应 ID
在表情回应场景,reactionID 为表情 ID。
说明
1. 单条消息最大支持 10 个 Reaction,单个 Reaction 最大支持 100 个用户。
2. 如果单条消息 Reaction 数量超过最大限制,调用接口会报 ERR_SVR_MSG_REACTION_COUNT_LIMIT 错误。
3. 如果单个 Reaction 用户数量超过最大限制,调用接口会报 ERR_SVR_MSG_REACTION_USER_COUNT_LIMIT 错误。
4. 如果 Reaction 已经包含当前用户,调用接口会报 ERR_SVR_MSG_REACTION_ALREADY_CONTAIN_USER 错误。
示例代码如下:
Java
Swift
Objective-C
C++
V2TIMManager.getMessageManager().addMessageReaction(message, "emoji", new V2TIMCallback() {
@Override
public void onSuccess() {
// 添加消息回应成功
}
@Override
public void onError(int code, String desc) {
// 添加消息回应失败
}
});
V2TIMManager.shared.addMessageReaction(message: msg, reactionID: "emoji1") {
print("addMessageReaction succ")
} fail: { code, desc in
print("addMessageReaction fail, \\(code), \\(desc)")
}
[[V2TIMManager sharedInstance] addMessageReaction:message reactionID:@"emoji" succ:^{
// 添加消息回应成功
} fail:^(int code, NSString *desc) {
// 添加消息回应失败
}];
class Callback final : public V2TIMCallback {
public:
using SuccessCallback = std::function<void()>;
using ErrorCallback = std::function<void(int, const V2TIMString &)>;
Callback() = default;
~Callback() override = default;
void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}
void OnSuccess() override {
if (success_callback_) {
success_callback_();
}
}
void OnError(int error_code, const V2TIMString &error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}
private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

auto *callback = new Callback{};
callback->SetCallback(
[=]() {
// 添加消息回应成功
delete callback;
},
[=](int error_code, const V2TIMString &error_message) {
// 添加消息回应失败
delete callback;
});
V2TIMManager::GetInstance()->GetMessageManager()->AddMessageReaction(message, "emoji", callback);

删除消息回应

调用 removeMessageReaction (Java / Swift / Objective-C/ C++) 接口删除消息回应。
删除消息回应接口入参详解如下:
属性
含义
说明
message
消息对象
消息必须是发送成功的状态。
reactionID
消息回应 ID
在表情回应场景,reactionID 为表情 ID。
说明
如果 Reaction 不存在,调用接口会报 ERR_SVR_MSG_REACTION_NOT_EXISTS 错误。
如果 Reaction 不包含当前用户,调用接口会报 ERR_SVR_MSG_REACTION_NOT_CONTAIN_USER 错误。
示例代码如下:
Java
Swift
Objective-C
C++
V2TIMManager.getMessageManager().removeMessageReaction(message, "emoji", new V2TIMCallback() {
@Override
public void onSuccess() {
// 删除消息回应成功
}
@Override
public void onError(int code, String desc) {
// 删除消息回应失败
}
});
V2TIMManager.shared.removeMessageReaction(message: msg, reactionID: "emoji1") {
print("removeMessageReaction succ")
} fail: { code, desc in
print("removeMessageReaction fail, \\(code), \\(desc)")
}
[[V2TIMManager sharedInstance] removeMessageReaction:message reactionID:@"emoji" succ:^{
// 删除消息回应成功
} fail:^(int code, NSString *desc) {
// 删除消息回应失败
}];
[[V2TIMManager sharedInstance] removeMessageReaction:message reactionID:@"emoji" succ:^{
// 删除消息回应成功
} fail:^(int code, NSString *desc) {
// 删除消息回应失败
}];

批量拉取多条消息回应信息

调用getMessageReactions (Java / Swift / Objective-C/ C++) 接口批量拉取多条消息回应信息。
批量拉取多条消息回应信息接口入参详解如下:
属性
含义
说明
messageList
消息列表
消息必须属于同一个会话,消息必须是发送成功的状态。
maxUserCountPerReaction
每个 Reaction 返回的最大用户资料数量
取值范围【0,10】,每个 Reaction 最多只返回前 10 个用户资料,如需更多用户资料,
可以按需调用 getAllUserListOfMessageReaction 接口分页拉取。
拉取消息回应信息结果V2TIMMessageReactionResult 对象详解如下:
属性
含义
说明
resultCode
返回码
0:表示成功。
非0:表示失败。
resultInfo
返回信息
错误信息。
msgID
消息 ID
消息唯一 ID。
reactionList
消息回应列表
消息回应 V2TIMMessageReaction 对象列表。
其中V2TIMMessageReaction 对象详解如下:
属性
含义
说明
reactionID
消息回应 ID
在表情回应场景,reactionID 为表情 ID。
totalUserCount
总的用户个数
使用同一个 reactionID 回应消息的总的用户个数。
partialUserList
部分用户列表
使用同一个 reactionID 回应消息的部分用户列表,用户列表数量取决于调用
getMessageReactions 接口时设置的 maxUserCountPerReaction 值。
reactedByMyself
自己是否使用了该 reaction
如果自己使用了该 reaction,该字段会返回 true。
示例代码如下:
Java
Swift
Objective-C
C++
V2TIMManager.getMessageManager().getMessageReactions(msgList, 5,
new V2TIMValueCallback<List<V2TIMMessageReactionResult>>() {
@Override
public void onSuccess(List<V2TIMMessageReactionResult> v2TIMMessageReactionResults) {
// 批量拉取消息回应信息成功
for (V2TIMMessageReactionResult reactionResult : v2TIMMessageReactionResults) {
int resultCode = reactionResult.getResultCode();
String resultInfo = reactionResult.getResultInfo();
List<V2TIMMessageReaction> reactionList = reactionResult.getReactionList();
for (V2TIMMessageReaction reaction : reactionList) {
String reactionID = reaction.getReactionID();
int totalUserCount = reaction.getTotalUserCount();
List<V2TIMUserInfo> partialUserList = reaction.getPartialUserList();
}
}
}
@Override
public void onError(int code, String desc) {
// 批量拉取消息回应信息失败
}
});
if let msg = sendedMsgList.first {
V2TIMManager.shared.getMessageReactions(messageList: [msg], maxUserCountPerReaction: 10) { resultList in
for result in resultList {
let resultCode = result.resultCode
let reactionList = result.reactionList
for reaction in reactionList {
let reactionID = reaction.reactionID
let totalUserCount = reaction.totalUserCount
let partialUserList = reaction.partialUserList
// 可以在这里处理 reactionID, totalUserCount 和 partialUserList
print("Reaction ID: \\(reactionID), Total User Count: \\(totalUserCount), Partial User List: \\(partialUserList)")
}
}
} fail: { code, desc in
print("getMessageReactions fail, \\(code), \\(desc)")
}
}
[[V2TIMManager sharedInstance] getMessageReactions:msgList maxUserCountPerReaction:5
succ:^(NSArray<V2TIMMessageReactionResult *> *resultList) {
// 批量拉取消息回应信息成功
for (V2TIMMessageReactionResult *result in resultList) {
int32_t resultCode = result.resultCode;
NSString *resultInfo = result.resultInfo;
NSArray *reactionList = result.reactionList;
for (V2TIMMessageReaction *reaction in reactionList) {
NSString *reactionID = reaction.reactionID;
uint32_t totalUserCount = reaction.totalUserCount;
NSArray *partialUserList = reaction.partialUserList;
}
}
} fail:^(int code, NSString *desc) {
// 批量拉取消息回应信息失败
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T &)>;
using ErrorCallback = std::function<void(int, const V2TIMString &)>;
ValueCallback() = defalt;
~ValueCallback() override = default;
void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}
void OnSuccess(const T &value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString &error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}
private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

auto *callback = new ValueCallback<V2TIMMessageReactionResultVector>{};
callback->SetCallback(
[=](const V2TIMMessageReactionResultVector &messageReactionResultList) {
// 批量拉取消息回应信息成功
delete callback;
},
[=](int error_code, const V2TIMString &error_message) {
// 批量拉取消息回应信息失败
delete callback;
});
V2TIMMessageVector message_list;
message_list.PushBack(message);
V2TIMManager::GetInstance()->GetMessageManager()->GetMessageReactions(message_list, 5, callback);

分页拉取全量消息回应用户列表

调用getAllUserListOfMessageReaction (Java / Swift / Objective-C / C++) 接口分页拉取全量消息回应用户列表。
分页拉取全量消息回应用户列表接口入参详解如下:
属性
含义
说明
message
消息对象
消息必须是发送成功的状态。
reactionID
消息回应 ID
在表情回应场景,reactionID 为表情 ID。
nextSeq
分页拉取的游标
第一次传 0,后续分页传 succ 返回的 nextSeq。
count
一次分页最大拉取个数
最大支持 100 个
示例代码如下:
Java
Swift
Objective-C
C++
int nextSeq = 0;
int count = 100;
V2TIMManager.getMessageManager().getAllUserListOfMessageReaction(message, "emoji", nextSeq, count,
new V2TIMValueCallback<V2TIMMessageReactionUserResult>() {
@Override
public void onSuccess(V2TIMMessageReactionUserResult v2TIMMessageReactionUserResult) {
// 分页拉取全量消息回应用户列表成功
// nextSeq:下次分页拉取的游标
}
@Override
public void onError(int code, String desc) {
// 分页拉取全量消息回应用户列表失败
}
});
V2TIMManager.shared.getAllUserListOfMessageReaction(message: msg, reactionID: "emoji1", nextSeq: 0, count: 20) { userList, nextSeq, isFinished in
var userListDesc = "";
userList.forEach { item in
userListDesc += item.description
}
// nextSeq:下次分页拉取的游标
print("\\(userListDesc), \\(nextSeq), \\(isFinished)");
} fail: { code, desc in
print("getMessageReactionUsers fail, \\(code), \\(desc)")
}
uint32_t nextSeq = 0;
uint32_t count = 100;
[[V2TIMManager sharedInstance] getAllUserListOfMessageReaction:message reactionID:@"emoji" nextSeq:nextSeq count:count
succ:^(NSArray<V2TIMUserInfo *> *userList, uint32_t nextSeq, BOOL isFinished) {
// 分页拉取全量消息回应用户列表成功
// nextSeq:下次分页拉取的游标
} fail:^(int code, NSString *desc) {
// 分页拉取全量消息回应用户列表失败
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T &)>;
using ErrorCallback = std::function<void(int, const V2TIMString &)>;
ValueCallback() = defalt;
~ValueCallback() override = default;
void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}
void OnSuccess(const T &value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString &error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}
private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

auto *callback = new ValueCallback<V2TIMMessageReactionUserResult>{};
callback->SetCallback(
[=](const V2TIMMessageReactionUserResult &messageReactionUserResult) {
// 分页拉取全量消息回应用户列表成功
delete callback;
},
[=](int error_code, const V2TIMString &error_message) {
// 分页拉取全量消息回应用户列表失败
delete callback;
});
V2TIMManager::GetInstance()->GetMessageManager()->GetAllUserListOfMessageReaction(message, "emoji", 0, 100, callback);

消息回应信息更新

如果您事先调用addAdvancedMsgListener添加了高级消息事件监听器,当消息回应信息发生了更新,您会收onRecvMessageReactionsChanged (Java / Swift / Objective-C / C++) 回调。
需要注意的是该回调是消息 Reaction 的增量回调,只会携带变更的 Reaction 信息。当变更的 Reaction 信息里的totalUserCount字段值为0时,表明该 Reaction 已经没有用户在使用,您可以在 UI 上移除该 Reaction 的展示。
示例代码如下:
Java
Swift
Objective-C
C++
V2TIMManager.getMessageManager().addAdvancedMsgListener(new V2TIMAdvancedMsgListener() {
@Override
public void onRecvMessageReactionsChanged(List<V2TIMMessageReactionChangeInfo> changeInfos) {
// 收到消息扩展变更通知
String msgID = changeInfo.getMessageID();
// 变更的 reaction 列表
List<V2TIMMessageReaction> reactionList = changeInfo.getReactionList();
}
});
V2TIMManager.shared.addAdvancedMsgListener(listener: self)
func onRecvMessageReactionsChanged(changeList: Array<V2TIMMessageReactionChangeInfo>) {
// 收到消息回应更新回调
for changeInfo in changeList {
let msgID = changeInfo.msgID
// 变更的 reaction 列表
let reactionList = changeInfo.reactionList
}
}
[[V2TIMManager sharedInstance] addAdvancedMsgListener:self];
- (void)onRecvMessageReactionsChanged:(NSArray<V2TIMMessageReactionChangeInfo *> *)changeList {
// 收到消息回应更新回调
for (V2TIMMessageReactionChangeInfo *changeInfo in changeList) {
NSString *msgID = changeInfo.msgID;
// 变更的 reaction 列表
NSArray *reactionList = changeInfo.reactionList;
}
}
V2TIMManager::GetInstance()->GetMessageManager()->AddAdvancedMsgListener(this);
void OnRecvMessageReactionsChanged(const V2TIMMessageReactionChangeInfoVector &changeInfos) override {
for (size_t i = 0; i < changeInfos.Size(); i++) {
V2TIMMessageReactionChangeInfo reactionChangeInfo = changeInfos[i];
V2TIMString msgID = reactionChangeInfo.msgID;
// 变更的 reaction 列表
V2TIMMessageReactionVector reactionList = reactionChangeInfo.reactionList;
}
}


帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈