Skip to main content

WebSocket 查询群聊历史记录

通过 WebSocket 命令查询指定群组在某个时间点之前的消息记录,支持分页。


命令: fetchChatHistory

方向: 客户端 → 服务端 → 客户端

请求

{
"identifier": "req-001",
"command": "fetchChatHistory",
"groupId": 123456,
"groupType": 1,
"startDate": 42,
"pageSize": 20,
"belong": null
}
字段类型必填说明
identifierstring客户端自定义标识,响应中原样返回
commandstring固定值 "fetchChatHistory"
groupIdnumber群号
groupTypenumber群类型,参见 发送群消息 中的 GroupType 表
startDatenumber消息数据库 id 游标,查询此 id 之前的消息。默认:Long.MAX_VALUE(获取最新消息)
pageSizenumber每页条数。默认:20
belongnumber外部机器人 QQ 号(外部 QQ 群)/ 私聊时服务端自动推导,无需传入

成功响应

{
"type": "FetchChatHistory",
"code": 3,
"identifier": "req-001",
"data": [
{
"groupId": 123456,
"groupType": 1,
"userId": "1001",
"type": 1,
"content": "[{\"text\":{\"text\":\"hello\"}}]",
"pinyin": "[{\"text\":{\"text\":\"hello\"}}]",
"groupName": "测试群",
"groupNamePinyin": "ce4 shi4 qun2",
"messageId": 42,
"createTime": 1780651200000,
"receiveTime": "Fri Jun 14 20:30:00 CST 2026",
"nickname": "Alice",
"nicknamePinyin": "Alice",
"avatar": "/api/avatar/get/personal?id=1001"
},
{
"groupId": 123456,
"groupType": 1,
"userId": "1002",
"type": 1,
"content": "[{\"text\":{\"text\":\"hi\"}}]",
"pinyin": "[{\"text\":{\"text\":\"hi\"}}]",
"groupName": "测试群",
"groupNamePinyin": "ce4 shi4 qun2",
"messageId": 41,
"createTime": 1780651190000,
"receiveTime": "Fri Jun 14 20:29:00 CST 2026",
"nickname": "Bob",
"nicknamePinyin": "Bob",
"avatar": null
}
]
}

dataFormatedMessageDto 数组,按 create_time DESC 排序(最新在前)。

字段类型说明
groupIdnumber群号
groupTypenumber群类型代码
userIdstring发言人用户 ID
typenumber消息类型 (MessageType)
contentstring消息 JSON 内容,格式见 接收消息推送
messageIdnumber消息 DB 主键 (id)
receiveTimestring格式化接收时间
nicknamestring发言人昵称(QQ 群为群名片,远东群为账号)
avatarstring/null发言人头像相对路径(QQ 用户: /api/avatar/get/QQpersonal?id={qq},远东用户: /api/avatar/get/personal?id={userId},无头像时为 null)。可在路径后追加 &size=aa 参数获取等比缩放到 aa 像素的图像
pinyinstring消息内容的拼音版本,JSON 格式同 content,但 text 段中的中文已转为带数字声调的拼音
groupNamestring群组名称
groupNamePinyinstring群组名称拼音(带数字声调)
nicknamePinyinstring发言人昵称拼音(带数字声调)

错误响应

{"type": "OperationFailed", "code": 500, "identifier": "req-001", "msg": "缺少参数 groupId/groupType"}

翻页示例

首次请求不带 startDate(使用默认值 Long.MAX_VALUE),获取最新一批消息。每次取最后一条的 messageId(即数据库 id)作为下次的 startDate

const ws = new WebSocket("ws://ydzx.panretro.com/external/api/v1/im/imWebSocket/via-cookie");

ws.onopen = function() {
// 查询最新 20 条
ws.send(JSON.stringify({
identifier: "fetch-1",
command: "fetchChatHistory",
groupId: 123456,
groupType: 1
}));
};

ws.onmessage = function(event) {
const resp = JSON.parse(event.data);
if (resp.type === "FetchChatHistory") {
const messages = resp.data;
const last = messages[messages.length - 1];
// 翻上一页
ws.send(JSON.stringify({
identifier: "fetch-2",
command: "fetchChatHistory",
groupId: 123456,
groupType: 1,
startDate: last.messageId // 以最后一条的 id 继续向前翻
}));
}
};