mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-12-27 11:21:21 +08:00
* feat: pnpm new * Refactor build and release workflows, update dependencies Switch build scripts and workflows from npm to pnpm, update build and artifact paths, and simplify release workflow by removing version detection and changelog steps. Add new dependencies (silk-wasm, express, ws, node-pty-prebuilt-multiarch), update exports in package.json files, and add vite config for napcat-framework. Also, rename manifest.json for framework package and fix static asset copying in shell build config.
145 lines
4.9 KiB
TypeScript
145 lines
4.9 KiB
TypeScript
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
|
||
import { OB11Message, OB11MessageData, OB11MessageDataType, OB11MessageForward, OB11MessageNodePlain as OB11MessageNode } from '@/napcat-onebot/index';
|
||
import { ActionName } from '@/napcat-onebot/action/router';
|
||
import { MessageUnique } from 'napcat-common/src/message-unique';
|
||
import { Static, Type } from '@sinclair/typebox';
|
||
import { ChatType, ElementType, MsgSourceType, NTMsgType, RawMessage } from 'napcat-core';
|
||
import { isNumeric } from 'napcat-common/src/helper';
|
||
|
||
const SchemaData = Type.Object({
|
||
message_id: Type.Optional(Type.String()),
|
||
id: Type.Optional(Type.String()),
|
||
});
|
||
|
||
type Payload = Static<typeof SchemaData>;
|
||
export class GoCQHTTPGetForwardMsgAction extends OneBotAction<Payload, {
|
||
messages: OB11Message[] | undefined;
|
||
}> {
|
||
override actionName = ActionName.GoCQHTTP_GetForwardMsg;
|
||
override payloadSchema = SchemaData;
|
||
|
||
private createTemplateNode (message: OB11Message): OB11MessageNode {
|
||
return {
|
||
type: OB11MessageDataType.node,
|
||
data: {
|
||
user_id: message.user_id,
|
||
nickname: message.sender.nickname,
|
||
message: [],
|
||
content: [],
|
||
},
|
||
};
|
||
}
|
||
|
||
async parseForward (messages: OB11Message[]): Promise<OB11MessageNode[]> {
|
||
const retMsg: OB11MessageNode[] = [];
|
||
|
||
for (const message of messages) {
|
||
const templateNode = this.createTemplateNode(message);
|
||
|
||
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 ?? []);
|
||
|
||
templateNode.data.message.push(newNode);
|
||
} else {
|
||
templateNode.data.message.push(msgdata as OB11MessageData);
|
||
}
|
||
}
|
||
retMsg.push(templateNode);
|
||
}
|
||
|
||
return retMsg;
|
||
}
|
||
|
||
async _handle (payload: Payload) {
|
||
// 1. 检查消息ID是否存在
|
||
const msgId = payload.message_id || payload.id;
|
||
if (!msgId) {
|
||
throw new Error('message_id is required');
|
||
}
|
||
|
||
// 2. 定义辅助函数 - 创建伪转发消息对象
|
||
const createFakeForwardMsg = (resId: string): RawMessage => {
|
||
return {
|
||
chatType: ChatType.KCHATTYPEGROUP,
|
||
elements: [{
|
||
elementType: ElementType.MULTIFORWARD,
|
||
elementId: '',
|
||
multiForwardMsgElement: {
|
||
resId,
|
||
fileName: '',
|
||
xmlContent: '',
|
||
},
|
||
}],
|
||
guildId: '',
|
||
isOnlineMsg: false,
|
||
msgId: '', // TODO: no necessary
|
||
msgRandom: '0',
|
||
msgSeq: '',
|
||
msgTime: '',
|
||
msgType: NTMsgType.KMSGTYPEMIX,
|
||
parentMsgIdList: [],
|
||
parentMsgPeer: {
|
||
chatType: ChatType.KCHATTYPEGROUP,
|
||
peerUid: '',
|
||
},
|
||
peerName: '',
|
||
peerUid: '284840486',
|
||
peerUin: '284840486',
|
||
recallTime: '0',
|
||
records: [],
|
||
sendNickName: '',
|
||
sendRemarkName: '',
|
||
senderUid: '',
|
||
senderUin: '1094950020',
|
||
sourceType: MsgSourceType.K_DOWN_SOURCETYPE_UNKNOWN,
|
||
subMsgType: 1,
|
||
} as RawMessage;
|
||
};
|
||
|
||
// 3. 定义协议回退逻辑函数
|
||
const protocolFallbackLogic = async (resId: string) => {
|
||
const ob = (await this.obContext.apis.MsgApi.parseMessageV2(createFakeForwardMsg(resId)))?.arrayMsg;
|
||
if (ob) {
|
||
return {
|
||
messages: (ob?.message?.[0] as OB11MessageForward)?.data?.content,
|
||
};
|
||
}
|
||
throw new Error('protocolFallbackLogic: 找不到相关的聊天记录');
|
||
};
|
||
// 4. 尝试通过正常渠道获取消息
|
||
// 如果是数字ID,优先使用getMsgsByMsgId获取
|
||
if (!isNumeric(msgId)) {
|
||
const ret = await protocolFallbackLogic(msgId);
|
||
if (ret.messages) {
|
||
return ret;
|
||
}
|
||
throw new Error('ResId无效: 找不到相关的聊天记录');
|
||
}
|
||
const rootMsgId = MessageUnique.getShortIdByMsgId(msgId.toString());
|
||
const rootMsg = MessageUnique.getMsgIdAndPeerByShortId(rootMsgId ?? +msgId);
|
||
|
||
if (rootMsg) {
|
||
// 5. 获取消息内容
|
||
const data = await this.core.apis.MsgApi.getMsgsByMsgId(rootMsg.Peer, [rootMsg.MsgId]);
|
||
|
||
if (data && data.result === 0 && data.msgList.length > 0) {
|
||
const singleMsg = data.msgList[0];
|
||
if (!singleMsg) {
|
||
throw new Error('消息不存在或已过期');
|
||
}
|
||
// 6. 解析消息内容
|
||
const resMsg = (await this.obContext.apis.MsgApi.parseMessage(singleMsg, 'array', true));
|
||
|
||
const forwardContent = (resMsg?.message?.[0] as OB11MessageForward)?.data?.content;
|
||
if (forwardContent) {
|
||
return { messages: forwardContent };
|
||
}
|
||
}
|
||
}
|
||
// 说明消息已过期或者为内层消息 NapCat 一次返回不处理内层消息
|
||
throw new Error('消息已过期或者为内层消息,无法获取转发消息');
|
||
}
|
||
}
|