Skip to main content

WebSocket 接收消息推送

服务端在群内有新消息时,向该群所有在线成员的 WebSocket 连接推送消息更新。


消息类型: MessageUpdate

方向: 服务端 → 客户端(单向推送)

触发场景:

  • 群内其他用户通过 HTTP 或 WebSocket 发送消息后,服务端调用 syncMessageToWebSocketClient() 广播
  • 不推送给发言人自己

推送格式

{
"type": "MessageUpdate",
"code": 1,
"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"
}
}

data 字段 (FormatedMessageDto)

字段类型说明
groupIdstring群号(实际为 messageId)
groupTypenumber群类型代码
userIdstring发言人用户 ID
typenumber消息类型,见 MessageType
contentstring消息 JSON 内容
messageIdstring消息创建时间戳
receiveTimestring格式化后的接收时间
nicknamestring发言人昵称(QQ 群为群名片,远东群为账号)
avatarstring/null发言人头像相对路径,详见 头像 API。无头像时为 null
pinyinstring消息内容的拼音版本,JSON 格式同 content,但 text 段中的中文已转为带数字声调的拼音
groupNamestring群组名称
groupNamePinyinstring群组名称拼音(带数字声调)
nicknamePinyinstring发言人昵称拼音(带数字声调)

MessageType 取值

Code说明
0QQ_BOT_SYNC — QQ 机器人同步的消息
1FAREAST_TO_FAREAST — 远东内部消息
2FAREAST_TO_QQ — 远东发往 QQ
3QQ_TO_FAREAST — QQ 发往远东

消息内容格式 (content)

content 为 JSON 数组,每个元素是一种消息段:

[
{"text": {"text": "hello world"}},
{"image": {"file": "abc123.jpg"}},
{"at": {"qq": "3927731416", "name": "Alice"}},
{"reply": {"id": "658617555", "messageId": "1783096941205"}}
]
类型说明
text文本消息,data.text 为文本内容
image图片消息,data.file 为文件 ID
at@提及,data.qq 为 QQ 号,data.name 为昵称
reply回复消息,data.messageId 为被回复消息的真实 ID,data.id 仅供参考不可信
file文件消息,data.relativePath 为相对路径,data.isQQ"1" 时代表 QQ 群文件。下载 URL:/downloadFile/{base64path}/{qq|local}/{safeName}

客户端接收示例

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

ws.onmessage = function(event) {
const msg = JSON.parse(event.data);

if (msg.type === "MessageUpdate") {
const d = msg.data;
console.log(`[${d.nickname}] ${d.receiveTime}`);
console.log(d.content);

// 解析消息内容
const segments = JSON.parse(d.content);
segments.forEach(seg => {
if (seg.text) {
console.log(" text:", seg.text.text);
} else if (seg.image) {
console.log(" image:", seg.image.file);
} else if (seg.at) {
console.log(" @", seg.at.name);
}
});
}
};