• UIKit
  • SDK
  • 服务端 API
Chat/
SDK/
Android/
消息/
SDK
  • 集成 SDK
  • 初始化
  • 登录登出
  • 消息
    • 介绍
    • 发送消息
    • 接收消息
    • 历史消息
    • 转发消息
    • 消息变更
    • 插入消息
    • 删除消息
    • 清空消息
    • 撤回消息
    • 在线消息
    • 已读回执
    • 查询消息
    • 群 @ 消息
    • 群定向消息
    • 消息免打套
    • 消息扩展
    • 消息回应
    • 消息翻译
    • 消息置顶
  • 会话
    • 介绍
    • 会话列表
    • 获取会话
    • 会话未读数
    • 置顶会话
    • 删除会话
    • 会话草稿
    • 会话标记
    • 会话分组
  • 群组
    • 介绍
    • 管理群组
    • 群资料
    • 管理群成员
    • 群成员资料
    • 自定义属性
    • 群计数器
  • 社群话题
    • 管理社群
    • 权限组
  • 用户
    • 用户资料
    • 用户状态
    • 管理好友
    • 好友分组
    • 黑名单
    • 关注与粉丝
  • 本地搜索
    • 搜索消息
    • 搜索好友
    • 搜索群组
    • 搜索群成员
  • 信令
  • 客户端 API
    • Java
  • 开发指引
  • 控制台指南
    • 创建和升级应用
    • 基本配置
    • 功能配置
    • 账号管理
    • 群组管理
    • 回调配置
  • 产品介绍
    • 消息管理
      • 单聊消息
      • 消息存储
      • 离线推送
      • 群消息
      • 消息格式
    • 账号系统
      • 登陆验证
      • 在线状态管理
    • 群相关
      • 群组系统
      • 群组管理
    • 用户资料和关系链
      • 资料管理
      • 关系链管理
  • 购买指南
    • 计费概述
    • 价格中心
  • 错误码

历史消息

功能描述

拉取历史消息的 API 在类 V2TIMManagerV2TIMManager+Message(iOS & Mac) / V2TIMMessageManager(Android & Windows) 中。
除了支持单聊、群聊历史消息的拉取外,还提供了高级接口以支持按指定方向拉取、按指定起点和指定时间范围拉取。
除了支持单独拉取本地历史消息外,还支持拉取云端历史消息。
说明:
在拉取云端历史消息时,如果检测到网络异常,SDK 会返回本地存储的历史消息。
本地存储的历史消息无时间限制,但云端存储的历史消息有存储时长的限制:
开发版:免费存储 7 天,不支持延长。
标准版:免费存储 7 天,支持延长。
进阶版:免费存储 30 天,支持延长。
说明:
延长历史消息存储时长是增值服务,如需延长历史消息存储时长,请加入 Telegram 技术交流群 联系我们。
富媒体消息(图片、文件、语音等)对应的文件存储时长,与历史消息存储时长保持一致。

拉取单聊历史消息

您可以调用接口 getC2CHistoryMessageList (Android / iOS & Mac) 获取单聊历史消息。 在网络正常的情况下会拉取最新的云端数据。如果网络出现异常,SDK 会返回本地存储的历史消息。
如果您仅仅想拉取本地历史消息,可以参考 高级接口 。 本接口支持分页拉取,参考:分页拉取
示例代码如下:
Android
iOS & Mac
// 拉取单聊历史消息
// 首次拉取,lastMsg 设置为 null
// 再次拉取时,lastMsg 可以使用返回的消息列表中的最后一条消息
V2TIMManager.getMessageManager().getC2CHistoryMessageList(#your user id#, 20, null, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onError(int code, String desc) {
Log.i("imsdk", "fail, " + code + ", " + desc);
}

@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// 记录下次拉取的 lastMsg, 用于下次拉取
V2TIMMessage lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);
Log.i("imsdk", "success");
}
});
// 拉取单聊历史消息
// 首次拉取,lastMsg 设置为 nil
// 再次拉取时,lastMsg 可以使用返回的消息列表中的最后一条消息
[V2TIMManager.sharedInstance getC2CHistoryMessageList:#your user id# count:20 lastMsg:nil succ:^(NSArray<V2TIMMessage *> *msgs) {
// 记录下次拉取的 lastMsg,用于下次拉取
V2TIMMessage *lastMsg = msgs.lastObject;
NSLog(@"success, %@", msgs);
} fail:^(int code, NSString *desc) {
NSLog(@"fail, %d, %@", code, desc);
}];

拉取群聊历史消息

您可以调用接口 getGroupHistoryMessageList (Android / iOS & Mac) 获取群聊历史消息。 在网络正常的情况下会拉取最新的云端数据。如果网络出现异常,SDK 会返回本地存储的历史消息。
如果您仅仅想拉取本地历史消息,可以参考 高级接口 。 本接口支持分页拉取,参考:分页拉取
注意:
只有会议群(Meeting)才能拉取到进群前的历史消息,更多关于群消息的限制,详见 消息能力差异
直播群(AVChatRoom)消息不存云端漫游和本地数据库,调用此接口无效。进阶版客户可以在 控制台 配置 “Message History for New Members”,即“直播群新成员查看入群前消息量”,配置路径:Applications > Your App > Chat > Configuration > Group Configuration > Group feature configuration > Message History for New Members > Previous Messages Viewable。配置后会在加入直播群成功后,在 onRecvNewMessage 回调中获得入群前消息。
示例代码如下:
Android
iOS & Mac
// 拉取群聊历史消息
// 首次拉取,lastMsg 设置为 null
// 再次拉取时,lastMsg 可以使用返回的消息列表中的最后一条消息
V2TIMManager.getMessageManager().getGroupHistoryMessageList(#your group id#, 20, null, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onError(int code, String desc) {
Log.i("imsdk", "fail, " + code + ", " + desc);
}

@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// 记录下次拉取的 lastMsg,用于下次拉取
V2TIMMessage lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);
Log.i("imsdk", "success");
}
});
// 拉取群聊历史消息
// 首次拉取,lastMsg 设置为 null
// 再次拉取时,lastMsg 可以使用返回的消息列表中的最后一条消息
[V2TIMManager.sharedInstance getGroupHistoryMessageList:#your group id# count:20 lastMsg:nil succ:^(NSArray<V2TIMMessage *> *msgs) {
// 记录下次拉取的 lastMsg,用于下次拉取
V2TIMMessage *lastMsg = msgs.lastObject;
NSLog(@"success, %@", msgs);
} fail:^(int code, NSString *desc) {
NSLog(@"fail, %d, %@", code, desc);
}];

高级功能

高级接口

如果以上的普通接口无法满足您对拉取历史消息的需求,我们还提供了高级接口 getHistoryMessageList (Android / iOS & Mac / Windows)。
该接口除了支持普通拉取单聊、群聊历史消息外,还支持以下高级特性:
支持设置消息拉取时的起点。
支持设置拉取消息的时间范围。
支持设置拉取消息的位置:从本地拉取、从云端拉取。
支持按照指定的方向拉取:往消息时间更老的方向拉取、往消息时间更新的方向拉取。
支持拉取本地指定的消息类型:文本、图片、语音、视频、文件、表情、群 tips 消息、合并消息、自定义消息等。
接口原型:
Android
iOS & Mac
Windows
public abstract void getHistoryMessageList(V2TIMMessageListGetOption option, V2TIMValueCallback<List<V2TIMMessage>> callback);
- (void)getHistoryMessageList:(V2TIMMessageListGetOption *)option
succ:(V2TIMMessageListSucc)succ
fail:(V2TIMFail)fail;
virtual void GetHistoryMessageList(const V2TIMMessageListGetOption& option,
V2TIMValueCallback<V2TIMMessageVector>* callback) = 0;
V2TIMMessageListGetOption 类参数说明:
参数
含义
单聊有效
群聊有效
是否必填
说明
getType
拉取消息的位置及方向,可以设置拉取 本地/云端更老/更新 的消息
YES
YES
YES
当设置从云端拉取时,会将本地存储消息列表与云端存储消息列表合并后返回。如果无网络,则直接返回本地消息列表。
userID
拉取指定用户的单聊历史消息
YES
NO
NO
拉取单聊消息,需要指定对方的 userID,此时 groupID 传空即可。
groupID
拉取指定群组的群聊历史消息
NO
YES
NO
拉取群聊消息,需要指定群聊的 groupID,此时 userID 传空即可。
count
单次拉取的消息数量
YES
YES
YES
建议设置为 20,否则可能影响拉取速度
messageTypeList
拉取的消息类型集合
YES
YES
NO
1. 只支持本地拉取,即当 getTypeV2TIM_GET_LOCAL_OLDER_MSGV2TIM_GET_LOCAL_NEWER_MSG 时有效。
2. 如果该字段为空,表示拉取所有的消息类型。
3. 支持的消息类型详见 V2TIMElemType (Android / iOS & Mac / Windows)。
lastMsg
最后一条消息
YES
YES
NO
可用于拉取历史消息的场景。
1. 单聊和群聊中均能使用。
2. 设置 lastMsg 作为拉取的起点,返回的消息列表中不包含这条消息。
3. 如果设置为空,则使用会话的最新一条消息作为拉取起点。
lastMsgSeq
最后一条消息的 seq
NO
YES
NO
可用于拉取历史消息或消息定位等场景。
1. 仅能在群聊中使用该字段。
2. 设置 lastMsgSeq 作为拉取的起点,返回的消息列表中包含这条消息。
3. 如果同时指定了 lastMsglastMsgSeq,SDK 优先使用 lastMsg
4. 如果均未指定 lastMsglastMsgSeq,拉取的起点取决于是否设置 getTimeBegin。设置了,则使用设置的范围作为起点;未设置,则使用最新消息作为起点。
getTimeBegin
拉取消息的时间起点。UTC 时间戳,单位:秒
YES
YES
NO
默认为 0,表示从当前时间开始拉取。
getTimePeriod
拉取消息的时间范围。单位:秒
YES
YES
NO
1. 默认为 0,表示不限制时间范围。
2. 取值的范围区间为闭区间,包含起止时间,二者关系如下:
如果 getType 指定了朝消息时间更老的方向拉取,则时间范围表示为 [getTimeBegin - getTimePeriod, getTimeBegin]。
如果 getType 指定了朝消息时间更新的方向拉取,则时间范围表示为 [getTimeBegin, getTimeBegin + getTimePeriod]。


分页拉取

上述拉取单聊历史消息、拉取群聊历史消息,及高级接口均可按照相同的方式实现分页,即使用 lastMsgcount 来实现:
1. 首次拉取,设置 lastMsg 为空,此时 SDK 会拉取到最新的消息。
2. 非首次拉取,使用上一次拉取到的消息列表中最后一条消息作为本次拉取的 lastMsg,拉取下一页数据。此时消息列表返回的消息不包含设置的 lastMsg。
3. 如果成功回调中返回的消息列表为空,表示拉取完毕,没有更多数据了。
说明:
1. 拉取到的消息列表中,越新的消息越靠前。
2. 考虑到加载效率、网络省流,建议分页时 count 设置为 20。
如果您使用 lastMsgSeq 拉取历史消息,返回的消息列表会包含lastMsgSeq 所对应的消息。 因此,非首次拉取群聊历史消息(也就是续拉)时,建议不要使用 lastMsgSeq,否则可能出现同一条消息被重复拉到的情况。 例如,现在的历史消息有 8 条,分别是:msg1、msg2、msg3、msg4、msg5、msg6、msg7、msg8。 每次拉取 4 条,首次拉取得到了 msg1、msg2、msg3、msg4,此时再用 msg4 的 lastMsgSeq 续拉,会拉到消息 msg4、msg5、msg6、msg7。两次拉取中,msg4 被重复拉取了。 如果您一定要使用 lastMsgSeq 续拉,建议处理好消息去重的逻辑。

按照时间范围拉取

您可以通过设置 getTimeBegingetTimePeriod 来拉取指定的时间范围内的消息。 如下图所示,时间范围的起止时间戳与 getType 有关。



示例代码将演示:从 2022-01-01 00:00:00 开始(时间戳是 1640966400),往过去的方向,从云端拉取一整天的群聊消息。
Android
iOS & Mac
Windows
V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取云端的更老的消息
option.setGetTimeBegin(1640966400); // 从 2022-01-01 00:00:00 开始
option.setGetTimePeriod(1 * 24 * 60 * 60); // 拉取一整天的消息
option.setCount(Integer.MAX_VALUE); // 返回时间范围内所有的消息
option.setGroupID(#you group id#); // 拉取群聊消息
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息
option.getTimeBegin = 1640966400; // 从 2022-01-01 00:00:00 开始
option.getTimePeriod = 1 * 24 * 60 * 60; // 拉取一整天的消息
option.count = INT_MAX; // 返回时间范围内所有的消息
option.groupID = #your group id#; // 拉取群聊消息
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, 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() = default;
~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_;
};

V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息
option.getTimeBegin = 1640966400; // 从 2022-01-01 00:00:00 开始
option.getTimePeriod = 1 * 24 * 60 * 60; // 拉取一整天的消息
option.count = std::numeric_limits<uint64_t>::max(); // 返回时间范围内所有的消息
option.groupID = "your group id"; // 拉取群聊消息

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) {
std::cout << "success" << std::endl;
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);

在时间范围内分页拉取

您可以同时指定拉取的时间范围和 lastMsg/lastMsgSeq。此时 SDK 的表现是:
1. 如果用户同时设置了 getTimeBegin/getTimePeriodlastMsg/lastMsgSeq,结果集可理解成:「单独按起始消息拉取的结果」与「单独按时间范围拉取的结果」 取交集。
2. 如果用户都没设置 getTimeBegin/getTimePeriodlastMsg/lastMsgSeq,结果集可理解成:从当前会话最新的一条消息开始,按照 getType 所指定的方向和拉取方式拉取。
示例代码将演示:从 2022-01-01 00:00:00 开始(时间戳是 1640966400),往过去的方向,每页 20 条,分页地从云端拉取一整天的群聊消息。
Android
iOS & Mac
Windows
// 定义变量,记录每次拉取的游标
private V2TIMMessage m_lastMsg = null; // 首次拉取时为 null

// 分页拉取逻辑
V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取云端的更老的消息
option.setGetTimeBegin(1640966400); // 从 2022-01-01 00:00:00 开始
option.setGetTimePeriod(1 * 24 * 60 * 60); // 拉取一整天的消息
option.setCount(20); // 每页 20 条
option.setLastMsg(m_lastMsg); // 上次拉取的位置 (每次返回的消息列表的最后一条消息)
option.setGroupID(#you group id#); // 拉取群聊消息
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
Log.i("imsdk", "success");
// 记录下一次拉取的 lastMsg
m_lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
// 定义变量,记录每次拉取的游标
@property (nonatomic, copy) V2TIMMessage *lastMsg;

// 分页拉取逻辑
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息
option.getTimeBegin = 1640966400; // 从 2022-01-01 00:00:00 开始
option.getTimePeriod = 1 * 24 * 60 * 60; // 拉取一整天的消息
option.count = 20; // 每页 20 条
option.lastMsg = self.lastMsg; // 上次拉取的位置 (每次返回的消息列表的最后一条消息)
option.groupID = #your group id#; // 拉取群聊消息
__weak typeof(self) weakSelf = self;
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {
NSLog(@"success");
// 记录下一次拉取的 lastMsg
weakSelf.lastMsg = msgs.lastObject;
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, 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() = default;
~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_;
};

// 定义变量,记录每次拉取的游标
V2TIMMessage lastMsg;

// 分页拉取逻辑
V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息
option.getTimeBegin = 1640966400; // 从 2022-01-01 00:00:00 开始
option.getTimePeriod = 1 * 24 * 60 * 60; // 拉取一整天的消息
option.count = 20; // 每页 20 条
option.lastMsg = 首次拉取 ? nullptr : &lastMsg; // 上次拉取的位置(每次返回的消息列表的最后一条消息)
option.groupID = "your group id"; // 拉取群聊消息

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
std::cout << "success" << std::endl;
// 记录下一次拉取的 lastMsg
lastMsg = messageList[messageList.Size() - 1];
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);

仅拉取本地消息

通过设置 getType 来实现仅拉取本地消息:
getType 取值为 V2TIM_GET_LOCAL_OLDER_MSG 时,表示往时间更旧的方向,拉取本地存储的消息。
getType 取值为 V2TIM_GET_LOCAL_NEWER_MSG 时,表示往时间更新的方向,拉取本地存储的消息。
示例代码将演示:从最新的消息开始,往更老的方向,从本地数据库中拉取 20 条单聊消息。
Android
iOS & Mac
Windows
V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_LOCAL_OLDER_MSG); // 拉取本地的更老的消息
option.setLastMsg(null); // 设置从最新的消息开始拉取
option.setCount(20); // 拉取 20 条消息
option.setUserID(#you user id#); // 拉取单聊消息
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_LOCAL_OLDER_MSG; // 拉取本地的更老的消息
option.lastMsg = nil; // 设置从最新的消息开始拉取
option.count = 20; // 拉取 20 条消息
option.userID = #your user id#; // 拉取单聊消息
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, 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() = default;
~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_;
};

V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_LOCAL_OLDER_MSG; // 拉取本地的更老的消息
option.count = 20; // 拉取 20 条消息
option.userID = "you user id"; // 拉取单聊消息

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
std::cout << "success" << std::endl;
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);


拉取指定类型的消息

SDK 定义一些常见的消息类型,例如文本、图片、视频等,参考 V2TIMElemType(Android / iOS & Mac / Windows)。高级接口 getHistoryMessageList 支持通过设置 messageTypeList,拉取指定类型的消息。
注意:
1. messageTypeList 为空时,表示拉取所有类型的消息。
2. 拉取指定的消息类型,只支持从本地拉取。从云端拉取消息不支持指定消息类型。
示例代码将演示:从当前开始,往过去的方向,拉取 20 条文本和图片消息。
Android
iOS & Mac
Windows
// 拉取图片消息、文本消息
ArrayList<Integer> messageTypeList = new ArrayList<Integer>();
messageTypeList.add(V2TIM_ELEM_TYPE_IMAGE);
messageTypeList.add(V2TIM_ELEM_TYPE_TEXT);

V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取云端的更老的消息
option.setCount(20);
option.setMessageTypeList(messageTypeList);
option.setGroupID("you group id");
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_CLOUD_OLDER_MSG;
// 拉取图片消息、文本消息
option.messageTypeList = @[@(V2TIM_ELEM_TYPE_IMAGE), @(V2TIM_ELEM_TYPE_TEXT)];
option.count = 20;
option.groupID = @"your group id";
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, 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() = default;
~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_;
};

V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取云端的更老的消息
option.count = 20; // 拉取 20 条消息
option.messageTypeList.PushBack(V2TIMElemType::V2TIM_ELEM_TYPE_IMAGE); // 拉取图片消息
option.messageTypeList.PushBack(V2TIMElemType::V2TIM_ELEM_TYPE_TEXT); // 拉取文本消息
option.userID = "you group id"; // 拉取群聊消息

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
std::cout << "success" << std::endl;
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);

拉取指定 sequence 的消息

在拉取群聊历史消息时,您可以按照指定的消息序列号 sequence 拉取。
说明:
仅拉取群组历史消息时有效;
消息序列号 seq 可以通过 V2TIMMessage 对象的 seq 字段获取;
当 getType 设置为从云端拉取时,会将本地存储消息列表与云端存储消息列表合并后返回;如果无网络,则直接返回本地消息列表;
当 getType 设置为从本地拉取时,直接返回本地的消息列表;
当 getType 设置为拉取更旧的消息时,消息列表按照时间逆序,也即消息按照时间戳从大往小的顺序排序;
当 getType 设置为拉取更新的消息时,消息列表按照时间顺序,也即消息按照时间戳从小往大的顺序排序。
示例代码将演示:在群组中,从云端拉取消息 sequence 为 1,3,5,9 的消息,并将消息按照时间逆序返回。
Android
iOS & Mac
Windows
ArrayList<Long> sequenceList = new ArrayList<>();
sequenceList.add(1L);
sequenceList.add(3L);
sequenceList.add(5L);
sequenceList.add(9L);
V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGroupID("your groupID");
option.setMessageSeqList(sequenceList);
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG;);
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {

}

@Override
public void onError(int code, String desc) {

}
});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_CLOUD_OLDER_MSG;
option.groupID = @"your groupID";
option.messageSeqList = @[@(1), @(3), @(5), @(9)];
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {

} 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() = default;
~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_;
};

V2TIMUInt64Vector sequence_list;
sequence_list.PushBack(1);
sequence_list.PushBack(3);
sequence_list.PushBack(5);
sequence_list.PushBack(9);
V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG;
option.messageSeqList = sequence_list;
option.groupID = "your group id";

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) {
std::cout << "success" << std::endl;
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);

一键跳转到群 @ 消息

在群聊会话中,收到群 @ 消息后,一般需要通过点击群 @ 提示条,跳转到群 @ 消息的位置,并拉取附近的消息列表用于显示。 由于群 @ 消息本身也需要显示,可以将 lastMsgSeq 设置成群 @ 消息的 sequence ,并使用高级接口 getHistoryMessageList 来拉取。
示例代码将演示:点击群 @ 提示后,跳转到群 @ 消息,并拉取前后各 20 条消息用于展示。
Android
iOS & Mac
Windows
// 获取群 @ 消息对应的的 sequence
long atSequence = 1081;

// 拉取群 @ 消息及之前的消息
V2TIMMessageListGetOption beforeOption = new V2TIMMessageListGetOption();
beforeOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取比群 @ 消息更早的消息
beforeOption.setCount(20); // 拉取 20 条
beforeOption.setLastMsgSeq(atSequence); // 从群 @ 消息开始拉取,包括群 @ 消息
beforeOption.setGroupID(#you group id#); // 拉取群聊消息
V2TIMManager.getMessageManager().getHistoryMessageList(beforeOption, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// 返回的消息列表中包括群 @ 消息
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});

// 拉取群 @ 消息之后的消息
V2TIMMessageListGetOption afterOption = new V2TIMMessageListGetOption();
afterOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_NEWER_MSG); // 拉取比群 @ 消息更晚的消息
afterOption.setCount(20); // 拉取 20 条
afterOption.setLastMsgSeq(atSequence + 1); // 从群 @ 消息的后一条消息开始拉取,不包括群 @ 消息
afterOption.setGroupID(#you group id#); // 拉取群聊消息
V2TIMManager.getMessageManager().getHistoryMessageList(afterOption, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// 返回的消息列表中不包括群 @ 消息
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
// 获取群 @ 消息对应的的 sequence
NSInteger atSequence = 1081;

// 拉取群 @ 消息及之前的消息
V2TIMMessageListGetOption *beforeOption = [[V2TIMMessageListGetOption alloc] init];
beforeOption.getType = V2TIM_GET_CLOUD_OLDER_MSG; // 拉取比群 @ 消息更早的消息
beforeOption.count = 20; // 拉取 20 条
beforeOption.lastMsgSeq = atSequence; // 从群 @ 消息开始拉取, 包括群 @ 消息
beforeOption.groupID = #your group id#; // 拉取群聊消息
[V2TIMManager.sharedInstance getHistoryMessageList:beforeOption succ:^(NSArray<V2TIMMessage *> *msgs) {
// 返回的消息列表中包括群 @ 消息
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];

// 拉取群 @ 消息之后的消息
V2TIMMessageListGetOption *afterOption = [[V2TIMMessageListGetOption alloc] init];
afterOption.getType = V2TIM_GET_CLOUD_NEWER_MSG; // 拉取比群 @ 消息更晚的消息
afterOption.count = 20; // 拉取 20 条
afterOption.lastMsgSeq = atSequence + 1; // 从群 @ 消息的后一条消息开始拉取,不包括群 @ 消息
afterOption.groupID = #your group id#; // 拉取群聊消息
[V2TIMManager.sharedInstance getHistoryMessageList:afterOption succ:^(NSArray<V2TIMMessage *> *msgs) {
// 返回的消息列表中不包括群 @ 消息
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, 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() = default;
~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_;
};

// 获取群 @ 消息对应的的 sequence
uint64_t atSequence = 1081;

// 拉取群 @ 消息及之前的消息
V2TIMMessageListGetOption beforeOption;
beforeOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取比群 @ 消息更早的消息
beforeOption.count = 20; // 拉取 20 条消息
beforeOption.lastMsgSeq = atSequence; // 从群 @ 消息开始拉取,包括群 @ 消息
beforeOption.userID = "you group id"; // 拉取群聊消息

auto beforeCallback = new ValueCallback<V2TIMMessageVector>{};
beforeCallback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
// 返回的消息列表中包括群 @ 消息
std::cout << "success" << std::endl;
delete beforeCallback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete beforeCallback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(beforeOption, beforeCallback);

// 拉取群 @ 消息及之前的消息
V2TIMMessageListGetOption afterOption;
afterOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_NEWER_MSG; // 拉取比群 @ 消息更晚的消息
afterOption.count = 20; // 拉取 20 条消息
afterOption.lastMsgSeq = atSequence + 1; // 从群 @ 消息的后一条消息开始拉取,不包括群 @ 消息
afterOption.userID = "you group id"; // 拉取群聊消息

auto afterCallback = new ValueCallback<V2TIMMessageVector>{};
afterCallback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
// 返回的消息列表中不包括群 @ 消息
std::cout << "success" << std::endl;
delete afterCallback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete afterCallback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(afterOption, afterCallback);

搜索场景下的消息定位

当用户通过本地搜索获取到 V2TIMMessage 对象。点击该消息后,一般需要跳转到该消息对应的位置并展示附近的消息。 此时可以将 lastMsg 设置成该消息对象,并使用高级接口 getHistoryMessageList 拉取前后的消息。
示例代码将演示:拉取搜索到的消息前后各 20 条消息,用于展示。
Android
iOS & Mac
Windows
// 获取当前的 message 对象
V2TIMMessage lastMsg = #搜索到的消息#;

// 拉取指定消息之前的消息
V2TIMMessageListGetOption beforeOption = new V2TIMMessageListGetOption();
beforeOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // 拉取比指定消息更早的消息
beforeOption.setCount(20); // 拉取 20 条
beforeOption.setLastMsg(lastMsg); // 从指定消息开始拉取,不包括该消息
beforeOption.setGroupID(#you group id#); // 拉取群聊消息
V2TIMManager.getMessageManager().getHistoryMessageList(beforeOption, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// 返回的消息列表中不包括 lastMsg
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});

// 拉取指定消息之后的消息
V2TIMMessageListGetOption afterOption = new V2TIMMessageListGetOption();
afterOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_NEWER_MSG); // 拉取比指定消息更晚的消息
afterOption.setCount(20); // 拉取 20 条
afterOption.setLastMsg(lastMsg); // 从指定消息开始拉取,不包括该消息
afterOption.setGroupID(#you group id#); // 拉取群聊消息
V2TIMManager.getMessageManager().getHistoryMessageList(afterOption, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// 返回的消息列表中不包括 lastMsg
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
// 获取当前的 message 对象
V2TIMMessage *lastMsg = #搜索后的消息#;

// 拉取指定消息之前的消息
V2TIMMessageListGetOption *beforeOption = [[V2TIMMessageListGetOption alloc] init];
beforeOption.getType = V2TIM_GET_CLOUD_OLDER_MSG; // 拉取比指定消息更早的消息
beforeOption.count = 20; // 拉取 20 条
beforeOption.lastMsg = lastMsg; // 从指定消息开始拉取, 不包括该消息
beforeOption.groupID = #your group id#; // 拉取群聊消息
[V2TIMManager.sharedInstance getHistoryMessageList:beforeOption succ:^(NSArray<V2TIMMessage *> *msgs) {
// 返回的消息列表中不包括指定消息
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];

// 拉取指定消息之后的消息
V2TIMMessageListGetOption *afterOption = [[V2TIMMessageListGetOption alloc] init];
afterOption.getType = V2TIM_GET_CLOUD_NEWER_MSG; // 拉取比指定消息更晚的消息
afterOption.count = 20; // 拉取 20 条
afterOption.lastMsg = lastMsg; // 从指定消息开始拉取,不包括该消息
afterOption.groupID = #your group id#; // 拉取群聊消息
[V2TIMManager.sharedInstance getHistoryMessageList:afterOption succ:^(NSArray<V2TIMMessage *> *msgs) {
// 返回的消息列表中不包括指定消息
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, 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() = default;
~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_;
};

// 获取当前的 message 对象
V2TIMMessage lastMsg = 搜索到的消息;

// 拉取指定消息之前的消息
V2TIMMessageListGetOption beforeOption;
beforeOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // 拉取比指定消息更早的消息
beforeOption.count = 20; // 拉取 20 条消息
beforeOption.lastMsg = lastMsg; // 从指定消息开始拉取,不包括该消息
beforeOption.userID = "you group id"; // 拉取群聊消息

auto beforeCallback = new ValueCallback<V2TIMMessageVector>{};
beforeCallback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
// 返回的消息列表中不包括 lastMsg
std::cout << "success" << std::endl;
delete beforeCallback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete beforeCallback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(beforeOption, beforeCallback);

// 拉取指定消息之后的消息
V2TIMMessageListGetOption afterOption;
afterOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_NEWER_MSG; // 拉取比指定消息更晚的消息
afterOption.count = 20; // 拉取 20 条消息
afterOption.lastMsg = lastMsg; // 从指定消息开始拉取,不包括该消息
afterOption.userID = "you group id"; // 拉取群聊消息

auto afterCallback = new ValueCallback<V2TIMMessageVector>{};
afterCallback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
// 返回的消息列表中不包括 lastMsg
std::cout << "success" << std::endl;
delete afterCallback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete afterCallback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(afterOption, afterCallback);

解析信令消息

如果您使用了 SDK 的信令相关接口(Android / iOS & Mac),调用 invite/inviteInGroup 时,设置了 onlineUserOnly false(Android) / NO(iOS),那么每次信令操作(包括 invitecancelacceptrejecttimeout)都会产生一条自定义消息,该消息会通过 V2TIMAdvancedMsgListeneronRecvNewMessage 回调抛给用户,也可以通过历史消息拉取。
如果您需要根据信令信息做自定义化文本展示,可以使用信令解析接口 getSignalingInfo (Android / iOS & Mac / Windows) 获取信令信息。
接口原型
Android
iOS & Mac
Windows
/**
* 获取信令信息
*
* 如果 invite 设置 onlineUserOnly 为 false,每次信令操作(包括 invite、cancel、accept、reject、timeout)都会产生一条自定义消息,
* 该消息会通过 V2TIMAdvancedMsgListener -> onRecvNewMessage 抛给用户,用户也可以通过历史消息拉取,如果需要根据信令信息做自定义化文本展示,可以调用下面接口获取信令信息。
*
* @param msg 消息对象
* @return V2TIMSignalingInfo 信令信息,如果为 null,则 msg 不是一条信令消息。
*/
public abstract V2TIMSignalingInfo getSignalingInfo(V2TIMMessage msg);
/**
* 获取信令信息
*
* 如果 invite 设置 onlineUserOnly 为 NO,每次信令操作(包括 invite、cancel、accept、reject、timeout)都会产生一条自定义消息,该消息会通过 V2TIMAdvancedMsgListener -> onRecvNewMessage 抛给用户,用户也可以通过历史消息拉取,如果需要根据信令信息做自定义化文本展示,可以调用下面接口获取信令信息。
*
* @param msg 消息对象
* @return V2TIMSignalingInfo 信令信息,如果为 nil,则 msg 不是一条信令消息。
*/
- (V2TIMSignalingInfo *)getSignallingInfo:(V2TIMMessage *)msg;
/**
* 获取信令信息
*
* 如果 Invite 设置 onlineUserOnly 为 false,每次信令操作(包括
* Invite、Cancel、Accept、Reject、Timeout)都会产生一条自定义消息, 该消息会通过
* V2TIMAdvancedMsgListener -> onRecvNewMessage
* 抛给用户,用户也可以通过历史消息拉取,如果需要根据信令信息做自定义化文本展示,可以调用下面接口获取信令信息。
*
* @param msg 消息对象
* @return V2TIMSignalingInfo 信令信息,如果 V2TIMSignalingInfo::inviteID 为空字符串,则 msg 不是一条信令消息。
*/
virtual V2TIMSignalingInfo GetSignalingInfo(const V2TIMMessage& msg) = 0;
示例代码将演示:拉取到历史消息之后,解析信令消息的显示文本。
Android
iOS & Mac
Windows
/// 信令消息对应的自定义文本
public String getCallSignalingContentWithMessage(V2TIMMessage message) {
if (message == null) {
Log.e(TAG, " invalid param ");
return "";
}

V2TIMSignalingInfo signalingInfo = V2TIMManager.getSignalingManager().getSignalingInfo(message);
if (signalingInfo == null) {
Log.e(TAG, " signalingInfo is null ");
return "";
}

String content = "";
Gson gson = new Gson();
Object businessIdObj = null;
String businessId = null;
try {
HashMap signalDataMap = gson.fromJson(signalingInfo.getData(), HashMap.class);
if (signalDataMap != null) {
businessIdObj = signalDataMap.get(TUIConstants.Message.CUSTOM_BUSINESS_ID_KEY);
} else {
Log.e(TAG, " signalDataMap is null ");
return "";
}
} catch (JsonSyntaxException e) {
Log.e(TAG, " get signalingInfoCustomJsonMap error ");
}

if (businessIdObj instanceof String) {
businessId = (String) businessIdObj;
}

if (TextUtils.equals(businessId, "av_call")) {
if (signalingInfo.getActionType() == V2TIMSignalingInfo.SIGNALING_ACTION_TYPE_INVITE) {
// 邀请通话
content = "@邀请通话";
} else if (signalingInfo.getActionType() == V2TIMSignalingInfo.SIGNALING_ACTION_TYPE_ACCEPT_INVITE) {
// 同意邀请
content = "@同意通话";
} else {
// 其他
// ...
}
}

return content;
}
/// 信令消息对应的自定义文本
+ (NSString *)getCallSignalingContentWithMessage:(V2TIMMessage *)message
{
V2TIMSignalingInfo *info = [[V2TIMManager sharedInstance] getSignallingInfo:message];
if (!info) {
return nil;
}
// 解析透传的data字段
NSError *err = nil;
NSDictionary *param = nil;
if (info.data != nil) {
param = [NSJSONSerialization JSONObjectWithData:[info.data dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&err];
}
if (!param || ![param isKindOfClass:[NSDictionary class]]) {
return nil;
}

// 判断业务类型
NSArray *allKeys = param.allKeys;
if (![allKeys containsObject:@"businessID"]) {
return nil;
}
NSString *businessId = [param objectForKey:@"businessID"];

// 判断是否为音视频通话信令
NSString *content = nil;
if ([businessId isEqualToString:@"av_call"]) {
if (info.actionType == SignalingActionType_Invite) {
// 邀请通话
content = @"邀请通话";
} else if (info.actionType == SignalingActionType_Accept_Invite) {
// 同意邀请
content = @"同意通话";
} else {
// 其他
// ...
}
}
return content;
}
信令消息对应的自定义文本
std::string GetCallSignalingContentWithMessage(const V2TIMMessage& message) {
V2TIMSignalingInfo signalingInfo =
V2TIMManager::GetInstance()->GetSignalingManager()->GetSignalingInfo(message);
if (signalingInfo.inviteID.Empty()) {
// 如果 V2TIMSignalingInfo::inviteID 为空,则 message 不是一条信令消息
return {};
}

// 解析透传的 data 字段,使用开源库 RapidJSON :https://github.com/Tencent/rapidjson/
rapidjson::Document document;
document.Parse(signalingInfo.data.CString(), signalingInfo.data.Size());
if (!document.HasMember("businessId") || !document["businessId"].IsString()) {
return {};
}
const char* businessId = document["businessId"].GetString();

// 判断是否为音视频通话信令
std::string content;
if (businessId == "av_call") {
if (signalingInfo.actionType == V2TIMSignalingActionType::SignalingActionType_Invite) {
// 邀请通话
content = u8"邀请通话";
}