diff --git a/napcat.webui/src/pages/OtherConfig.vue b/napcat.webui/src/pages/OtherConfig.vue index 685c2dd5..730f2568 100644 --- a/napcat.webui/src/pages/OtherConfig.vue +++ b/napcat.webui/src/pages/OtherConfig.vue @@ -11,6 +11,9 @@ + + +
保存 @@ -28,6 +31,7 @@ import { QQLoginManager } from '@/backend/shell'; const otherConfig = ref>({ musicSignUrl: '', enableLocalFile2Url: false, + parseMultMsg: true }); const getOB11Config = async (): Promise => { @@ -68,6 +72,7 @@ const saveConfig = async () => { if (userConfig) { userConfig.musicSignUrl = otherConfig.value.musicSignUrl || ''; userConfig.enableLocalFile2Url = otherConfig.value.enableLocalFile2Url ?? false; + userConfig.parseMultMsg = otherConfig.value.parseMultMsg ?? true; const success = await setOB11Config(userConfig); if (success) { MessagePlugin.success('配置保存成功'); diff --git a/src/onebot/action/go-cqhttp/GetForwardMsg.ts b/src/onebot/action/go-cqhttp/GetForwardMsg.ts index 7f5338fe..4e902c04 100644 --- a/src/onebot/action/go-cqhttp/GetForwardMsg.ts +++ b/src/onebot/action/go-cqhttp/GetForwardMsg.ts @@ -41,7 +41,7 @@ export class GoCQHTTPGetForwardMsgAction extends OneBotAction { for (const msgdata of message.message) { if ((msgdata as OB11MessageData).type === OB11MessageDataType.forward) { const newNode = this.createTemplateNode(message); - newNode.data.message = await this.parseForward((msgdata as OB11MessageForward).data.content); + newNode.data.message = await this.parseForward((msgdata as OB11MessageForward).data.content ?? []); templateNode.data.message.push(newNode); } else { diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index 83f792bb..9418a203 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -19,7 +19,7 @@ import { FaceType, } from '@/core'; import faceConfig from '@/core/external/face_config.json'; -import { NapCatOneBot11Adapter, OB11Message, OB11MessageData, OB11MessageDataType, OB11MessageFileBase, } from '@/onebot'; +import { NapCatOneBot11Adapter, OB11Message, OB11MessageData, OB11MessageDataType, OB11MessageFileBase, OB11MessageForward, } from '@/onebot'; import { OB11Construct } from '@/onebot/helper/data'; import { EventType } from '@/onebot/event/OneBotEvent'; import { encodeCQCode } from '@/onebot/helper/cqcode'; @@ -37,21 +37,26 @@ type RawToOb11Converters = { element: Exclude, msg: RawMessage, elementWrapper: MessageElement, + context: RecvMessageContext ) => PromiseLike } type Ob11ToRawConverters = { [Key in OB11MessageDataType]: ( sendMsg: Extract, - context: MessageContext, + context: SendMessageContext, ) => Promise } -export type MessageContext = { +export type SendMessageContext = { deleteAfterSentFiles: string[], peer: Peer } +export type RecvMessageContext = { + parseMultMsg: boolean +} + function keyCanBeParsed(key: string, parser: RawToOb11Converters): key is keyof RawToOb11Converters { return key in parser; } @@ -338,42 +343,26 @@ export class OneBotMsgApi { }; }, - multiForwardMsgElement: async (_, msg) => { - // const message_data: OB11MessageForward = { - // data: {} as any, - // type: OB11MessageDataType.forward, - // }; - // message_data.data.id = msg.msgId; + multiForwardMsgElement: async (_, msg, wrapper, context) => { 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 this.core.apis.MsgApi.getMultiMsg(parentMsgPeer, msg.parentMsgIdList[0], msg.msgId))?.msgList; - //拉取下级消息 + const multiMsgs = await this.getMultiMessages(msg, parentMsgPeer); + // 拉取失败则跳过 if (!multiMsgs) return null; - //拉取失败则跳过 - - return { + const forward: OB11MessageForward = { 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.createUniqueMsgId(parentMsgPeer, multiMsgItem.msgId); //该ID仅用查看 无法调用 - return await this.parseMessage(multiMsgItem, 'array'); - }, - ))).filter(item => item !== undefined), - }, + data: { id: msg.msgId } }; + if (!context.parseMultMsg) return forward; + forward.data.content = await this.parseMultiMessageContent( + multiMsgs, + parentMsgPeer, + msg.parentMsgIdList + ); + return forward; }, arkElement: async (element) => { @@ -692,18 +681,48 @@ export class OneBotMsgApi { } } + private async getMultiMessages(msg: RawMessage, parentMsgPeer: Peer) { + //判断是否在合并消息内 + msg.parentMsgIdList = msg.parentMsgIdList ?? []; + //首次列表不存在则开始创建 + msg.parentMsgIdList.push(msg.msgId); + //拉取下级消息 + return (await this.core.apis.MsgApi.getMultiMsg( + parentMsgPeer, + msg.parentMsgIdList[0], + msg.msgId + ))?.msgList; + } + + private async parseMultiMessageContent( + multiMsgs: RawMessage[], + parentMsgPeer: Peer, + parentMsgIdList: string[] + ) { + const parsed = await Promise.all(multiMsgs.map(async msg => { + msg.parentMsgPeer = parentMsgPeer; + msg.parentMsgIdList = parentMsgIdList; + msg.id = MessageUnique.createUniqueMsgId(parentMsgPeer, msg.msgId); + //该ID仅用查看 无法调用 + return await this.parseMessage(msg, 'array', true); + })); + return parsed.filter(item => item !== undefined); + } + async parseMessage( msg: RawMessage, messagePostFormat: string, + parseMultMsg: boolean = true ) { if (messagePostFormat === 'string') { - return (await this.parseMessageV2(msg))?.stringMsg; + return (await this.parseMessageV2(msg, parseMultMsg))?.stringMsg; } - return (await this.parseMessageV2(msg))?.arrayMsg; + return (await this.parseMessageV2(msg, parseMultMsg))?.arrayMsg; } async parseMessageV2( msg: RawMessage, + parseMultMsg: boolean = true ) { if (msg.senderUin == '0' || msg.senderUin == '') return; if (msg.peerUin == '0' || msg.peerUin == '') return; @@ -767,11 +786,15 @@ export class OneBotMsgApi { element: Exclude, msg: RawMessage, elementWrapper: MessageElement, + context: RecvMessageContext ) => PromiseLike; const parsedElement = await converters?.( element[key], msg, element, + { + parseMultMsg: parseMultMsg + } ); // 对于 face 类型的消息,检查是否存在 if (key === 'faceElement' && !parsedElement) { @@ -819,7 +842,7 @@ export class OneBotMsgApi { } const converter = this.ob11ToRawConverters[sendMsg.type] as ( sendMsg: Extract, - context: MessageContext, + context: SendMessageContext, ) => Promise; const callResult = converter( sendMsg, @@ -878,7 +901,7 @@ export class OneBotMsgApi { private async handleOb11FileLikeMessage( { data: inputdata }: OB11MessageFileBase, - { deleteAfterSentFiles }: MessageContext, + { deleteAfterSentFiles }: SendMessageContext, ) { const realUri = inputdata.url || inputdata.file || inputdata.path || ''; if (realUri.length === 0) { diff --git a/src/onebot/config/config.ts b/src/onebot/config/config.ts index 2a70dea0..e31626fd 100644 --- a/src/onebot/config/config.ts +++ b/src/onebot/config/config.ts @@ -103,6 +103,7 @@ export interface OneBotConfig { network: NetworkConfig; // 网络配置 musicSignUrl: string; // 音乐签名地址 enableLocalFile2Url: boolean; + parseMultMsg: boolean; } const createDefaultConfig = (config: T): T => config; @@ -116,6 +117,7 @@ export const defaultOneBotConfigs = createDefaultConfig({ }, musicSignUrl: '', enableLocalFile2Url: false, + parseMultMsg: true }); export const mergeNetworkDefaultConfig = { @@ -149,9 +151,12 @@ export function mergeOneBotConfigs( if (userConfig.musicSignUrl !== undefined) { mergedConfig.musicSignUrl = userConfig.musicSignUrl; } - if(userConfig.enableLocalFile2Url !== undefined) { + if (userConfig.enableLocalFile2Url !== undefined) { mergedConfig.enableLocalFile2Url = userConfig.enableLocalFile2Url; } + if (userConfig.parseMultMsg !== undefined) { + mergedConfig.parseMultMsg = userConfig.parseMultMsg; + } return mergedConfig; } diff --git a/src/onebot/index.ts b/src/onebot/index.ts index c9938ef5..cc0cf24d 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -551,7 +551,7 @@ export class NapCatOneBot11Adapter { } private async handleMsg(message: RawMessage, network: Array) { try { - const ob11Msg = await this.apis.MsgApi.parseMessageV2(message); + const ob11Msg = await this.apis.MsgApi.parseMessageV2(message, this.configLoader.configData.parseMultMsg); if (ob11Msg) { const isSelfMsg = this.isSelfMessage(ob11Msg); this.context.logger.logDebug('转化为 OB11Message', ob11Msg); diff --git a/src/onebot/types/message.ts b/src/onebot/types/message.ts index 8dcbb03b..12a7aa9e 100644 --- a/src/onebot/types/message.ts +++ b/src/onebot/types/message.ts @@ -236,7 +236,7 @@ export interface OB11MessageForward { type: OB11MessageDataType.forward; data: { id: string; - content: OB11Message[]; + content?: OB11Message[]; }; }