消息回应
功能描述
消息回应功能是指对某条消息进行互动回应,典型的场景就是表情回应。表情回应是通过表情符号对消息进行互动,我们可以在回应详情中看到具体的回应人数和回应人列表。
效果展示
您可以使用本功能实现如下的表情回应效果:


接口说明
您可以基于 SDK API 实现表情回应能力,主要操作如下:
调用
addMessageReaction
接口为一条消息添加一个 emoji,添加成功后,emoji 下就会存储当前操作用户。调用
removeMessageReaction
接口删除已经添加的 emoji,删除成功后,emoji 下就不再存储当前操作用户。调用
getMessageReactions
接口批量拉取多条消息的 emoji 列表,其中每个 emoji 都包含了当前使用者总人数以及前 N(默认 10)个使用者用户资料。调用
getAllUserListOfMessageReaction
接口分页拉取消息 emoji 的全量使用者用户资料。监听
onRecvMessageReactionsChanged
回调,感知 emoji 的使用者信息变更,该回调会携带 emoji 最新的使用者信息(包含使用者总人数以及前 N 个使用者用户资料)。具体的使用说明参见下文所述。
添加消息回应
添加消息回应接口入参详解如下:
属性 | 含义 | 说明 |
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 错误。
示例代码如下:
V2TIMManager.getMessageManager().addMessageReaction(message, "emoji", new V2TIMCallback() {@Overridepublic void onSuccess() {// 添加消息回应成功}@Overridepublic void onError(int code, String desc) {// 添加消息回应失败}});
V2TIMManager.shared.addMessageReaction(message: msg, reactionID: "emoji1") {print("addMessageReaction succ")} fail: { code, desc inprint("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);
删除消息回应
删除消息回应接口入参详解如下:
属性 | 含义 | 说明 |
message | 消息对象 | 消息必须是发送成功的状态。 |
reactionID | 消息回应 ID | 在表情回应场景,reactionID 为表情 ID。 |
说明
如果 Reaction 不存在,调用接口会报 ERR_SVR_MSG_REACTION_NOT_EXISTS 错误。
如果 Reaction 不包含当前用户,调用接口会报 ERR_SVR_MSG_REACTION_NOT_CONTAIN_USER 错误。
示例代码如下:
V2TIMManager.getMessageManager().removeMessageReaction(message, "emoji", new V2TIMCallback() {@Overridepublic void onSuccess() {// 删除消息回应成功}@Overridepublic void onError(int code, String desc) {// 删除消息回应失败}});
V2TIMManager.shared.removeMessageReaction(message: msg, reactionID: "emoji1") {print("removeMessageReaction succ")} fail: { code, desc inprint("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) {// 删除消息回应失败}];
批量拉取多条消息回应信息
批量拉取多条消息回应信息接口入参详解如下:
属性 | 含义 | 说明 |
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。 |
示例代码如下:
V2TIMManager.getMessageManager().getMessageReactions(msgList, 5,new V2TIMValueCallback<List<V2TIMMessageReactionResult>>() {@Overridepublic 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();}}}@Overridepublic void onError(int code, String desc) {// 批量拉取消息回应信息失败}});
if let msg = sendedMsgList.first {V2TIMManager.shared.getMessageReactions(messageList: [msg], maxUserCountPerReaction: 10) { resultList infor result in resultList {let resultCode = result.resultCodelet reactionList = result.reactionListfor reaction in reactionList {let reactionID = reaction.reactionIDlet totalUserCount = reaction.totalUserCountlet partialUserList = reaction.partialUserList// 可以在这里处理 reactionID, totalUserCount 和 partialUserListprint("Reaction ID: \(reactionID), Total User Count: \(totalUserCount), Partial User List: \(partialUserList)")}}} fail: { code, desc inprint("getMessageReactions fail, \(code), \(desc)")}}
[[V2TIMManager sharedInstance] getMessageReactions:msgList maxUserCountPerReaction:5succ:^(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);
分页拉取全量消息回应用户列表
分页拉取全量消息回应用户列表接口入参详解如下:
属性 | 含义 | 说明 |
message | 消息对象 | 消息必须是发送成功的状态。 |
reactionID | 消息回应 ID | 在表情回应场景,reactionID 为表情 ID。 |
nextSeq | 分页拉取的游标 | 第一次传 0,后续分页传 succ 返回的 nextSeq。 |
count | 一次分页最大拉取个数 | 最大支持 100 个 |
示例代码如下:
int nextSeq = 0;int count = 100;V2TIMManager.getMessageManager().getAllUserListOfMessageReaction(message, "emoji", nextSeq, count,new V2TIMValueCallback<V2TIMMessageReactionUserResult>() {@Overridepublic void onSuccess(V2TIMMessageReactionUserResult v2TIMMessageReactionUserResult) {// 分页拉取全量消息回应用户列表成功// nextSeq:下次分页拉取的游标}@Overridepublic void onError(int code, String desc) {// 分页拉取全量消息回应用户列表失败}});
V2TIMManager.shared.getAllUserListOfMessageReaction(message: msg, reactionID: "emoji1", nextSeq: 0, count: 20) { userList, nextSeq, isFinished invar userListDesc = "";userList.forEach { item inuserListDesc += item.description}// nextSeq:下次分页拉取的游标print("\(userListDesc), \(nextSeq), \(isFinished)");} fail: { code, desc inprint("getMessageReactionUsers fail, \(code), \(desc)")}
uint32_t nextSeq = 0;uint32_t count = 100;[[V2TIMManager sharedInstance] getAllUserListOfMessageReaction:message reactionID:@"emoji" nextSeq:nextSeq count:countsucc:^(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 的展示。示例代码如下:
V2TIMManager.getMessageManager().addAdvancedMsgListener(new V2TIMAdvancedMsgListener() {@Overridepublic 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;}}