From 62ea4b98e1a11e0d865a05de1d97af972e7b26ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 25 Nov 2024 20:39:44 +0800 Subject: [PATCH 01/12] refactor: parseGroupEvent --- src/onebot/api/group.ts | 310 ++++++++++++++++++++---------------- src/onebot/index.ts | 15 +- src/onebot/network/index.ts | 6 +- 3 files changed, 189 insertions(+), 142 deletions(-) diff --git a/src/onebot/api/group.ts b/src/onebot/api/group.ts index bd3300d4..edb1bd8f 100644 --- a/src/onebot/api/group.ts +++ b/src/onebot/api/group.ts @@ -1,10 +1,12 @@ import { ChatType, GrayTipElement, + InstanceContext, JsonGrayBusiId, NapCatCore, NTGrayTipElementSubTypeV2, RawMessage, + TipGroupElement, TipGroupElementType, } from '@/core'; import { NapCatOneBot11Adapter } from '@/onebot'; @@ -15,13 +17,10 @@ import fastXmlParser from 'fast-xml-parser'; import { OB11GroupMsgEmojiLikeEvent } from '@/onebot/event/notice/OB11MsgEmojiLikeEvent'; import { MessageUnique } from '@/common/message-unique'; import { OB11GroupCardEvent } from '@/onebot/event/notice/OB11GroupCardEvent'; -import { OB11GroupUploadNoticeEvent } from '@/onebot/event/notice/OB11GroupUploadNoticeEvent'; import { OB11GroupPokeEvent } from '@/onebot/event/notice/OB11PokeEvent'; import { OB11GroupEssenceEvent } from '@/onebot/event/notice/OB11GroupEssenceEvent'; import { OB11GroupTitleEvent } from '@/onebot/event/notice/OB11GroupTitleEvent'; -import { FileNapCatOneBotUUID } from '@/common/helper'; -import { pathToFileURL } from 'node:url'; - +import { OB11EmitEventContent } from '../network'; export class OneBotGroupApi { obContext: NapCatOneBot11Adapter; @@ -32,137 +31,6 @@ export class OneBotGroupApi { this.core = core; } - async parseGroupEvent(msg: RawMessage) { - const logger = this.core.context.logger; - if (msg.chatType !== ChatType.KCHATTYPEGROUP) { - return; - } - //log("group msg", msg); - if (msg.senderUin && msg.senderUin !== '0') { - const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUid, msg.senderUin); - if (member && member.cardName !== msg.sendMemberName) { - const newCardName = msg.sendMemberName ?? ''; - const event = new OB11GroupCardEvent(this.core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName); - member.cardName = newCardName; - return event; - } - } - - for (const element of msg.elements) { - if (element.grayTipElement?.groupElement) { - const groupElement = element.grayTipElement.groupElement; - if (groupElement.type == TipGroupElementType.KMEMBERADD) { - const MemberIncreaseEvent = await this.obContext.apis.GroupApi.parseGroupMemberIncreaseEvent(msg.peerUid, element.grayTipElement); - if (MemberIncreaseEvent) return MemberIncreaseEvent; - } else if (groupElement.type === TipGroupElementType.KSHUTUP) { - const BanEvent = await this.obContext.apis.GroupApi.parseGroupBanEvent(msg.peerUid, element.grayTipElement); - if (BanEvent) return BanEvent; - } else if (groupElement.type == TipGroupElementType.KQUITTE) { - this.core.apis.GroupApi.quitGroup(msg.peerUid).then(); - try { - const KickEvent = await this.obContext.apis.GroupApi.parseGroupKickEvent(msg.peerUid, element.grayTipElement); - if (KickEvent) return KickEvent; - } catch (e) { - return new OB11GroupDecreaseEvent( - this.core, - parseInt(msg.peerUid), - parseInt(this.core.selfInfo.uin), - 0, - 'leave', - ); - } - } - } else if (element.fileElement) { - return new OB11GroupUploadNoticeEvent( - this.core, - parseInt(msg.peerUid), parseInt(msg.senderUin || ''), - { - id: FileNapCatOneBotUUID.encode({ - chatType: ChatType.KCHATTYPEGROUP, - peerUid: msg.peerUid, - }, msg.msgId, element.elementId, element.fileElement.fileUuid, "." + element.fileElement.fileName), - url: pathToFileURL(element.fileElement.filePath).href, - name: element.fileElement.fileName, - size: parseInt(element.fileElement.fileSize), - busid: element.fileElement.fileBizId ?? 0, - }, - ); - } - if (element.grayTipElement) { - if (element.grayTipElement.xmlElement?.templId === '10382') { - const emojiLikeEvent = await this.obContext.apis.GroupApi.parseGroupEmojiLikeEventByGrayTip(msg.peerUid, element.grayTipElement); - if (emojiLikeEvent) return emojiLikeEvent; - } - if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) { - const GroupIncreaseEvent = await this.obContext.apis.GroupApi.parseGroupIncreaseEvent(msg.peerUid, element.grayTipElement); - if (GroupIncreaseEvent) return GroupIncreaseEvent; - } - - else if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) { - const json = JSON.parse(element.grayTipElement.jsonGrayTipElement.jsonStr); - if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) { - //判断业务类型 - //Poke事件 - const pokedetail: any[] = json.items; - //筛选item带有uid的元素 - const poke_uid = pokedetail.filter(item => item.uid); - if (poke_uid.length == 2) { - return new OB11GroupPokeEvent( - this.core, - parseInt(msg.peerUid), - +await this.core.apis.UserApi.getUinByUidV2(poke_uid[0].uid), - +await this.core.apis.UserApi.getUinByUidV2(poke_uid[1].uid), - pokedetail, - ); - } - } - if (element.grayTipElement.jsonGrayTipElement.busiId == JsonGrayBusiId.AIO_GROUP_ESSENCE_MSG_TIP) { - const searchParams = new URL(json.items[0].jp).searchParams; - const msgSeq = searchParams.get('msgSeq')!; - const Group = searchParams.get('groupCode'); - if (!Group) return; - // const businessId = searchParams.get('businessid'); - const Peer = { - guildId: '', - chatType: ChatType.KCHATTYPEGROUP, - peerUid: Group, - }; - const msgData = await this.core.apis.MsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true); - const msgList = (await this.core.apis.WebApi.getGroupEssenceMsgAll(Group)).flatMap((e) => e.data.msg_list); - const realMsg = msgList.find((e) => e.msg_seq.toString() == msgSeq); - return new OB11GroupEssenceEvent( - this.core, - parseInt(msg.peerUid), - MessageUnique.getShortIdByMsgId(msgData.msgList[0].msgId)!, - parseInt(msgData.msgList[0].senderUin), - parseInt(realMsg?.add_digest_uin ?? '0'), - ); - // 获取MsgSeq+Peer可获取具体消息 - } - if (element.grayTipElement.jsonGrayTipElement.busiId == JsonGrayBusiId.GROUP_AIO_CONFIGURABLE_GRAY_TIPS) { - const type = json.items[json.items.length - 1]?.txt; - if (type === "头衔") { - const memberUin = json.items[1].param[0]; - const title = json.items[3].txt; - logger.logDebug('收到群成员新头衔消息', json); - return new OB11GroupTitleEvent( - this.core, - parseInt(msg.peerUid), - parseInt(memberUin), - title, - ); - } else if (type === "移出") { - logger.logDebug('收到机器人被踢消息', json); - return; - } else { - logger.logWarn('收到未知的灰条消息', json); - } - } - } - } - } - } - async parseGroupBanEvent(GroupCode: string, grayTipElement: GrayTipElement) { const groupElement = grayTipElement?.groupElement; if (!groupElement?.shutUp) return undefined; @@ -300,4 +168,176 @@ export class OneBotGroupApi { }], ); } + async parseCardChangedEvent(msg: RawMessage) { + if (msg.senderUin && msg.senderUin !== '0') { + const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUid, msg.senderUin); + if (member && member.cardName !== msg.sendMemberName) { + const newCardName = msg.sendMemberName ?? ''; + const event = new OB11GroupCardEvent(this.core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName); + member.cardName = newCardName; + return event; + } + } + return undefined; + } + + async parseGroupElement(msg: RawMessage, groupElement: TipGroupElement, elementWrapper: GrayTipElement) { + if (groupElement.type == TipGroupElementType.KMEMBERADD) { + const MemberIncreaseEvent = await this.obContext.apis.GroupApi.parseGroupMemberIncreaseEvent(msg.peerUid, elementWrapper); + if (MemberIncreaseEvent) return MemberIncreaseEvent; + } else if (groupElement.type === TipGroupElementType.KSHUTUP) { + const BanEvent = await this.obContext.apis.GroupApi.parseGroupBanEvent(msg.peerUid, elementWrapper); + if (BanEvent) return BanEvent; + } else if (groupElement.type == TipGroupElementType.KQUITTE) { + this.core.apis.GroupApi.quitGroup(msg.peerUid).then(); + try { + const KickEvent = await this.obContext.apis.GroupApi.parseGroupKickEvent(msg.peerUid, elementWrapper); + if (KickEvent) return KickEvent; + } catch (e) { + return new OB11GroupDecreaseEvent( + this.core, + parseInt(msg.peerUid), + parseInt(this.core.selfInfo.uin), + 0, + 'leave', + ); + } + } + return undefined; + } + + async parsePaiYiPai(msg: RawMessage, jsonStr: string) { + const json = JSON.parse(jsonStr); + + //判断业务类型 + //Poke事件 + const pokedetail: any[] = json.items; + //筛选item带有uid的元素 + const poke_uid = pokedetail.filter(item => item.uid); + if (poke_uid.length == 2) { + return new OB11GroupPokeEvent( + this.core, + parseInt(msg.peerUid), + +await this.core.apis.UserApi.getUinByUidV2(poke_uid[0].uid), + +await this.core.apis.UserApi.getUinByUidV2(poke_uid[1].uid), + pokedetail, + ); + } + return undefined; + } + + async parseOtherJsonEvent(msg: RawMessage, jsonStr: string, context: InstanceContext) { + const json = JSON.parse(jsonStr); + const type = json.items[json.items.length - 1]?.txt; + if (type === "头衔") { + const memberUin = json.items[1].param[0]; + const title = json.items[3].txt; + context.logger.logDebug('收到群成员新头衔消息', json); + return new OB11GroupTitleEvent( + this.core, + parseInt(msg.peerUid), + parseInt(memberUin), + title, + ); + } else if (type === "移出") { + context.logger.logDebug('收到机器人被踢消息', json); + return; + } else { + context.logger.logWarn('收到未知的灰条消息', json); + } + } + + async parseEssenceMsg(msg: RawMessage, jsonStr: string) { + const json = JSON.parse(jsonStr); + const searchParams = new URL(json.items[0].jp).searchParams; + const msgSeq = searchParams.get('msgSeq')!; + const Group = searchParams.get('groupCode'); + if (!Group) return; + // const businessId = searchParams.get('businessid'); + const Peer = { + guildId: '', + chatType: ChatType.KCHATTYPEGROUP, + peerUid: Group, + }; + const msgData = await this.core.apis.MsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true); + const msgList = (await this.core.apis.WebApi.getGroupEssenceMsgAll(Group)).flatMap((e) => e.data.msg_list); + const realMsg = msgList.find((e) => e.msg_seq.toString() == msgSeq); + return new OB11GroupEssenceEvent( + this.core, + parseInt(msg.peerUid), + MessageUnique.getShortIdByMsgId(msgData.msgList[0].msgId)!, + parseInt(msgData.msgList[0].senderUin), + parseInt(realMsg?.add_digest_uin ?? '0'), + ); + // 获取MsgSeq+Peer可获取具体消息 + } + + // async parseGroupUploadFileEvene() { + // return new OB11GroupUploadNoticeEvent( + // this.core, + // parseInt(msg.peerUid), parseInt(msg.senderUin || ''), + // { + // id: FileNapCatOneBotUUID.encode({ + // chatType: ChatType.KCHATTYPEGROUP, + // peerUid: msg.peerUid, + // }, msg.msgId, element.elementId, element.fileElement.fileUuid, "." + element.fileElement.fileName), + // url: pathToFileURL(element.fileElement.filePath).href, + // name: element.fileElement.fileName, + // size: parseInt(element.fileElement.fileSize), + // busid: element.fileElement.fileBizId ?? 0, + // }, + // ); + // } + + async parseGrayTipElement(msg: RawMessage, grayTipElement: GrayTipElement) { + let events: Array = []; + + // 群名片修改事件解析 + + const cardChangedEvent = await this.parseCardChangedEvent(msg); + if (cardChangedEvent) { + events.push(cardChangedEvent); + } + + // 解析群组事件 + if (grayTipElement.groupElement) { + const groupEvent = await this.parseGroupElement(msg, grayTipElement.groupElement, grayTipElement); + if (groupEvent) { + events.push(groupEvent); + } + } + + if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) { + // 筛选出表情回应 事件 + if (grayTipElement.xmlElement?.templId === '10382') { + const emojiLikeEvent = await this.obContext.apis.GroupApi.parseGroupEmojiLikeEventByGrayTip(msg.peerUid, grayTipElement); + if (emojiLikeEvent) { + events.push(emojiLikeEvent); + } + } else { + const GroupIncreaseEvent = await this.obContext.apis.GroupApi.parseGroupIncreaseEvent(msg.peerUid, grayTipElement); + if (GroupIncreaseEvent) { + events.push(GroupIncreaseEvent); + } + } + } else if (grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) { + if (grayTipElement.jsonGrayTipElement.busiId == 1061) { + const paiYiPaiEvent = await this.parsePaiYiPai(msg, grayTipElement.jsonGrayTipElement.jsonStr); + if (paiYiPaiEvent) { + events.push(paiYiPaiEvent); + } + } else if (grayTipElement.jsonGrayTipElement.busiId == JsonGrayBusiId.AIO_GROUP_ESSENCE_MSG_TIP) { + const essenceMsgEvent = await this.parseEssenceMsg(msg, grayTipElement.jsonGrayTipElement.jsonStr); + if (essenceMsgEvent) { + events.push(essenceMsgEvent); + } + } else { + const otherJsonEvent = await this.parseOtherJsonEvent(msg, grayTipElement.jsonGrayTipElement.jsonStr, this.core.context) + if (otherJsonEvent) { + events.push(otherJsonEvent); + } + } + } + return events; + } } diff --git a/src/onebot/index.ts b/src/onebot/index.ts index 0eb5bdfc..56a853af 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -527,8 +527,11 @@ export class NapCatOneBot11Adapter { const network = Object.values(this.configLoader.configData.network).flat() as Array; this.context.logger.logDebug('收到新消息 RawMessage', message); await this.handleMsg(message, network); - await this.handleGroupEvent(message); - await this.handlePrivateMsgEvent(message); + if (message.chatType == ChatType.KCHATTYPEGROUP) { + await this.handleGroupEvent(message); + } else { + await this.handlePrivateMsgEvent(message); + } } private async handleMsg(message: RawMessage, network: Array) { try { @@ -597,10 +600,10 @@ export class NapCatOneBot11Adapter { private async handleGroupEvent(message: RawMessage) { try { - const groupEvent = await this.apis.GroupApi.parseGroupEvent(message); - if (groupEvent) { - this.networkManager.emitEvent(groupEvent); - } + const grayTipElement = message.elements.find((element) => element.grayTipElement)?.grayTipElement; + if (!grayTipElement) return; + const events = await this.apis.GroupApi.parseGrayTipElement(message, grayTipElement); + await this.networkManager.emitEvents(events); } catch (e) { this.context.logger.logError('constructGroupEvent error: ', e); } diff --git a/src/onebot/network/index.ts b/src/onebot/network/index.ts index 5663f241..cbe1140b 100644 --- a/src/onebot/network/index.ts +++ b/src/onebot/network/index.ts @@ -37,6 +37,10 @@ export class OB11NetworkManager { return Promise.all(Array.from(this.adapters.values()).map(adapter => adapter.onEvent(event))); } + async emitEvents(events: OB11EmitEventContent[]) { + return Promise.all(events.map(event => this.emitEvent(event))); + } + async emitEventByName(names: string[], event: OB11EmitEventContent) { return Promise.all(names.map(name => { const adapter = this.adapters.get(name); @@ -71,7 +75,7 @@ export class OB11NetworkManager { async closeSomeAdaterWhenOpen(adaptersToClose: IOB11NetworkAdapter[]) { for (const adapter of adaptersToClose) { this.adapters.delete(adapter.name); - if(adapter.isEnable){ + if (adapter.isEnable) { await adapter.close(); } } From 035aa32305067d96daf4a43dfc5f6551a6504df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 25 Nov 2024 21:04:33 +0800 Subject: [PATCH 02/12] fix: parseGroupUploadFileEvene --- src/onebot/api/group.ts | 74 ++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/src/onebot/api/group.ts b/src/onebot/api/group.ts index edb1bd8f..749bc8c8 100644 --- a/src/onebot/api/group.ts +++ b/src/onebot/api/group.ts @@ -1,10 +1,13 @@ import { ChatType, + FileElement, GrayTipElement, InstanceContext, JsonGrayBusiId, + MessageElement, NapCatCore, NTGrayTipElementSubTypeV2, + NTMsgType, RawMessage, TipGroupElement, TipGroupElementType, @@ -21,6 +24,9 @@ import { OB11GroupPokeEvent } from '@/onebot/event/notice/OB11PokeEvent'; import { OB11GroupEssenceEvent } from '@/onebot/event/notice/OB11GroupEssenceEvent'; import { OB11GroupTitleEvent } from '@/onebot/event/notice/OB11GroupTitleEvent'; import { OB11EmitEventContent } from '../network'; +import { OB11GroupUploadNoticeEvent } from '../event/notice/OB11GroupUploadNoticeEvent'; +import { pathToFileURL } from 'node:url'; +import { FileNapCatOneBotUUID } from '@/common/helper'; export class OneBotGroupApi { obContext: NapCatOneBot11Adapter; @@ -246,7 +252,7 @@ export class OneBotGroupApi { context.logger.logWarn('收到未知的灰条消息', json); } } - + async parseEssenceMsg(msg: RawMessage, jsonStr: string) { const json = JSON.parse(jsonStr); const searchParams = new URL(json.items[0].jp).searchParams; @@ -272,42 +278,55 @@ export class OneBotGroupApi { // 获取MsgSeq+Peer可获取具体消息 } - // async parseGroupUploadFileEvene() { - // return new OB11GroupUploadNoticeEvent( - // this.core, - // parseInt(msg.peerUid), parseInt(msg.senderUin || ''), - // { - // id: FileNapCatOneBotUUID.encode({ - // chatType: ChatType.KCHATTYPEGROUP, - // peerUid: msg.peerUid, - // }, msg.msgId, element.elementId, element.fileElement.fileUuid, "." + element.fileElement.fileName), - // url: pathToFileURL(element.fileElement.filePath).href, - // name: element.fileElement.fileName, - // size: parseInt(element.fileElement.fileSize), - // busid: element.fileElement.fileBizId ?? 0, - // }, - // ); - // } + async parseGroupUploadFileEvene(msg: RawMessage, element: FileElement, elementWrapper: MessageElement) { + return new OB11GroupUploadNoticeEvent( + this.core, + parseInt(msg.peerUid), parseInt(msg.senderUin || ''), + { + id: FileNapCatOneBotUUID.encode({ + chatType: ChatType.KCHATTYPEGROUP, + peerUid: msg.peerUid, + }, msg.msgId, elementWrapper.elementId, elementWrapper?.fileElement?.fileUuid, "." + element.fileName), + url: pathToFileURL(element.filePath).href, + name: element.fileName, + size: parseInt(element.fileSize), + busid: element.fileBizId ?? 0, + }, + ); + } async parseGrayTipElement(msg: RawMessage, grayTipElement: GrayTipElement) { let events: Array = []; - // 群名片修改事件解析 - - const cardChangedEvent = await this.parseCardChangedEvent(msg); - if (cardChangedEvent) { - events.push(cardChangedEvent); + // 群名片修改事件解析 任何都该判断 + if (msg.senderUin && msg.senderUin !== '0') { + const cardChangedEvent = await this.parseCardChangedEvent(msg); + if (cardChangedEvent) { + events.push(cardChangedEvent); + } } - // 解析群组事件 - if (grayTipElement.groupElement) { + + if (msg.msgType === NTMsgType.KMSGTYPEFILE) { + //文件上传事件 文件为单一元素 + const elementWrapper = msg.elements.find(e => !!e.fileElement); + if (elementWrapper && elementWrapper.fileElement) { + const uploadGroupFileEvent = await this.parseGroupUploadFileEvene(msg, elementWrapper.fileElement, elementWrapper); + if (uploadGroupFileEvent) { + events.push(uploadGroupFileEvent); + return events;//带有file 说明必然不可能是灰条消息 + } + } + } + + + if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_GROUP) { + // 解析群组事件 const groupEvent = await this.parseGroupElement(msg, grayTipElement.groupElement, grayTipElement); if (groupEvent) { events.push(groupEvent); } - } - - if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) { + } else if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) { // 筛选出表情回应 事件 if (grayTipElement.xmlElement?.templId === '10382') { const emojiLikeEvent = await this.obContext.apis.GroupApi.parseGroupEmojiLikeEventByGrayTip(msg.peerUid, grayTipElement); @@ -321,6 +340,7 @@ export class OneBotGroupApi { } } } else if (grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) { + // 解析json事件 if (grayTipElement.jsonGrayTipElement.busiId == 1061) { const paiYiPaiEvent = await this.parsePaiYiPai(msg, grayTipElement.jsonGrayTipElement.jsonStr); if (paiYiPaiEvent) { From 00f726b515011d3ca83976afde1a36f60a0e7558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 25 Nov 2024 21:20:32 +0800 Subject: [PATCH 03/12] fix: event parse --- src/onebot/api/group.ts | 59 +++++++---------------------------------- src/onebot/index.ts | 21 ++++++++++++--- 2 files changed, 28 insertions(+), 52 deletions(-) diff --git a/src/onebot/api/group.ts b/src/onebot/api/group.ts index 749bc8c8..5a189a78 100644 --- a/src/onebot/api/group.ts +++ b/src/onebot/api/group.ts @@ -174,6 +174,7 @@ export class OneBotGroupApi { }], ); } + async parseCardChangedEvent(msg: RawMessage) { if (msg.senderUin && msg.senderUin !== '0') { const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUid, msg.senderUin); @@ -296,68 +297,28 @@ export class OneBotGroupApi { } async parseGrayTipElement(msg: RawMessage, grayTipElement: GrayTipElement) { - let events: Array = []; - - // 群名片修改事件解析 任何都该判断 - if (msg.senderUin && msg.senderUin !== '0') { - const cardChangedEvent = await this.parseCardChangedEvent(msg); - if (cardChangedEvent) { - events.push(cardChangedEvent); - } - } - - - if (msg.msgType === NTMsgType.KMSGTYPEFILE) { - //文件上传事件 文件为单一元素 - const elementWrapper = msg.elements.find(e => !!e.fileElement); - if (elementWrapper && elementWrapper.fileElement) { - const uploadGroupFileEvent = await this.parseGroupUploadFileEvene(msg, elementWrapper.fileElement, elementWrapper); - if (uploadGroupFileEvent) { - events.push(uploadGroupFileEvent); - return events;//带有file 说明必然不可能是灰条消息 - } - } - } - - if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_GROUP) { // 解析群组事件 - const groupEvent = await this.parseGroupElement(msg, grayTipElement.groupElement, grayTipElement); - if (groupEvent) { - events.push(groupEvent); - } + return await this.parseGroupElement(msg, grayTipElement.groupElement, grayTipElement); + } else if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) { // 筛选出表情回应 事件 if (grayTipElement.xmlElement?.templId === '10382') { - const emojiLikeEvent = await this.obContext.apis.GroupApi.parseGroupEmojiLikeEventByGrayTip(msg.peerUid, grayTipElement); - if (emojiLikeEvent) { - events.push(emojiLikeEvent); - } + return await this.obContext.apis.GroupApi.parseGroupEmojiLikeEventByGrayTip(msg.peerUid, grayTipElement); + } else { - const GroupIncreaseEvent = await this.obContext.apis.GroupApi.parseGroupIncreaseEvent(msg.peerUid, grayTipElement); - if (GroupIncreaseEvent) { - events.push(GroupIncreaseEvent); - } + return await this.obContext.apis.GroupApi.parseGroupIncreaseEvent(msg.peerUid, grayTipElement); } } else if (grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) { // 解析json事件 if (grayTipElement.jsonGrayTipElement.busiId == 1061) { - const paiYiPaiEvent = await this.parsePaiYiPai(msg, grayTipElement.jsonGrayTipElement.jsonStr); - if (paiYiPaiEvent) { - events.push(paiYiPaiEvent); - } + return await this.parsePaiYiPai(msg, grayTipElement.jsonGrayTipElement.jsonStr); } else if (grayTipElement.jsonGrayTipElement.busiId == JsonGrayBusiId.AIO_GROUP_ESSENCE_MSG_TIP) { - const essenceMsgEvent = await this.parseEssenceMsg(msg, grayTipElement.jsonGrayTipElement.jsonStr); - if (essenceMsgEvent) { - events.push(essenceMsgEvent); - } + return await this.parseEssenceMsg(msg, grayTipElement.jsonGrayTipElement.jsonStr); } else { - const otherJsonEvent = await this.parseOtherJsonEvent(msg, grayTipElement.jsonGrayTipElement.jsonStr, this.core.context) - if (otherJsonEvent) { - events.push(otherJsonEvent); - } + return await this.parseOtherJsonEvent(msg, grayTipElement.jsonGrayTipElement.jsonStr, this.core.context) } } - return events; + return undefined; } } diff --git a/src/onebot/index.ts b/src/onebot/index.ts index 56a853af..bb02d11a 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -13,6 +13,7 @@ import { Peer, RawMessage, SendStatusType, + NTMsgType, } from '@/core'; import { OB11ConfigLoader } from '@/onebot/config'; import { @@ -600,10 +601,24 @@ export class NapCatOneBot11Adapter { private async handleGroupEvent(message: RawMessage) { try { + // 群名片修改事件解析 任何都该判断 + if (message.senderUin && message.senderUin !== '0') { + const cardChangedEvent = await this.apis.GroupApi.parseCardChangedEvent(message); + cardChangedEvent && await this.networkManager.emitEvent(cardChangedEvent); + } + if (message.msgType === NTMsgType.KMSGTYPEFILE) { + //文件上传事件 文件为单一元素 + const elementWrapper = message.elements.find(e => !!e.fileElement); + if (elementWrapper?.fileElement) { + const uploadGroupFileEvent = await this.apis.GroupApi.parseGroupUploadFileEvene(message, elementWrapper.fileElement, elementWrapper); + uploadGroupFileEvent && await this.networkManager.emitEvent(uploadGroupFileEvent); + } + } const grayTipElement = message.elements.find((element) => element.grayTipElement)?.grayTipElement; - if (!grayTipElement) return; - const events = await this.apis.GroupApi.parseGrayTipElement(message, grayTipElement); - await this.networkManager.emitEvents(events); + if (grayTipElement) { + const event = await this.apis.GroupApi.parseGrayTipElement(message, grayTipElement); + event && await this.networkManager.emitEvent(event); + } } catch (e) { this.context.logger.logError('constructGroupEvent error: ', e); } From 4e6af0a6559d0934b616e5a4fa8430f4d57ff6c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 25 Nov 2024 21:28:04 +0800 Subject: [PATCH 04/12] =?UTF-8?q?feat:=20=E6=80=A7=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/onebot/index.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/onebot/index.ts b/src/onebot/index.ts index bb02d11a..882fef00 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -527,12 +527,10 @@ export class NapCatOneBot11Adapter { private async emitMsg(message: RawMessage) { const network = Object.values(this.configLoader.configData.network).flat() as Array; this.context.logger.logDebug('收到新消息 RawMessage', message); - await this.handleMsg(message, network); - if (message.chatType == ChatType.KCHATTYPEGROUP) { - await this.handleGroupEvent(message); - } else { - await this.handlePrivateMsgEvent(message); - } + await Promise.allSettled([ + this.handleMsg(message, network), + message.chatType == ChatType.KCHATTYPEGROUP ? this.handleGroupEvent(message) : this.handlePrivateMsgEvent(message) + ]); } private async handleMsg(message: RawMessage, network: Array) { try { @@ -607,17 +605,19 @@ export class NapCatOneBot11Adapter { cardChangedEvent && await this.networkManager.emitEvent(cardChangedEvent); } if (message.msgType === NTMsgType.KMSGTYPEFILE) { - //文件上传事件 文件为单一元素 + // 文件为单元素消息 const elementWrapper = message.elements.find(e => !!e.fileElement); if (elementWrapper?.fileElement) { const uploadGroupFileEvent = await this.apis.GroupApi.parseGroupUploadFileEvene(message, elementWrapper.fileElement, elementWrapper); uploadGroupFileEvent && await this.networkManager.emitEvent(uploadGroupFileEvent); } - } - const grayTipElement = message.elements.find((element) => element.grayTipElement)?.grayTipElement; - if (grayTipElement) { - const event = await this.apis.GroupApi.parseGrayTipElement(message, grayTipElement); - event && await this.networkManager.emitEvent(event); + } else if (message.msgType === NTMsgType.KMSGTYPEGRAYTIPS) { + // 灰条为单元素消息 + const grayTipElement = message.elements[0].grayTipElement; + if (grayTipElement) { + const event = await this.apis.GroupApi.parseGrayTipElement(message, grayTipElement); + event && await this.networkManager.emitEvent(event); + } } } catch (e) { this.context.logger.logError('constructGroupEvent error: ', e); From 6d0020533cb02c48f22a0ffaa1da280e8a2fa148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 25 Nov 2024 21:44:22 +0800 Subject: [PATCH 05/12] =?UTF-8?q?chore:=20=E5=8F=AF=E8=AF=BB=E6=80=A7?= =?UTF-8?q?=E6=8F=90=E9=AB=98=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/onebot/api/msg.ts | 124 +++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 49 deletions(-) diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index a1a771e0..02cf1f1d 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -727,8 +727,33 @@ export class OneBotMsgApi { ) { if (msg.senderUin == '0' || msg.senderUin == '') return; if (msg.peerUin == '0' || msg.peerUin == '') return; - //跳过空消息 - const resMsg: OB11Message = { + + const resMsg = this.initializeMessage(msg); + + if (this.core.selfInfo.uin == msg.senderUin) { + resMsg.message_sent_type = 'self'; + } + + if (msg.chatType == ChatType.KCHATTYPEGROUP) { + await this.handleGroupMessage(resMsg, msg); + } else if (msg.chatType == ChatType.KCHATTYPEC2C) { + await this.handlePrivateMessage(resMsg, msg); + } else if (msg.chatType == ChatType.KCHATTYPETEMPC2CFROMGROUP) { + await this.handleTempGroupMessage(resMsg, msg); + } else { + return undefined; + } + + const validSegments = await this.parseMessageSegments(msg, parseMultMsg); + resMsg.message = validSegments; + resMsg.raw_message = validSegments.map(msg => encodeCQCode(msg)).join('').trim(); + + const stringMsg = await this.convertArrayToStringMessage(resMsg); + return { stringMsg, arrayMsg: resMsg }; + } + + private initializeMessage(msg: RawMessage): OB11Message { + return { self_id: parseInt(this.core.selfInfo.uin), user_id: parseInt(msg.senderUin), time: parseInt(msg.msgTime) || Date.now(), @@ -748,37 +773,40 @@ export class OneBotMsgApi { message_format: 'array', post_type: this.core.selfInfo.uin == msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE, }; - if (this.core.selfInfo.uin == msg.senderUin) { - resMsg.message_sent_type = 'self'; - } - if (msg.chatType == ChatType.KCHATTYPEGROUP) { - resMsg.sub_type = 'normal'; // 这里go-cqhttp是group,而onebot11标准是normal, 蛋疼 - resMsg.group_id = parseInt(msg.peerUin); - let member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin); - if (!member) member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin); - if (member) { - resMsg.sender.role = OB11Construct.groupMemberRole(member.role); - resMsg.sender.nickname = member.nick; - } - } else if (msg.chatType == ChatType.KCHATTYPEC2C) { - resMsg.sub_type = 'friend'; - resMsg.sender.nickname = (await this.core.apis.UserApi.getUserDetailInfo(msg.senderUid)).nick; - } else if (msg.chatType == ChatType.KCHATTYPETEMPC2CFROMGROUP) { - resMsg.sub_type = 'group'; - const ret = await this.core.apis.MsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid); - if (ret.result === 0) { - const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin); - resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode); - resMsg.sender.nickname = member?.nick ?? member?.cardName ?? '临时会话'; - resMsg.temp_source = resMsg.group_id; - } else { - resMsg.group_id = 284840486; //兜底数据 - resMsg.temp_source = resMsg.group_id; - resMsg.sender.nickname = '临时会话'; - } - } + } - // 处理消息段 + private async handleGroupMessage(resMsg: OB11Message, msg: RawMessage) { + resMsg.sub_type = 'normal'; + resMsg.group_id = parseInt(msg.peerUin); + let member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin); + if (!member) member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin); + if (member) { + resMsg.sender.role = OB11Construct.groupMemberRole(member.role); + resMsg.sender.nickname = member.nick; + } + } + + private async handlePrivateMessage(resMsg: OB11Message, msg: RawMessage) { + resMsg.sub_type = 'friend'; + resMsg.sender.nickname = (await this.core.apis.UserApi.getUserDetailInfo(msg.senderUid)).nick; + } + + private async handleTempGroupMessage(resMsg: OB11Message, msg: RawMessage) { + resMsg.sub_type = 'group'; + const ret = await this.core.apis.MsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid); + if (ret.result === 0) { + const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin); + resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode); + resMsg.sender.nickname = member?.nick ?? member?.cardName ?? '临时会话'; + resMsg.temp_source = resMsg.group_id; + } else { + resMsg.group_id = 284840486; + resMsg.temp_source = resMsg.group_id; + resMsg.sender.nickname = '临时会话'; + } + } + + private async parseMessageSegments(msg: RawMessage, parseMultMsg: boolean): Promise { const msgSegments = await Promise.allSettled(msg.elements.map( async (element) => { for (const key in element) { @@ -793,43 +821,41 @@ export class OneBotMsgApi { element[key], msg, element, - { - parseMultMsg: parseMultMsg - } + { parseMultMsg } ); - // 对于 face 类型的消息,检查是否存在 if (key === 'faceElement' && !parsedElement) { - return null; // 如果没有找到对应的表情,返回 null + return null; } - return parsedElement; } } }, )); - // 过滤掉无效的消息段 - const validSegments = msgSegments.filter(entry => { + return msgSegments.filter(entry => { if (entry.status === 'fulfilled') { return !!entry.value; } else { - this.core.context.logger.logError.bind(this.core.context.logger)('消息段解析失败', entry.reason); + this.core.context.logger.logError('消息段解析失败', entry.reason); return false; } }).map((entry) => (>entry).value).filter(value => value != null); - - const msgAsCQCode = validSegments.map(msg => encodeCQCode(msg)).join('').trim(); - resMsg.message = validSegments; - resMsg.raw_message = msgAsCQCode; - let stringMsg = structuredClone(resMsg); - stringMsg = await this.importArrayTostringMsg(stringMsg); - return { stringMsg: stringMsg, arrayMsg: resMsg }; } - async importArrayTostringMsg(msg: OB11Message) { + + private async convertArrayToStringMessage(originMsg: OB11Message): Promise { + let msg = structuredClone(originMsg); msg.message_format = 'string'; msg.message = msg.raw_message; return msg; } + + async importArrayTostringMsg(originMsg: OB11Message) { + let msg = structuredClone(originMsg); + msg.message_format = 'string'; + msg.message = msg.raw_message; + return msg; + } + async createSendElements( messageData: OB11MessageData[], peer: Peer, From 1adb4a4ba8b963d4e6e6a6edc8ff8f2c5a7e7c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 25 Nov 2024 21:53:35 +0800 Subject: [PATCH 06/12] refactor: parsePrivateMsgEvent --- src/onebot/api/msg.ts | 24 +++++++++--------------- src/onebot/index.ts | 11 ++++++++--- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index 02cf1f1d..fa2a31ee 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -17,6 +17,7 @@ import { SendTextElement, BaseEmojiType, FaceType, + GrayTipElement, } from '@/core'; import faceConfig from '@/core/external/face_config.json'; import { NapCatOneBot11Adapter, OB11Message, OB11MessageData, OB11MessageDataType, OB11MessageFileBase, OB11MessageForward, } from '@/onebot'; @@ -664,20 +665,13 @@ export class OneBotMsgApi { this.core = core; } - async parsePrivateMsgEvent(msg: RawMessage) { - if (msg.chatType !== ChatType.KCHATTYPEC2C) { - return; - } - for (const element of msg.elements) { - if (element.grayTipElement && element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) { - if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) { - const PokeEvent = await this.obContext.apis.FriendApi.parsePrivatePokeEvent(element.grayTipElement); - if (PokeEvent) return PokeEvent; - } - //好友添加成功事件 - if (element.grayTipElement.jsonGrayTipElement.busiId == 19324 && msg.peerUid !== '') { - return new OB11FriendAddNoticeEvent(this.core, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid))); - } + async parsePrivateMsgEvent(msg: RawMessage, grayTipElement: GrayTipElement) { + if (grayTipElement && grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) { + if (grayTipElement.jsonGrayTipElement.busiId == 1061) { + const PokeEvent = await this.obContext.apis.FriendApi.parsePrivatePokeEvent(grayTipElement); + if (PokeEvent) return PokeEvent; + } else if (grayTipElement.jsonGrayTipElement.busiId == 19324 && msg.peerUid !== '') { + return new OB11FriendAddNoticeEvent(this.core, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid))); } } } @@ -733,7 +727,7 @@ export class OneBotMsgApi { if (this.core.selfInfo.uin == msg.senderUin) { resMsg.message_sent_type = 'self'; } - + if (msg.chatType == ChatType.KCHATTYPEGROUP) { await this.handleGroupMessage(resMsg, msg); } else if (msg.chatType == ChatType.KCHATTYPEC2C) { diff --git a/src/onebot/index.ts b/src/onebot/index.ts index 882fef00..6b32ad95 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -626,14 +626,19 @@ export class NapCatOneBot11Adapter { private async handlePrivateMsgEvent(message: RawMessage) { try { - const privateEvent = await this.apis.MsgApi.parsePrivateMsgEvent(message); - if (privateEvent) { - this.networkManager.emitEvent(privateEvent); + if (message.msgType === NTMsgType.KMSGTYPEGRAYTIPS) { + // 灰条为单元素消息 + const grayTipElement = message.elements[0].grayTipElement; + if (grayTipElement) { + const event = await this.apis.MsgApi.parsePrivateMsgEvent(message, grayTipElement); + event && await this.networkManager.emitEvent(event); + } } } catch (e) { this.context.logger.logError('constructPrivateEvent error: ', e); } } + private async emitRecallMsg(msgList: RawMessage[], cache: LRUCache) { for (const message of msgList) { // log("message update", message.sendStatus, message.msgId, message.msgSeq) From c3568d07e8627c1fb0903274c5b308c1a92f23ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 25 Nov 2024 21:56:34 +0800 Subject: [PATCH 07/12] fix: #563 --- src/onebot/api/msg.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index fa2a31ee..20c9a867 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -912,11 +912,19 @@ export class OneBotMsgApi { guildId: '', peerUid: peer.peerUid, }, returnMsg.msgId); + setTimeout(() => { deleteAfterSentFiles.forEach(file => { - fsPromise.unlink(file).then().catch(e => this.core.context.logger.logError.bind(this.core.context.logger)('发送消息删除文件失败', e)); + try { + if (fs.existsSync(file)) { + fsPromise.unlink(file).then().catch(e => this.core.context.logger.logError.bind(this.core.context.logger)('发送消息删除文件失败', e)); + } + } catch (error) { + this.core.context.logger.logError.bind(this.core.context.logger)('发送消息删除文件失败', (e as Error).message) + } }); }, 60000); + return returnMsg; } From a1079dd948e5877fdcea162135e9f85abc2c1c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 25 Nov 2024 21:58:35 +0800 Subject: [PATCH 08/12] fix --- src/onebot/api/msg.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index 20c9a867..480ec96a 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -920,11 +920,11 @@ export class OneBotMsgApi { fsPromise.unlink(file).then().catch(e => this.core.context.logger.logError.bind(this.core.context.logger)('发送消息删除文件失败', e)); } } catch (error) { - this.core.context.logger.logError.bind(this.core.context.logger)('发送消息删除文件失败', (e as Error).message) + this.core.context.logger.logError.bind(this.core.context.logger)('发送消息删除文件失败', (error as Error).message) } }); }, 60000); - + return returnMsg; } From 62127b6d48dd53e58a3a1a592c3cb1bd16fe33a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 25 Nov 2024 22:36:07 +0800 Subject: [PATCH 09/12] refactor: onMsgRecall --- src/core/listeners/NodeIKernelMsgListener.ts | 2 +- src/core/types/element.ts | 17 +++++++++-------- src/onebot/api/msg.ts | 4 ++-- src/onebot/api/user.ts | 4 ++-- src/onebot/index.ts | 14 ++++++++++---- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/core/listeners/NodeIKernelMsgListener.ts b/src/core/listeners/NodeIKernelMsgListener.ts index bdfcd0a5..379f0289 100644 --- a/src/core/listeners/NodeIKernelMsgListener.ts +++ b/src/core/listeners/NodeIKernelMsgListener.ts @@ -255,7 +255,7 @@ export class NodeIKernelMsgListener { } - onMsgRecall(i2: unknown, str: unknown, j2: unknown): any { + onMsgRecall(chatType: ChatType, uid: string, msgSeq: string): any { } diff --git a/src/core/types/element.ts b/src/core/types/element.ts index 6211650b..579603ba 100644 --- a/src/core/types/element.ts +++ b/src/core/types/element.ts @@ -40,17 +40,18 @@ export interface FaceElement { surpriseId?: string; randomType?: number; } +export interface GrayTipRovokeElement { + operatorRole: string; + operatorUid: string; + operatorNick: string; + operatorRemark: string; + operatorMemRemark?: string; + wording: string; // 自定义的撤回提示语 +} export interface GrayTipElement { subElementType: NTGrayTipElementSubTypeV2; - revokeElement: { - operatorRole: string; - operatorUid: string; - operatorNick: string; - operatorRemark: string; - operatorMemRemark?: string; - wording: string; // 自定义的撤回提示语 - }; + revokeElement: GrayTipRovokeElement; aioOpGrayTipElement: TipAioOpGrayTipElement; groupElement: TipGroupElement; xmlElement: { diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index 480ec96a..c987d400 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -666,10 +666,10 @@ export class OneBotMsgApi { } async parsePrivateMsgEvent(msg: RawMessage, grayTipElement: GrayTipElement) { - if (grayTipElement && grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) { + if (grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) { if (grayTipElement.jsonGrayTipElement.busiId == 1061) { const PokeEvent = await this.obContext.apis.FriendApi.parsePrivatePokeEvent(grayTipElement); - if (PokeEvent) return PokeEvent; + if (PokeEvent) { return PokeEvent }; } else if (grayTipElement.jsonGrayTipElement.busiId == 19324 && msg.peerUid !== '') { return new OB11FriendAddNoticeEvent(this.core, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid))); } diff --git a/src/onebot/api/user.ts b/src/onebot/api/user.ts index eeb1fcc2..68a7a295 100644 --- a/src/onebot/api/user.ts +++ b/src/onebot/api/user.ts @@ -1,4 +1,4 @@ -import { NapCatCore } from '@/core'; +import { GrayTipRovokeElement, NapCatCore, RawMessage } from '@/core'; import { NapCatOneBot11Adapter } from '@/onebot'; import { OB11ProfileLikeEvent } from '@/onebot/event/notice/OB11ProfileLikeEvent'; import { decodeProfileLikeTip } from "@/core/helper/adaptDecoder"; @@ -11,7 +11,7 @@ export class OneBotUserApi { this.obContext = obContext; this.core = core; } - + async parseLikeEvent(wrappedBody: Uint8Array): Promise { const likeTip = decodeProfileLikeTip(Uint8Array.from(wrappedBody)); if (likeTip?.msgType !== 0 || likeTip?.subType !== 203) return; diff --git a/src/onebot/index.ts b/src/onebot/index.ts index 6b32ad95..3b655b26 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -265,16 +265,22 @@ export class NapCatOneBot11Adapter { }; const msgIdSend = new LRUCache(100); - const recallMsgs = new LRUCache(100); + msgListener.onAddSendMsg = async (msg) => { if (msg.sendStatus == SendStatusType.KSEND_STATUS_SENDING) { msgIdSend.put(msg.msgId, 0); } }; + msgListener.onMsgRecall = async (chatType: ChatType, uid: string, msgSeq: string) => { + const peer: Peer = { + chatType: chatType, + peerUid: uid, + guildId: '' + }; + let msg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeq(peer, msgSeq)).msgList; + console.log(JSON.stringify(msg)); + } msgListener.onMsgInfoListUpdate = async (msgList) => { - this.emitRecallMsg(msgList, recallMsgs).catch((e) => - this.context.logger.logError.bind(this.context.logger)('处理消息失败', e) - ); for (const msg of msgList.filter((e) => e.senderUin == this.core.selfInfo.uin)) { if (msg.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS && msgIdSend.get(msg.msgId) == 0) { msgIdSend.put(msg.msgId, 1); From 657ddd334186c695da0c870be262e1fa30f6c7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Tue, 26 Nov 2024 11:08:12 +0800 Subject: [PATCH 10/12] refactor: emitRecallMsg --- src/onebot/index.ts | 90 ++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/onebot/index.ts b/src/onebot/index.ts index 3b655b26..57fac72b 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -14,6 +14,7 @@ import { RawMessage, SendStatusType, NTMsgType, + MessageElement, } from '@/core'; import { OB11ConfigLoader } from '@/onebot/config'; import { @@ -277,8 +278,11 @@ export class NapCatOneBot11Adapter { peerUid: uid, guildId: '' }; - let msg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeq(peer, msgSeq)).msgList; - console.log(JSON.stringify(msg)); + let msg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeq(peer, msgSeq)).msgList.find(e => e.msgType == NTMsgType.KMSGTYPEGRAYTIPS); + let element = msg?.elements[0]; + if (msg && element) { + await this.emitRecallMsg(msg, element); + } } msgListener.onMsgInfoListUpdate = async (msgList) => { for (const msg of msgList.filter((e) => e.senderUin == this.core.selfInfo.uin)) { @@ -645,51 +649,47 @@ export class NapCatOneBot11Adapter { } } - private async emitRecallMsg(msgList: RawMessage[], cache: LRUCache) { - for (const message of msgList) { - // log("message update", message.sendStatus, message.msgId, message.msgSeq) - const peer: Peer = { chatType: message.chatType, peerUid: message.peerUid, guildId: '' }; - if (message.recallTime != '0' && !cache.get(message.msgId)) { - //TODO: 这个判断方法不太好,应该使用灰色消息元素来判断? - cache.put(message.msgId, true); - // 撤回消息上报 - let oriMessageId = MessageUnique.getShortIdByMsgId(message.msgId); - if (!oriMessageId) { - oriMessageId = MessageUnique.createUniqueMsgId(peer, message.msgId); - } - if (message.chatType == ChatType.KCHATTYPEC2C) { - const friendRecallEvent = new OB11FriendRecallNoticeEvent( - this.core, - +message.senderUin, - oriMessageId - ); - this.networkManager - .emitEvent(friendRecallEvent) - .catch((e) => - this.context.logger.logError.bind(this.context.logger)('处理好友消息撤回失败', e) - ); - } else if (message.chatType == ChatType.KCHATTYPEGROUP) { - let operatorId = message.senderUin; - for (const element of message.elements) { - const operatorUid = element.grayTipElement?.revokeElement.operatorUid; - if (!operatorUid) return; - const operator = await this.core.apis.GroupApi.getGroupMember(message.peerUin, operatorUid); - operatorId = operator?.uin ?? message.senderUin; - } - const groupRecallEvent = new OB11GroupRecallNoticeEvent( - this.core, - +message.peerUin, - +message.senderUin, - +operatorId, - oriMessageId - ); - this.networkManager - .emitEvent(groupRecallEvent) - .catch((e) => this.context.logger.logError.bind(this.context.logger)('处理群消息撤回失败', e)); - } - } + private async emitRecallMsg(message: RawMessage, element: MessageElement) { + const peer: Peer = { chatType: message.chatType, peerUid: message.peerUid, guildId: '' }; + let oriMessageId = MessageUnique.getShortIdByMsgId(message.msgId) ?? MessageUnique.createUniqueMsgId(peer, message.msgId); + if (message.chatType == ChatType.KCHATTYPEC2C) { + await this.emitFriendRecallMsg(message, oriMessageId, element); + } else if (message.chatType == ChatType.KCHATTYPEGROUP) { + await this.emitGroupRecallMsg(message, oriMessageId, element); } } + + private async emitFriendRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) { + const friendRecallEvent = new OB11FriendRecallNoticeEvent( + this.core, + +message.senderUin, + oriMessageId + ); + try { + await this.networkManager.emitEvent(friendRecallEvent); + } catch (e) { + this.context.logger.logError('处理好友消息撤回失败', e); + } + } + + private async emitGroupRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) { + const operatorUid = element.grayTipElement?.revokeElement.operatorUid; + if (!operatorUid) return; + let operatorId = message.senderUin ?? await this.core.apis.UserApi.getUinByUidV2(operatorUid); + const groupRecallEvent = new OB11GroupRecallNoticeEvent( + this.core, + +message.peerUin, + +message.senderUin, + +operatorId, + oriMessageId + ); + try { + await this.networkManager.emitEvent(groupRecallEvent); + } catch (e) { + this.context.logger.logError('处理群消息撤回失败', e); + } + } + } export * from './types'; From aadebb3cc5c3540f0d81df58563a15432d400e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Tue, 26 Nov 2024 11:10:59 +0800 Subject: [PATCH 11/12] refactor: event emit --- src/onebot/index.ts | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/onebot/index.ts b/src/onebot/index.ts index 57fac72b..bf5d130c 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -281,7 +281,14 @@ export class NapCatOneBot11Adapter { let msg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeq(peer, msgSeq)).msgList.find(e => e.msgType == NTMsgType.KMSGTYPEGRAYTIPS); let element = msg?.elements[0]; if (msg && element) { - await this.emitRecallMsg(msg, element); + let recallEvent = await this.emitRecallMsg(msg, element); + try { + if (recallEvent) { + await this.networkManager.emitEvent(recallEvent); + } + } catch (e) { + this.context.logger.logError('处理消息撤回失败', e); + } } } msgListener.onMsgInfoListUpdate = async (msgList) => { @@ -542,6 +549,7 @@ export class NapCatOneBot11Adapter { message.chatType == ChatType.KCHATTYPEGROUP ? this.handleGroupEvent(message) : this.handlePrivateMsgEvent(message) ]); } + private async handleMsg(message: RawMessage, network: Array) { try { const ob11Msg = await this.apis.MsgApi.parseMessageV2(message, this.configLoader.configData.parseMultMsg); @@ -653,41 +661,32 @@ export class NapCatOneBot11Adapter { const peer: Peer = { chatType: message.chatType, peerUid: message.peerUid, guildId: '' }; let oriMessageId = MessageUnique.getShortIdByMsgId(message.msgId) ?? MessageUnique.createUniqueMsgId(peer, message.msgId); if (message.chatType == ChatType.KCHATTYPEC2C) { - await this.emitFriendRecallMsg(message, oriMessageId, element); + return await this.emitFriendRecallMsg(message, oriMessageId, element); } else if (message.chatType == ChatType.KCHATTYPEGROUP) { - await this.emitGroupRecallMsg(message, oriMessageId, element); + return await this.emitGroupRecallMsg(message, oriMessageId, element); } + } private async emitFriendRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) { - const friendRecallEvent = new OB11FriendRecallNoticeEvent( + return new OB11FriendRecallNoticeEvent( this.core, +message.senderUin, oriMessageId ); - try { - await this.networkManager.emitEvent(friendRecallEvent); - } catch (e) { - this.context.logger.logError('处理好友消息撤回失败', e); - } } private async emitGroupRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) { const operatorUid = element.grayTipElement?.revokeElement.operatorUid; - if (!operatorUid) return; + if (!operatorUid) return undefined; let operatorId = message.senderUin ?? await this.core.apis.UserApi.getUinByUidV2(operatorUid); - const groupRecallEvent = new OB11GroupRecallNoticeEvent( + return new OB11GroupRecallNoticeEvent( this.core, +message.peerUin, +message.senderUin, +operatorId, oriMessageId ); - try { - await this.networkManager.emitEvent(groupRecallEvent); - } catch (e) { - this.context.logger.logError('处理群消息撤回失败', e); - } } } From ceec9e5e1b40745b9caad57f79c347c9b3e9caed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Tue, 26 Nov 2024 11:26:34 +0800 Subject: [PATCH 12/12] refactor: self report --- src/onebot/index.ts | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/onebot/index.ts b/src/onebot/index.ts index bf5d130c..a8858bc6 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -265,11 +265,24 @@ export class NapCatOneBot11Adapter { } }; - const msgIdSend = new LRUCache(100); - msgListener.onAddSendMsg = async (msg) => { if (msg.sendStatus == SendStatusType.KSEND_STATUS_SENDING) { - msgIdSend.put(msg.msgId, 0); + await this.core.eventWrapper.registerListen('NodeIKernelMsgListener/onMsgInfoListUpdate', (msgList: RawMessage[]) => { + const report = msgList.find((e) => + e.senderUin == this.core.selfInfo.uin && e.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS && e.msgId === msg.msgId + ); + return !!report; + }, 1, 300); + msg.id = MessageUnique.createUniqueMsgId( + { + chatType: msg.chatType, + peerUid: msg.peerUid, + guildId: '', + }, + msg.msgId + ); + //此时上报的seq不是对的 不过对onebot业务无影响 + this.emitMsg(msg); } }; msgListener.onMsgRecall = async (chatType: ChatType, uid: string, msgSeq: string) => { @@ -291,23 +304,6 @@ export class NapCatOneBot11Adapter { } } } - msgListener.onMsgInfoListUpdate = async (msgList) => { - for (const msg of msgList.filter((e) => e.senderUin == this.core.selfInfo.uin)) { - if (msg.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS && msgIdSend.get(msg.msgId) == 0) { - msgIdSend.put(msg.msgId, 1); - // 完成后再post - msg.id = MessageUnique.createUniqueMsgId( - { - chatType: msg.chatType, - peerUid: msg.peerUid, - guildId: '', - }, - msg.msgId - ); - this.emitMsg(msg); - } - } - }; msgListener.onKickedOffLine = async (kick) => { const event = new BotOfflineEvent(this.core, kick.tipsTitle, kick.tipsDesc); this.networkManager @@ -549,7 +545,7 @@ export class NapCatOneBot11Adapter { message.chatType == ChatType.KCHATTYPEGROUP ? this.handleGroupEvent(message) : this.handlePrivateMsgEvent(message) ]); } - + private async handleMsg(message: RawMessage, network: Array) { try { const ob11Msg = await this.apis.MsgApi.parseMessageV2(message, this.configLoader.configData.parseMultMsg);