From 2a7f8d0c9904545ad10d96575823737732dbd1e1 Mon Sep 17 00:00:00 2001 From: Seijo Cecilia Date: Sun, 25 Aug 2024 17:54:50 +0800 Subject: [PATCH] refactor: raw message parsers --- src/common/utils/MessageUnique.ts | 2 +- .../msg/SendMsg/create-send-elements.ts | 2 +- src/onebot/api/msg.ts | 764 +++++++++--------- src/onebot/types/message.ts | 8 +- 4 files changed, 375 insertions(+), 401 deletions(-) diff --git a/src/common/utils/MessageUnique.ts b/src/common/utils/MessageUnique.ts index 71198eb5..725c51de 100644 --- a/src/common/utils/MessageUnique.ts +++ b/src/common/utils/MessageUnique.ts @@ -101,7 +101,7 @@ class MessageUniqueWrapper { return ret.map((t) => t?.MsgId).filter((t) => t !== undefined); } - createMsg(peer: Peer, msgId: string): number | undefined { + createMsg(peer: Peer, msgId: string) { const key = `${msgId}|${peer.chatType}|${peer.peerUid}`; const hash = crypto.createHash('md5').update(key).digest(); //设置第一个bit为0 保证shortId为正数 diff --git a/src/onebot/action/msg/SendMsg/create-send-elements.ts b/src/onebot/action/msg/SendMsg/create-send-elements.ts index 5a8ebae2..ab7f983a 100644 --- a/src/onebot/action/msg/SendMsg/create-send-elements.ts +++ b/src/onebot/action/msg/SendMsg/create-send-elements.ts @@ -99,7 +99,7 @@ const _handlers: { coreContext, (await handleOb11FileLikeMessage(coreContext, obContext, sendMsg, context)).path, sendMsg.data.summary || '', - sendMsg.data.subType || 0, + sendMsg.data.sub_type || 0, ); context.deleteAfterSentFiles.push(PicEle.picElement.sourcePath); return PicEle; diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index 1ffba3af..a96ee1f1 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -6,10 +6,354 @@ import { OB11Constructor } from '../helper'; import { EventType } from '@/onebot/event/OB11BaseEvent'; import { encodeCQCode } from '@/onebot/helper/cqcode'; +type RawToOb11Converters = { + [Key in keyof MessageElement as Key extends `${string}Element` ? Key : never]: ( + element: Exclude, + msg: RawMessage, + elementWrapper: MessageElement + ) => PromiseLike +} + +function keyCanBeParsed(key: string, parser: RawToOb11Converters): key is keyof RawToOb11Converters { + return key in parser; +} + export class OneBotMsgApi { obContext: NapCatOneBot11Adapter; coreContext: NapCatCore; + rawToOb11Converters: RawToOb11Converters = { + textElement: async element => { + if (element.atType === AtType.notAt) { + let text = element.content; + if (!text.trim()) { + return null; + } + // 兼容 9.7.x 换行符 + if (text.indexOf('\n') === -1 && text.indexOf('\r\n') === -1) { + text = text.replace(/\r/g, '\n'); + } + return { + type: OB11MessageDataType.text, + data: { text } + }; + } else { + let qq: string = 'all'; + if (element.atType !== AtType.atAll) { + const { atNtUid, /* content */ } = element; + let atQQ = element.atUid; + if (!atQQ || atQQ === '0') { + atQQ = await this.coreContext.apis.UserApi.getUinByUidV2(atNtUid); + } + if (atQQ) { + qq = atQQ as `${number}`; + } + } + return { + type: OB11MessageDataType.at, + data: { + qq: qq, + // name: content.slice(1); + }, + }; + } + }, + + picElement: async (element, msg) => { + try { + return { + type: OB11MessageDataType.image, + data: { + file: element.fileName, + sub_type: element.picSubType, + file_id: UUIDConverter.encode(msg.peerUin, msg.msgId), + url: await this.coreContext.apis.FileApi.getImageUrl(element), + file_size: element.fileSize, + }, + }; + } catch (e: any) { + this.coreContext.context.logger.logError('获取图片url失败', e.stack); + return null; + } + }, + + fileElement: async (element, msg, elementWrapper) => { + await this.coreContext.apis.FileApi.addFileCache( + { + peerUid: msg.peerUid, + chatType: msg.chatType, + guildId: '', + }, + msg.msgId, + msg.msgSeq, + msg.senderUid, + elementWrapper.elementId, + elementWrapper.elementType.toString(), + element.fileSize, + element.fileName, + ); + return { + type: OB11MessageDataType.file, + data: { + file: element.fileName, + path: element.filePath, + url: element.filePath, + file_id: UUIDConverter.encode(msg.peerUin, msg.msgId), + file_size: element.fileSize, + } + }; + }, + + faceElement: async element => { + const faceIndex = element.faceIndex; + if (faceIndex === FaceIndex.dice) { + return { + type: OB11MessageDataType.dice, + data: { + result: element.resultId!, + } + }; + } else if (faceIndex === FaceIndex.RPS) { + return { + type: OB11MessageDataType.RPS, + data: { + result: element.resultId!, + } + }; + } else { + return { + type: OB11MessageDataType.face, + data: { + id: element.faceIndex.toString() + } + }; + } + }, + + marketFaceElement: async (_, msg, elementWrapper) => { + await this.coreContext.apis.FileApi.addFileCache( + { + peerUid: msg.peerUid, + chatType: msg.chatType, + guildId: '', + }, + msg.msgId, + msg.msgSeq, + msg.senderUid, + elementWrapper.elementId, + elementWrapper.elementType.toString(), + '0', + 'marketface', + ); + return { + type: OB11MessageDataType.image, + data: { + file: 'marketface', + file_id: UUIDConverter.encode(msg.peerUin, msg.msgId), + path: elementWrapper.elementId, + url: elementWrapper.elementId, + } + }; + }, + + replyElement: async (element, msg) => { + const NTQQMsgApi = this.coreContext.apis.MsgApi; + const records = msg.records.find(msgRecord => msgRecord.msgId === element?.sourceMsgIdInRecords); + const peer = { + chatType: msg.chatType, + peerUid: msg.peerUid, + guildId: '', + }; + if (!records) { + this.coreContext.context.logger.logError('获取不到引用的消息', element.replayMsgSeq); + return null; + } + let replyMsg: RawMessage | undefined; + // Attempt 1 + replyMsg = (await NTQQMsgApi.getMsgsBySeqAndCount({ + peerUid: msg.peerUid, + guildId: '', + chatType: msg.chatType, + }, element.replayMsgSeq, 1, true, true)) + .msgList + .find(msg => msg.msgRandom === records.msgRandom); + + if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) { + // Attempt 2 + replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replayMsgSeq)).msgList[0]; + + if ((!replyMsg || records.msgRandom !== replyMsg.msgRandom) && msg.peerUin !== '284840486') { + // Attempt 3 + const replyMsgList = (await NTQQMsgApi.getMsgExBySeq(peer, records.msgSeq)).msgList; + if (replyMsgList.length < 1) { + this.coreContext.context.logger.logError('回复消息消息验证失败', element.replayMsgSeq); + return null; + } + replyMsg = replyMsgList.filter(e => e.msgSeq == records.msgSeq) + .sort((a, b) => parseInt(a.msgTime) - parseInt(b.msgTime))[0]; + } + } + + return { + type: OB11MessageDataType.reply, + data: { + id: MessageUnique.createMsg({ + peerUid: msg.peerUid, + guildId: '', + chatType: msg.chatType, + }, replyMsg.msgId).toString() + } + }; + }, + + videoElement: async (element, msg, elementWrapper) => { + const NTQQFileApi = this.coreContext.apis.FileApi; + + //读取视频链接并兜底 + let videoUrlWrappers: Awaited> | undefined; + + if (msg.peerUin === '284840486') { + //TODO: 合并消息内部 应该进行特殊处理 可能需要重写peer 待测试与研究 Mlikiowa Tagged + } + try { + videoUrlWrappers = await NTQQFileApi.getVideoUrl({ + chatType: msg.chatType, + peerUid: msg.peerUid, + guildId: '0', + }, msg.msgId, elementWrapper.elementId); + } catch (error) { + this.coreContext.context.logger.logWarn('获取视频 URL 失败'); + } + + //读取在线URL + let videoDownUrl: string | undefined; + + if (videoUrlWrappers) { + const videoDownUrlTemp = videoUrlWrappers.find((urlWrapper) => { + return !!(urlWrapper.url); + }); + if (videoDownUrlTemp) { + videoDownUrl = videoDownUrlTemp.url; + } + } + + //开始兜底 + if (!videoDownUrl) { + videoDownUrl = element.filePath; + } + + await NTQQFileApi.addFileCache( + { + peerUid: msg.peerUid, + chatType: msg.chatType, + guildId: '', + }, + msg.msgId, + msg.msgSeq, + msg.senderUid, + elementWrapper.elementId, + elementWrapper.elementType.toString(), + element.fileSize || '0', + element.fileName, + ); + + return { + type: OB11MessageDataType.video, + data: { + file: element.fileName, + path: videoDownUrl, + url: videoDownUrl, + file_id: UUIDConverter.encode(msg.peerUin, msg.msgId), + file_size: element.fileSize, + } + }; + }, + + pttElement: async (element, msg, elementWrapper) => { + await this.coreContext.apis.FileApi.addFileCache( + { + peerUid: msg.peerUid, + chatType: msg.chatType, + guildId: '', + }, + msg.msgId, + msg.msgSeq, + msg.senderUid, + elementWrapper.elementId, + elementWrapper.elementType.toString(), + element.fileSize || '0', + element.fileUuid || '', + ); + return { + type: OB11MessageDataType.voice, + data: { + file: element.fileName, + path: element.filePath, + file_id: UUIDConverter.encode(msg.peerUin, msg.msgId), + file_size: element.fileSize, + } + }; + }, + + multiForwardMsgElement: async (_, msg) => { + const NTQQMsgApi = this.coreContext.apis.MsgApi; + const message_data: OB11MessageData = { + data: {} as any, + type: 'unknown' as any, + }; + message_data['type'] = OB11MessageDataType.forward; + message_data['data']['id'] = msg.msgId; + const parentMsgPeer = msg.parentMsgPeer ?? { + chatType: msg.chatType, + guildId: '', + peerUid: msg.peerUid, + }; + //判断是否在合并消息内 + msg.parentMsgIdList = msg.parentMsgIdList ?? []; + //首次列表不存在则开始创建 + msg.parentMsgIdList.push(msg.msgId); + //let parentMsgId = msg.parentMsgIdList[msg.parentMsgIdList.length - 2 < 0 ? 0 : msg.parentMsgIdList.length - 2]; + //加入自身MsgId + const multiMsgs = (await NTQQMsgApi.getMultiMsg(parentMsgPeer, msg.parentMsgIdList[0], msg.msgId))?.msgList; + //拉取下级消息 + if (!multiMsgs) return null; + //拉取失败则跳过 + + return { + type: OB11MessageDataType.forward, + data: { + id: msg.msgId, + content: (await Promise.all(multiMsgs.map( + async multiMsgItem => { + multiMsgItem.parentMsgPeer = parentMsgPeer; + multiMsgItem.parentMsgIdList = msg.parentMsgIdList; + multiMsgItem.id = MessageUnique.createMsg(parentMsgPeer, multiMsgItem.msgId); //该ID仅用查看 无法调用 + return await this.parseMessage(multiMsgItem); + } + ))).filter(item => item !== undefined), + } + }; + }, + + arkElement: async (element) => { + return { + type: OB11MessageDataType.json, + data: { + data: element.bytesData + } + }; + }, + + markdownElement: async (element) => { + return { + type: OB11MessageDataType.markdown, + data: { + content: element.content + } + }; + } + }; + constructor(obContext: NapCatOneBot11Adapter, coreContext: NapCatCore) { this.obContext = obContext; this.coreContext = coreContext; @@ -17,10 +361,10 @@ export class OneBotMsgApi { async parseMessage( msg: RawMessage, - messagePostFormat: string = this.obContext.configLoader.configData.messagePostFormat + messagePostFormat: string = this.obContext.configLoader.configData.messagePostFormat, ) { - if (msg.senderUin == "0" || msg.senderUin == "") return; - if (msg.peerUin == "0" || msg.peerUin == "") return; + if (msg.senderUin == '0' || msg.senderUin == '') return; + if (msg.peerUin == '0' || msg.peerUin == '') return; //跳过空消息 const NTQQGroupApi = this.coreContext.apis.GroupApi; const NTQQUserApi = this.coreContext.apis.UserApi; @@ -65,404 +409,34 @@ export class OneBotMsgApi { resMsg.sender.nickname = ret.tmpChatInfo!.fromNick; } else { resMsg.group_id = 284840486; //兜底数据 - resMsg.sender.nickname = "临时会话"; + resMsg.sender.nickname = '临时会话'; } } - for (const element of msg.elements) { - let message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - if (element.textElement && element.textElement?.atType !== AtType.notAt) { - const textAtMsgData = await this.obContext.apiContext.MsgApi.parseTextElemntWithAt(msg, element); - if (textAtMsgData) message_data = textAtMsgData; - } else if (element.textElement) { - const textMsgData = await this.obContext.apiContext.MsgApi.parseTextElement(msg, element); - if (textMsgData) message_data = textMsgData; - } else if (element.replyElement) { - const replyMsgData = await this.obContext.apiContext.MsgApi.parseReplyElement(msg, element); - if (replyMsgData) message_data = replyMsgData; - } else if (element.picElement) { - const PicMsgData = await this.obContext.apiContext.MsgApi.parsePicElement(msg, element); - if (PicMsgData) message_data = PicMsgData; - } else if (element.fileElement) { - const FileMsgData = await this.obContext.apiContext.MsgApi.parseFileElement(msg, element); - if (FileMsgData) message_data = FileMsgData; - } else if (element.videoElement) { - const videoMsgData = await this.obContext.apiContext.MsgApi.parseVideoElement(msg, element); - if (videoMsgData) message_data = videoMsgData; - } else if (element.pttElement) { - const pttMsgData = await this.obContext.apiContext.MsgApi.parsePTTElement(msg, element); - if (pttMsgData) message_data = pttMsgData; - } else if (element.arkElement) { - const arkMsgData = await this.obContext.apiContext.MsgApi.parseArkElement(msg, element); - if (arkMsgData) message_data = arkMsgData; - } else if (element.faceElement) { - const faceMsgData = await this.obContext.apiContext.MsgApi.parseFaceElement(msg, element); - if (faceMsgData) message_data = faceMsgData; - } else if (element.marketFaceElement) { - const marketFaceMsgData = await this.obContext.apiContext.MsgApi.parseMarketFaceElement(msg, element); - if (marketFaceMsgData) message_data = marketFaceMsgData; - } else if (element.markdownElement) { - message_data['type'] = OB11MessageDataType.markdown; - message_data['data']['data'] = element.markdownElement.content; - } else if (element.multiForwardMsgElement) { - const multiForwardMsgData = await this.obContext.apiContext.MsgApi.parseMultForwardElement(msg, element, messagePostFormat); - if (multiForwardMsgData) message_data = multiForwardMsgData; - } - if ((message_data.type as string) !== 'unknown' && message_data.data) { - const cqCode = encodeCQCode(message_data); - if (messagePostFormat === 'string') { - (resMsg.message as string) += cqCode; - } else (resMsg.message as OB11MessageData[]).push(message_data); - resMsg.raw_message += cqCode; + const msgSegments = (await Promise.all(msg.elements.map( + async (element) => { + for (const key in element) { + if (keyCanBeParsed(key, this.rawToOb11Converters)) { + return await this.rawToOb11Converters[key]?.( + // eslint-disable-next-line + // @ts-ignore + element[key], + msg, + element + ); + } + } } + ))).filter(entry => !!entry); + const msgAsCQCode = msgSegments.map(msg => encodeCQCode(msg)).join('').trim(); + + if (messagePostFormat === 'string') { + resMsg.message = msgAsCQCode; + } else { + resMsg.message = msgSegments; + resMsg.raw_message = msgAsCQCode; } - resMsg.raw_message = resMsg.raw_message.trim(); return resMsg; } - - async parseFileElement(msg: RawMessage, element: MessageElement) { - const fileElement = element.fileElement; - if (!fileElement) return undefined; - const NTQQFileApi = this.coreContext.apis.FileApi; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - message_data['type'] = OB11MessageDataType.file; - message_data['data']['file'] = fileElement.fileName; - message_data['data']['path'] = fileElement.filePath; - message_data['data']['url'] = fileElement.filePath; - message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); - message_data['data']['file_size'] = fileElement.fileSize; - await NTQQFileApi.addFileCache( - { - peerUid: msg.peerUid, - chatType: msg.chatType, - guildId: '', - }, - msg.msgId, - msg.msgSeq, - msg.senderUid, - element.elementId, - element.elementType.toString(), - fileElement.fileSize, - fileElement.fileName - ); - return message_data; - } - async parseTextElemntWithAt(msg: RawMessage, element: MessageElement) { - const textElement = element.textElement; - if (!textElement) return undefined; - const NTQQUserApi = this.coreContext.apis.UserApi; - let qq: `${number}` | 'all'; - // let name: string | undefined; - if (textElement.atType == AtType.atAll) { - qq = 'all'; - } else { - const { atNtUid, content } = textElement; - let atQQ = textElement.atUid; - if (!atQQ || atQQ === '0') { - atQQ = await NTQQUserApi.getUinByUidV2(atNtUid); - } - if (atQQ) { - qq = atQQ as `${number}`; - // name = content.replace('@', ''); - } - } - - return { - type: OB11MessageDataType.at, - data: { - qq: qq!, - // name, - }, - }; - } - async parseTextElement(msg: RawMessage, element: MessageElement) { - const textElement = element.textElement; - if (!textElement) return undefined; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - message_data['type'] = OB11MessageDataType.text; - - let text = textElement.content; - if (!text.trim()) { - return false; - } - // 兼容 9.7.x 换行符 - if (text.indexOf('\n') === -1 && text.indexOf('\r\n') === -1) { - text = text.replace(/\r/g, '\n'); - } - message_data['data']['text'] = text; - return message_data; - } - async parsePicElement(msg: RawMessage, element: MessageElement) { - const picElement = element.picElement; - if (!picElement) return undefined; - const NTQQFileApi = this.coreContext.apis.FileApi; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - message_data['type'] = OB11MessageDataType.image; - // message_data["data"]["file"] = element.picElement.sourcePath - message_data['data']['file'] = picElement.fileName; - message_data['data']['subType'] = picElement.picSubType; - message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); - // message_data["data"]["path"] = element.picElement.sourcePath - try { - message_data['data']['url'] = await NTQQFileApi.getImageUrl(picElement); - } catch (e: any) { - this.coreContext.context.logger.logError('获取图片url失败', e.stack); - } - //console.log(message_data['data']['url']) - // message_data["data"]["file_id"] = element.picElement.fileUuid - message_data['data']['file_size'] = picElement.fileSize; - return message_data; - } - async parseMarketFaceElement(msg: RawMessage, element: MessageElement) { - const NTQQFileApi = this.coreContext.apis.FileApi; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - message_data['type'] = OB11MessageDataType.image; - message_data['data']['file'] = 'marketface'; - message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); - message_data['data']['path'] = element.elementId; - message_data['data']['url'] = element.elementId; - await NTQQFileApi.addFileCache( - { - peerUid: msg.peerUid, - chatType: msg.chatType, - guildId: '', - }, - msg.msgId, - msg.msgSeq, - msg.senderUid, - element.elementId, - element.elementType.toString(), - '0', - 'marketface' - ); - return message_data; - } - async parseReplyElement(msg: RawMessage, element: MessageElement) { - const replyElement = element.replyElement; - if (!replyElement) return undefined; - const NTQQMsgApi = this.coreContext.apis.MsgApi; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - message_data['type'] = OB11MessageDataType.reply; - //log("收到回复消息", element.replyElement); - try { - const records = msg.records.find(msgRecord => msgRecord.msgId === replyElement?.sourceMsgIdInRecords); - const peer = { - chatType: msg.chatType, - peerUid: msg.peerUid, - guildId: '', - }; - let replyMsg: RawMessage | undefined; - if (!records) throw new Error('找不到回复消息'); - replyMsg = (await NTQQMsgApi.getMsgsBySeqAndCount({ - peerUid: msg.peerUid, - guildId: '', - chatType: msg.chatType, - }, replyElement.replayMsgSeq, 1, true, true)).msgList.find(msg => msg.msgRandom === records.msgRandom); - if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) { - replyMsg = (await NTQQMsgApi.getSingleMsg(peer, replyElement.replayMsgSeq)).msgList[0]; - } - if (msg.peerUin == '284840486') { - //合并消息内侧 消息具体定位不到 - } - if ((!replyMsg || records.msgRandom !== replyMsg.msgRandom) && msg.peerUin !== '284840486') { - const replyMsgList = (await NTQQMsgApi.getMsgExBySeq(peer, records.msgSeq)).msgList; - if (replyMsgList.length < 1) { - throw new Error('回复消息消息验证失败'); - } - replyMsg = replyMsgList.filter(e => e.msgSeq == records.msgSeq).sort((a, b) => parseInt(a.msgTime) - parseInt(b.msgTime))[0]; - } - message_data['data']['id'] = MessageUnique.createMsg({ - peerUid: msg.peerUid, - guildId: '', - chatType: msg.chatType, - }, replyMsg.msgId)?.toString(); - //log("找到回复消息", message_data['data']['id'], replyMsg.msgList[0].msgId) - } catch (e: any) { - message_data['type'] = 'unknown' as any; - message_data['data'] = undefined; - this.coreContext.context.logger.logError('获取不到引用的消息', e.stack, replyElement.replayMsgSeq); - return undefined; - } - return message_data; - } - async parseVideoElement(msg: RawMessage, element: MessageElement) { - const videoElement = element.videoElement; - if (!videoElement) return undefined; - const NTQQFileApi = this.coreContext.apis.FileApi; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - //读取视频链接并兜底 - let videoUrl; //Array - if (msg.peerUin === '284840486') { - //合并消息内部 应该进行特殊处理 可能需要重写peer 待测试与研究 Mlikiowa Taged TODO - } - try { - - videoUrl = await NTQQFileApi.getVideoUrl({ - chatType: msg.chatType, - peerUid: msg.peerUid, - guildId: '0', - }, msg.msgId, element.elementId); - } catch (error) { - videoUrl = undefined; - } - //读取在线URL - let videoDownUrl = undefined; - - if (videoUrl) { - const videoDownUrlTemp = videoUrl.find((url) => { - return !!url.url; - }); - if (videoDownUrlTemp) { - videoDownUrl = videoDownUrlTemp.url; - } - } - //开始兜底 - if (!videoDownUrl) { - videoDownUrl = videoElement.filePath; - } - message_data['type'] = OB11MessageDataType.video; - message_data['data']['file'] = videoElement.fileName; - message_data['data']['path'] = videoDownUrl; - message_data['data']['url'] = videoDownUrl; - message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); - message_data['data']['file_size'] = videoElement.fileSize; - - await NTQQFileApi.addFileCache( - { - peerUid: msg.peerUid, - chatType: msg.chatType, - guildId: '', - }, - msg.msgId, - msg.msgSeq, - msg.senderUid, - element.elementId, - element.elementType.toString(), - videoElement.fileSize || '0', - videoElement.fileName - ); - return message_data; - } - async parsePTTElement(msg: RawMessage, element: MessageElement) { - const pttElement = element.pttElement; - if (!pttElement) return undefined; - const NTQQFileApi = this.coreContext.apis.FileApi; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - - message_data['type'] = OB11MessageDataType.voice; - message_data['data']['file'] = pttElement.fileName; - message_data['data']['path'] = pttElement.filePath; - //message_data['data']['file_id'] = element.pttElement.fileUuid; - message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); - message_data['data']['file_size'] = pttElement.fileSize; - await NTQQFileApi.addFileCache({ - peerUid: msg.peerUid, - chatType: msg.chatType, - guildId: '', - }, - msg.msgId, - msg.msgSeq, - msg.senderUid, - element.elementId, - element.elementType.toString(), - pttElement.fileSize || '0', - pttElement.fileUuid || '' - ); - //以uuid作为文件名 - return message_data; - } - async parseFaceElement(msg: RawMessage, element: MessageElement) { - const faceElement = element.faceElement; - if (!faceElement) return undefined; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - const faceId = faceElement.faceIndex; - if (faceId === FaceIndex.dice) { - message_data['type'] = OB11MessageDataType.dice; - message_data['data']['result'] = faceElement.resultId; - } else if (faceId === FaceIndex.RPS) { - message_data['type'] = OB11MessageDataType.RPS; - message_data['data']['result'] = faceElement.resultId; - } else { - message_data['type'] = OB11MessageDataType.face; - message_data['data']['id'] = faceElement.faceIndex.toString(); - } - return message_data; - } - async parseMultForwardElement(msg: RawMessage, element: MessageElement, messagePostFormat: any) { - const NTQQMsgApi = this.coreContext.apis.MsgApi; - const faceElement = element.multiForwardMsgElement; - if (!faceElement) return undefined; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - message_data['type'] = OB11MessageDataType.forward; - message_data['data']['id'] = msg.msgId; - const ParentMsgPeer = msg.parentMsgPeer ?? { - chatType: msg.chatType, - guildId: '', - peerUid: msg.peerUid, - }; - //判断是否在合并消息内 - msg.parentMsgIdList = msg.parentMsgIdList ?? []; - //首次列表不存在则开始创建 - msg.parentMsgIdList.push(msg.msgId); - //let parentMsgId = msg.parentMsgIdList[msg.parentMsgIdList.length - 2 < 0 ? 0 : msg.parentMsgIdList.length - 2]; - //加入自身MsgId - const MultiMsgs = (await NTQQMsgApi.getMultiMsg(ParentMsgPeer, msg.parentMsgIdList[0], msg.msgId))?.msgList; - //拉取下级消息 - if (!MultiMsgs) return undefined; - //拉取失败则跳过 - message_data['data']['content'] = []; - for (const MultiMsg of MultiMsgs) { - //对每条拉取的消息传递ParentMsgPeer修正Peer - MultiMsg.parentMsgPeer = ParentMsgPeer; - MultiMsg.parentMsgIdList = msg.parentMsgIdList; - MultiMsg.id = MessageUnique.createMsg(ParentMsgPeer, MultiMsg.msgId); //该ID仅用查看 无法调用 - const msgList = await this.parseMessage(MultiMsg, messagePostFormat); - if (!msgList) continue; - message_data['data']['content'].push(msgList); - //console.log("合并消息", msgList); - } - return message_data; - } - async parseArkElement(msg: RawMessage, element: MessageElement) { - const arkElement = element.arkElement; - if (!arkElement) return undefined; - const message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any, - }; - message_data['type'] = OB11MessageDataType.json; - message_data['data']['data'] = arkElement.bytesData; - return message_data; - } } diff --git a/src/onebot/types/message.ts b/src/onebot/types/message.ts index e9a06612..d91c111b 100644 --- a/src/onebot/types/message.ts +++ b/src/onebot/types/message.ts @@ -94,7 +94,7 @@ export interface OB11MessageImage extends OB11MessageFileBase { type: OB11MessageDataType.image data: OB11MessageFileBase['data'] & { summary?: string; // 图片摘要 - subType?: PicSubType + sub_type?: PicSubType }, } @@ -113,7 +113,7 @@ export interface OB11MessageVideo extends OB11MessageFileBase { export interface OB11MessageAt { type: OB11MessageDataType.at; data: { - qq: `${number}` | 'all' + qq: string, // `${number}` | 'all' name?: string }; } @@ -162,14 +162,14 @@ export interface OB11MessageJson { export interface OB11MessageDice { type: OB11MessageDataType.dice, data: { - result: number + result: number /* intended */ | string /* in fact */ } } export interface OB11MessageRPS { type: OB11MessageDataType.RPS, data: { - result: number + result: number | string } }