IM 即时通讯
Windows/macOS
开发指南

历史记录

更新时间: 2023/09/13 18:49:22

本地记录

  • 获取聊天对象的本地消息记录

通过传入指定的消息历史记录的参数(会话id,会话类型,指定消息的时间戳)作为锚点,向前或向后查询本地消息记录。

void nim_msglog_query_msg_async(const char *account_id //会话id,对方的account id或者群组tid
						, NIMSessionType to_type //会话类型
						, int limit_count //一次查询数量,建议20
						, __int64 anchor_msg_time //指定消息的时间戳
						, const char *json_extension
						, nim_msglog_query_cb_func cb
						, const void *user_data);

例:

C++

void OnQueryMsgCallback(nim::NIMResCode code, const std::string& query_id, nim::NIMSessionType query_type, const nim::QueryMsglogResult& result)
{
	std::vector<nim::IMMessage> vec;
	for each (auto msg in result.msglogs_)
	{
		vec.push_back(msg);
	}
}

void foo()
{
	nim::MsgLog::QueryMsgAsync("session_id", nim::kNIMSessionTypeTeam, 20, 0, &OnQueryMsgCallback);
}

C#

NIM.Messagelog.MessagelogAPI.QueryMsglogLocally("session_id", NIM.Session.NIMSessionType.kNIMSessionTypeP2P, 20, 0, (code, accountId, sType, result) =>
{
	foreach(var i in result.MsglogCollection)
	{
		···
	}
});

C

//按时间逆序查询,逆序排列
void CallbackQueryMsgCb(int res_code, const char* id, const char* type, const char* str, const char *json_exten, const void *user_data)
{
	Json::Value values;
	Json::Reader reader;
	if (reader.parse(str, values) && values.isObject())
	{
		int count = values[kNIMMsglogQueryKeyCount].asInt();
		if (count > 0)
			...
	}
}

typedef void(*nim_msglog_query_msg_async)(const char* account_id, nim::NIMSessionType to_type, int limit_count, __int64 last_time, const char *json_extension, nim_msglog_query_cb_func cb, const void* user_data);

void foo()
{
	//设置搜索方向为向前
	Json::Value json_extension_value;
	json_extension_value[kNIMMsglogQueryJsonExtensionKeyDirection] = kForward;
	Json::FastWriter fw;

	nim_msglog_query_msg_async func = (nim_msglog_query_msg_async) GetProcAddress(hInst, "nim_msglog_query_msg_async");
	func("acount_id", is_team ? kNIMSessionTypeTeam : kNIMSessionTypeP2P, 20, 0, fw.write(json_extension_value).c_str(), &CallbackQueryMsgCb, nullptr);
}
  • 删除消息记录:

C++

void foo()
{
	//删除单条消息
	nim::MsgLog::DeleteAsync("session_id", nim::kNIMSessionTypeTeam, client_msg_id_, nim::MsgLog::DeleteCallback());

	//删除与某个聊天对象的全部消息记录
	nim::MsgLog::BatchStatusDeleteAsync("session_id", nim::kNIMSessionTypeTeam, nim::MsgLog::BatchStatusDeleteCallback());

	//删除指定会话类型的所有消息
	nim::MsgLog::DeleteBySessionTypeAsync(true, nim::kNIMSessionTypeTeam, nim::MsgLog::DeleteBySessionTypeCallback());

	//删除所有消息记录
	nim::MsgLog::DeleteAllAsync(true, nim::MsgLog::DeleteAllCallback());
}

C#

void foo()
{
	//删除单条消息
	NIM.Messagelog.MessagelogAPI.DeleteSpecifiedMsglog("session_id", NIM.Session.NIMSessionType.kNIMSessionTypeP2P, msg_id, (code, msgId) =>
	{
	});

	//删除与某个聊天对象的全部消息记录
	NIM.Messagelog.MessagelogAPI.BatchDeleteMeglog("session_id", NIM.Session.NIMSessionType.kNIMSessionTypeP2P, (code, uid, sType) =>
	{
	});

	//删除指定会话类型的所有消息
	NIM.Messagelog.MessagelogAPI.DeleteMsglogsBySessionType(NIM.Session.NIMSessionType.kNIMSessionTypeP2P, true, (code, uid, sType) =>
	{
	});

	//删除所有消息记录
	NIM.Messagelog.MessagelogAPI.ClearAll(true, (code) =>
	{
	});
}

C

void CallbackModifyMsglog(int res_code, const char *msg_id, const char *json_extension, const void user_data)
{
	if (user_data)
	{
		···
	}
}

typedef void(*nim_msglog_delete_async)(const char *account_id, NIMSessionType to_type, const char *msg_id, const char *json_extension, nim_msglog_res_cb_func cb, const void *user_data);
typedef void(*nim_msglog_batch_status_delete_async)(const char* account_id, nim::NIMSessionType to_type, const char *json_extension, nim_msglog_res_ex_cb_func cb, const void* user_data);
typedef void(*nim_msglog_delete_by_session_type_async)(bool delete_sessions, NIMSessionType to_type, const char *json_extension, nim_msglog_res_ex_cb_func cb, const void *user_data);
typedef void(*nim_msglog_delete_all_async)(bool delete_sessions, const char *json_extension, nim_msglog_modify_res_cb_func cb, const void *user_data);

void foo()
{
	nim_msglog_delete_async func = (nim_msglog_delete_async) GetProcAddress(hInst, "nim_msglog_delete_async");
	nim_msglog_batch_status_delete_async func_batch_statuc = (nim_msglog_batch_status_delete_async) GetProcAddress(hInst, "nim_msglog_batch_status_delete_async");
	nim_msglog_delete_by_session_type_async func_session = (nim_msglog_delete_by_session_type_async) GetProcAddress(hInst, "nim_msglog_delete_by_session_type_async");
	nim_msglog_delete_all_async func_all = (nim_msglog_delete_all_async) GetProcAddress(hInst, "nim_msglog_delete_all_async");

	//删除单条消息
	func("acount_id", is_team ? kNIMSessionTypeTeam : kNIMSessionTypeP2P, msg_id, nullptr, &CallbackModifyMsglog, nullptr);

	//删除与某个聊天对象的全部消息记录
	func_batch_statuc("acount_id", is_team ? kNIMSessionTypeTeam : kNIMSessionTypeP2P, nullptr, &CallbackModifyMsglog, nullptr);

	//删除指定会话类型的所有消息
	func_session(true, is_team ? kNIMSessionTypeTeam : kNIMSessionTypeP2P, nullptr, &CallbackModifyMsglog, nullptr);

	//删除所有消息记录
	func_all(delete_sessions, nullptr, &CallbackModifyMsglog, nullptr);
}
  • 插入聊天记录

C++

接口:

static bool WriteMsglogToLocalAsync(const std::string& talk_id , const IMMessage& msg , bool need_update_session , const WriteMsglogCallback& cb , const std::string& json_extension = "");

示例:

void foo()
{
	std::wstring notify_text = GetRecallNotifyTextEx(talk_id, notify.session_type_, notify.from_id_, notify.operator_id_,notify.from_nick_);
	nim::IMMessage msg;
	msg.timetag_ = notify.msglog_timetag_;
	msg.client_msg_id_ = QString::GetGUID();
	msg.receiver_accid_ = talk_id;
	msg.session_type_ = notify.session_type_;
	msg.sender_accid_ = notify.from_id_;
	msg.status_ = nim::kNIMMsgLogStatusSent;
	msg.type_ = nim::kNIMMessageTypeText;
	Json::Value values;
	values["comment"] = "is_recall_notification";
	values["notify_from"] = notify.from_id_;
	values["operator_id"] = notify.operator_id_;
	values["from_nick"] = notify.from_nick_;
	msg.attach_ = values.toStyledString();
	msg.content_ = nbase::UTF16ToUTF8(notify_text);
	msg.msg_setting_.push_need_badge_ = nim::BS_FALSE; //设置会话列表不需要计入未读数
	nim::MsgLog::WriteMsglogToLocalAsync(talk_id, msg, true, nim::MsgLog::WriteMsglogCallback());
}

nim_msglog.h 文件中的接口提供了比较完善的消息记录管理功能,开发者可本地查阅、在线查阅、删除和清空聊天记录,还可以调用nim_msglog_write_db_only_async 接口只往本地消息历史数据库里写入一条消息(通常是APP 的本地自定义消息,并不会发给服务器)。详见API 文档。此外,还要注意:本地消息历史操作(如删除)及状态变化(如发送失败或成功)会与会话列表里的消息状态自动同步,App 上层需要根据nim_session_reg_change_cb 注册好的会话列表通知回调进行相应通知事件的处理。

导入导出

  • 导入消息历史记录(不包括系统通知,且不允许拿别人的消息历史记录文件来导入):
void nim_msglog_import_db_async(const char *src_path, const char *json_extension, nim_msglog_modify_res_cb_func res_cb, const void *res_user_data, nim_msglog_import_prg_cb_func prg_cb, const void *prg_user_data);

例:

C++

void OnImportProgressCallback(int64_t imported_count, int64_t total_count)
{
	···
}

void OnImportCompeleteCallback(nim::NIMResCode res_code)
{
	if (res_code == nim::kNIMResSuccess)
	{
		//导入完成
	}
	else
	{
		//导入失败
	}
}

void foo()
{
	nim::MsgLog::ImportDbAsync(path, &OnImportCompeleteCallback, &OnImportProgressCallback);
}

C#

NIM.Messagelog.MessagelogAPI.ImportDatabase(path, (code) =>
{
}
, (importedCount, totalCount) =>
{
});

C

void CallbackMsglogRes(int res, const char* msg_id, const char *json_exten, const void *user_data)
{
	...
}

void CallbackMsgImportPrg(int res_code, const char* id, const char* type, const char* str, const char *json_exten, const void *user_data)
{
	...
}

typedef void(*nim_msglog_import_db_async)(const char *src_path, const char *json_extension, nim_msglog_modify_res_cb_func res_cb, const void *res_user_data, nim_msglog_import_prg_cb_func prg_cb, const void *prg_user_data);

void foo()
{
	nim_msglog_import_db_async func = (nim_msglog_import_db_async) GetProcAddress(hInst, "nim_msglog_import_db_async");
	func("src_path", "", &CallbackMsglogRes, nullptr, &CallbackMsgImportPrg, nullptr);
}
  • 导出整个消息历史DB文件(不包括系统通知):

C++

void OnExportCompeleteCallback(nim::NIMResCode res_code)
{
	if (res_code == nim::kNIMResSuccess)
	{
		//导出完成
	}
	else
	{
		//导出失败
	}
}

void foo()
{
	nim::MsgLog::ExportDbAsync(path, &OnExportCompeleteCallback);
}

C#

NIM.Messagelog.MessagelogAPI.ExportDatabaseFile(path, (code) =>
{
});

C

void CallbackMsglogRes(int res, const char* msg_id, const char *json_exten, const void *user_data)
{
	...
}

typedef void(*nim_msglog_export_db_async)(const char *dst_path, const char *json_extension, nim_msglog_modify_res_cb_func cb, const void *user_data);

void foo()
{
	nim_msglog_export_db_async func = (nim_msglog_export_db_async) GetProcAddress(hInst, "nim_msglog_export_db_async");
	func("src_path", "", &CallbackMsglogRes, nullptr);
}

云端记录

  • 在线查询聊天对象的消息历史记录:
void nim_msglog_query_msg_online_async(const char *id //会话id,对方的account id或者群组tid
								, NIMSessionType to_type //会话类型
								, int limit_count //本次查询的消息条数上限(最多100条)
								, __int64 from_time //起始时间点,单位:毫秒
								, __int64 end_time //结束时间点,单位:毫秒
								, __int64 end_msg_id //结束查询的最后一条消息的server_msg_id(不包含在查询结果中) 
								, bool reverse //true:反向查询(按时间正序起查,正序排列),false:按时间逆序起查,逆序排列(建议默认为false)
								, bool need_save_to_local //true: 将在线查询结果保存到本地,false: 不保存
								, const char *json_extension
								, nim_msglog_query_cb_func cb
								, const void *user_data);

例:

C++

void QueryMsgOnlineCb(nim::NIMResCode code, const std::string& id, nim::NIMSessionType type, const nim::QueryMsglogResult& result)
{
	if (code == nim::kNIMResSuccess)
	{
		std::vector<nim::IMMessage> vec;
		for (auto& msg : result.msglogs_)
		{
			···
		}
	}
}

void foo()
{
	nim::MsgLog::QueryMsgOnlineAsync("session_id", nim::kNIMSessionTypeP2P, 20, 0, farst_msg_time_, last_server_id_, false, true, &QueryMsgOnlineCb);
}

C#

NIM.Messagelog.MessagelogAPI.QueryMsglogOnline("session_id", NIM.Session.NIMSessionType.kNIMSessionTypeTeam, 20, 0, 0, 0, false, false,
(ResponseCode code, string accountId, NIM.Session.NIMSessionType sType, MsglogQueryResult result) =>
{
	···
});

C

void CallbackQueryMsgCb(int res_code, const char* id, const char* type, const char* str, const char *json_exten, const void *user_data)
{
	...
}

typedef void(*nim_msglog_query_msg_online_async)(const char *id, nim::NIMSessionType to_type, int limit_count, __int64 from_time, __int64 end_time, __int64 end_msg_id, bool reverse,	bool need_save_to_local, const char *json_extension, nim_msglog_query_cb_func cb, const void *user_data);

void foo()
{
	nim_msglog_query_msg_online_async func = (nim_msglog_query_msg_online_async) GetProcAddress(hInst, "nim_msglog_query_msg_online_async");
	func("acount_id", is_team ? kNIMSessionTypeTeam : kNIMSessionTypeP2P, 20, 0, msg_time, first_msg_server_msg_id, false, false, nullptr, &CallbackQueryMsgCb, nullptr);
}

动态查询历史消息

为了获取完整的历史消息记录,您可以使用全云端方案,即用户每次进入时都通过查询云端历史记录并将查到的消息同步至本地。但是在会话多、消息多的场景下,使用全云端方案,会导致耗时长,耗能大等问题。

为解决上述问题,云信 IM 提供本地+云端智能调度方案,通过调用完整的内部逻辑保证历史消息的连续性和完整性。您仅需要选择开始或结束时间戳以及对应的消息条数即可按需获取历史消息。

开启动态查询历史消息功能

请先在云信控制台开通动态查询历史消息功能,否则该接口只会从本地数据库获取消息。

  1. 在控制台首页应用管理选择应用进入应用配置页面,然后单击 IM即时通讯 专业版下的功能配置按钮进入 IM 即时通讯配置页。

    功能配置.png

  2. 在顶部选择全局功能页签,开启动态查询历史消息功能。

    开启动态查询历史消息.png

  3. 阅读并确认信息后,单击确认开启动态查询历史消息功能。

接口说明

该接口为完整独立的历史消息查询接口,与其他历史消息查询接口互不影响。

C++

通过调用 GetMessagesDynamically 方法动态查询连续的历史消息。

参数说明:

参数 说明
session_id 会话 ID
to_type 会话类型,具体请及参见NIMSessionType
from_time 开始时间
to_time 结束时间,大于开始时间,0 表示当前时间
limit_count 查询的历史消息数量,最大 100
anchor_client_msg_id 查询起始的客户端消息 ID,查询结果不包括这条消息
anchor_server_msg_id 查询起始的服务端消息 ID,查询结果不包括这条消息
direction 查询方向,具体请参见NIMMsglogSearchDirection ,默认kForward,即从新往旧查询
cb 查询历史消息的回调函数

示例代码:

std::string session_id = "session_id";
uint64_t from_time = 0;
uint64_t to_time = 0;
uint32_t limit = 100;
std::string anchor_client_msg_id = "";
uint64_t anchor_server_msg_id = 0;.
MsgLog::GetMessagesDynamically(session_id, kNIMSessionTypeP2P, from_time, to_time, limit, anchor_client_msg_id, anchor_server_msg_id, kForward, [](const GetMessagesResult& result) {
	// process result
	// ......
});
C

用户可通过 nim_msglog_get_messages_dynamically 方法动态查询连续的历史消息。

示例代码:

static void CallbackGetMessages(int res_code,
    const char* id,
    nim::NIMSessionType to_type,
    const char* result,
    const char* json_extension,
    const void* callback) {
	// process messages
	// ......
}
nim_msglog_get_messages_dynamically("session_id", kNIMSessionTypeP2P, 0, 0, 100, "", 0, direction,json_extension.c_str(), &CallbackGetMessages, cb_pointer);

此文档是否对你有帮助?
有帮助
去反馈
  • 本地记录
  • 导入导出
  • 云端记录
  • 动态查询历史消息
  • 开启动态查询历史消息功能
  • 接口说明