获取历史消息
获取历史消息可以仅从本地数据中获取,仅从远端获取,和同时从本地与远端获取。
开通服务
从远端获取单群聊历史消息是指从融云服务端获取历史消息,该功能要求 App Key 已启用融云提供的单群聊消息云端存储服务。您可以在控制台 IM 服务的服务购买页面为当前使用的 App Key 开启服务。如果使用生产环境的 App Key,请注意仅 IM 旗舰版或 IM 尊享版可开通该服务。具体功能与费用以融云官方价格说明页面及计费说明文档为准。
请注意区分历史消息记录与离线消息?。融云针对单聊、群聊、系统消息默认提供最多 7 天(可调整)的离线消息缓存服务。客户端上线时 SDK 会自动收取离线期间的消息,无需 App 层调用 API。
从本地数据库中获取消息
从本地数据库中获取单条消息:消息 messageId
您可以根据消息 messageId 从本地数据库中获取单条消息。
接口原型
public getMessageById(messageId: number): Promise<IAsyncResult<Message>>;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
messageId | number | 消息的 ID |
示例代码
let messageId = 123;
IMEngine.getInstance().getMessageById(messageId).then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
// 消息体
let msg = result.data as Message;
});
从本地数据库中获取单条消息:消息 msgUid
您可以根据消息 msgUid 从本地数据库中获取单条消息。
接口原型
public getMessageByUid(messageUid: string): Promise<IAsyncResult<Message>>;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
msgUid | string | 消息 唯一 id,发送成功的消息才有 uid |
示例代码
let msgUid = "CG5U-IGFN-F6S6-CVTR";
IMEngine.getInstance().getMessageByUid(msgUid).then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
// 消息体
let msg = result.data as Message;
});
从本地数据库中分页获取批量消息:消息 meeeageId
您可以查询指定会话存储在本地数据库中的历史消息,并返回消息对象列表。
接口说明
public getHistoryMessagesById(conId: ConversationIdentifier, option: IGetLocalMsgByIdOption): Promise<IAsyncResult<List<Message>>>;
参数说明
| 参数名 | 类型 | 详细说明 |
|---|---|---|
conId | ConversationIdentifier | 会话标识对象,包含会话类型和会话 targetId |
option | IGetLocalMsgByIdOption | 消息查询配置选项 |
参数 IGetLocalMsgByIdOption 的详细描述
/**
* 获取本地消息的配置
*
* beforeCount afterCount 总共分为四种情况
* ```
* 1. beforeCount > 0 && afterCount > 0,将获取 beforeCount + {messageId} + afterCount 的消息
* 2. beforeCount > 0 && afterCount == 0,将获取 beforeCount + {messageId} 的消息
* 3. beforeCount == 0 && afterCount > 0,将获取 {messageId} + afterCount 的消息
* 4. beforeCount == 0 && afterCount == 0,将获取 {messageId}
* ```
* @version 1.0.0
*/
interface IGetLocalMsgByIdOption {
/**
* objectName 集合,为空的话代表获取所有类型的本地消息
*
* 有效值的话代表获取指定类型的消息
*/
objNameList?: List<string>,
/**
* 消息本地数据库 ID
*/
messageId: number,
/**
* 在 messageId 之前的消息个数,取值 ≥0
* @discussion beforeCount 如果传入 10 ,但是获取的个数不足时说明往前没有更多的消息了
*/
beforeCount: number,
/**
* 在 messageId 之后的消息个数,取值 ≥0
* @discussion afterCount 如果传入 10 ,但是获取的个数不足时说明往后没有更多的消息了
*/
afterCount: number,
}
示例代码
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 id";
let option: IGetLocalMsgByIdOption = {
objNameList: objNameList,
messageId: messageId,
beforeCount: beforeCount,
afterCount: afterCount
}
IMEngine.getInstance().getHistoryMessagesById(conId, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
// 消息体
let msg = result.data as List<Message>;
});
从本地数据库中分页获取批量消息:时间戳
您可以根据时间戳查询指定会话存储在本地数据库中的历史消息,并返回消息对象列表。
接口原型
public getHistoryMessagesByTime(conId: ConversationIdentifier, option: IGetLocalMsgByTimeOption): Promise<IAsyncResult<List<Message>>>;
参数说明
| 参数名 | 类型 | 详细说明 |
|---|---|---|
conId | ConversationIdentifier | 会话标识对象,需包含有效的会话类型和会话 targetId |
option | IGetLocalMsgByTimeOption | 基于时间范围的消息查询配置 |
参数 IGetLocalMsgByTimeOption 的详细描述
/**
* 获取本地消息的配置
*
* beforeCount afterCount 总共分为四种情况
* ```
* 1. beforeCount > 0 && afterCount > 0,将获取 beforeCount + {time} + afterCount 的消息
* 2. beforeCount > 0 && afterCount == 0,将获取 beforeCount + {time} 的消息
* 3. beforeCount == 0 && afterCount > 0,将获取 {time} + afterCount 的消息
* 4. beforeCount == 0 && afterCount == 0,将获取 {time}
* ```
* @version 1.0.0
*/
interface IGetLocalMsgByTimeOption {
/**
* objectName 集合,为空的话代表获取所有类型的本地消息
*
* 有效值的话代表获取指定类型的消息
*/
objNameList?: List<string>,
/**
* 毫秒时间戳
* 初次可以传入当前时间: Date.now() 或者传入会话的 lastSentTime
* @see Conversation
*/
time: number,
/**
* 在 messageId 之前的消息个数,取值 ≥0
* @discussion beforeCount 如果传入 10 ,但是获取的个数不足时说明往前没有更多的消息了
*/
beforeCount: number,
/**
* 在 messageId 之后的消息个数,取值 ≥0
* @discussion afterCount 如果传入 10 ,但是获取的个数不足时说明往后没有更多的消息了
*/
afterCount: number,
}
示例代码
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 id";
let option: IGetLocalMsgByTimeOption = {
objNameList: objNameList,
time: time,
beforeCount: beforeCount,
afterCount: afterCount
}
IMEngine.getInstance().getHistoryMessagesByTime(conId, option)
.then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
// 消息列表
let msgList = result.data as List<Message>;
});
获取本地批量未读 @ 消息
接口原型
public getUnreadMentionedMessages(conId: ConversationIdentifier, option: ICountOption): Promise<IAsyncResult<List<Message>>>;
参数说明
| 参数名 | 类型 | 详细说明 |
|---|---|---|
conId | ConversationIdentifier | 会话唯一标识对象,需包含有效的会话类型和会话 ID |
option | ICountOption | 未读提及消息查询配置 |
参数 ICountOption 的详细描述
/**
* 个数配置
* @version 1.0.0
*/
interface ICountOption {
/**
* 消息个数
*/
count: number,
/**
* 获取数据顺序
* @see Order
*/
order: Order,
}
示例代码
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 id";
let option: ICountOption = {
count: 5,
order: Order.Descending
};
IMEngine.getInstance().getUnreadMentionedMessages(conId, option)
.then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
// 消息列表
let msgList = result.data as List<Message>;
});
获取本地第一条未读消息
示例代码
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 id";
IMEngine.getInstance().getFirstUnreadMessage(conId)
.then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
let msg = result.data as Message;
});
按日期查询本地消息数量
SDK 从 26.9.0 版本开始支持通过 IMEngine 按日期查询本地消息数量。
您可以通过 getMessageCountDetail 查询指定会话 在时间范围内每天的本地消息数量。该接口只返回日期和消息数量,不返回消息对象,也不会发起网络请求,无需额外开通服务。
接口原型
public getMessageCountDetail(
conId: ConversationIdentifier,
options: MessageCountDetailOptions,
): Promise<IAsyncResult<List<MessageCountDetail>>>;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
conId | ConversationIdentifier | 必填,会话标识,包含会话类型 conversationType、会话 ID targetId 和频道 ID channelId。channelId 默认为空字符串,仅查询频道 ID 为空的消息,不表示查询所有频道。 |
options | MessageCountDetailOptions | 必填,查询时间范围。 |
MessageCountDetailOptions 字 段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
startTime | number | 开始时间,包含在查询范围内。使用 Unix 毫秒时间戳,可以是自然日内的任意时刻。 |
endTime | number | 结束时间,不包含在查询范围内。使用 Unix 毫秒时间戳,必须大于 startTime,可以是自然日内的任意时刻。 |
起止时间必须为安全整数(满足 Number.isSafeInteger)。
返回值为 Promise<IAsyncResult<List<MessageCountDetail>>>。应先判断 result.code:为 EngineError.Success 时,result.data 为每日统计列表;失败时,result.data 为 null,根据错误码处理失败。
MessageCountDetail 返回结果说明:
| 字段 | 类型 | 说明 |
|---|---|---|
dateMs | number | 查询时设备时区下当天零点的 Unix 毫秒时间戳。 |
messageCount | number | 该自然日内、且位于查询范围内的本地消息数量。 |
示例代码
以下示例按设备时区计算本月及下月第一天的零点,查询当前月份每天的本地消息数量。请将 targetId 替换为待查询的会话 ID。
let now = new Date();
let monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
let nextMonthStart = new Date(now.getFullYear(), now.getMonth() + 1, 1);
let options: MessageCountDetailOptions = {
startTime: monthStart.getTime(),
endTime: nextMonthStart.getTime(),
};
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "targetId";
IMEngine.getInstance().getMessageCountDetail(conId, options).then(result => {
if (EngineError.Success !== result.code) {
// 根据 result.code 处理查询失败。
return;
}
if (!result.data) {
return;
}
let details = result.data;
for (let i = 0; i < details.length; i++) {
let detail = details.get(i);
// 使用 detail.dateMs 和 detail.messageCount 标记日历中有消息的日期。
}
});
如需查询带频道 ID 的单聊或群聊会话,请在调用前设置 conId.channelId 为对应的业务标识。
- 按消息发送时间统计,包含开始时间,不包含结束时间,即
[startTime, endTime)。单次查询最多覆盖 180 个自然日。 - SDK 按查询时设备的系统时区划分自然日,即当天零点至次日零点。首尾日期只统计查询范围内的消息;结束时间恰好为零点时,不包含该日期。
- 结果按日期从新到旧排列,只包含有匹配消息的日期。没有匹配消息时,查询成功并返回空列表。
获取远端历史消息
您可以使用 getRemoteHistoryMessages 方法可直接查询指定会话存储在单群聊消息云端存储中的历史消息。
- 用户是否可以获取在加入群组之前的群聊历史消息取决于 App 在控制台的设置。您可以在需先按控制台内嵌指南嵌入到管理后台的 IM 服务功能配置页面(page_code: im_service_config)中,进入 单群聊 > 新用户获取加入群组前历史消息,启用此选项。启用后,新入群用户可以获取在他们加入群组之前发送的所有群聊消息。如不启用, 新入群用户只能看到他们入群后的群聊消息。
- 默认情况下,用户不在群组中不能获取群组中的历史消息。如果您希望用户未在指定群组中时,也可以获取群组历史消息,可以在需先按控制台内嵌指南嵌入到管理后台的 IM 服务功能配置页面(page_code: im_service_config)中,进入 单群聊 > 用户不在群组时是否可以拉取历史消息,允许不在群组的用户也可以获取该群组的的历史消息。
获取远端批量消息
接口原型
public getRemoteHistoryMessages(conId: ConversationIdentifier, option: IGetRemoteMsgOption): Promise<IAsyncResult<List<Message>>>;
参数说明
| 参数名 | 类型 | 详细说明 |
|---|---|---|
conId | ConversationIdentifier | 会话唯一标识对象,需包含有效的会话类型和会话 ID |
option | IGetRemoteMsgOption | 云端历史消息查询配置 |
参数 IGetRemoteMsgOption 的详细描述
/**
* 获取远端消息配置
* @version 1.0.0
*/
interface IGetRemoteMsgOption {
/**
* 毫秒时间戳
* 初次可以传入当前时间: Date.now() 或者传入 Conversation.lastSentTime
*/
time: number,
/**
* 消息个数,[1 ~ 100]
*/
count: number,
/**
* 获取的消息顺序
*
* Descending: 获取比 time 小的消息列表
*
* Ascending:获取比比 time 大的消息列表
*/
order: Order,
/**
* 是否包含本地已存在消息
*
* @discussion true: 拉取回来的消息全部返回 ; false: 拉取回来的消息只返回本地数据库中不存在的
*/
isCheckDup: boolean,
}
示例代码
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "会话 id";
let option: IGetRemoteMsgOption = {
time: time,
count: 10,
order: Order.Descending,
isCheckDup: true
}
IMEngine.getInstance().getRemoteHistoryMessages(conId, option).then(result => {
if (EngineError.Success !== result.code) {
// 获取消息失败
return;
}
if (!result.data) {
// 消息不存在
return;
}
// 消息列表
let msgList = result.data as List<Message>;
});