mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
refactor: getFile
This commit is contained in:
parent
7f9da8cc2d
commit
025da8fb76
@ -1,7 +1,7 @@
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import { QQLevel } from '@/core';
|
import { Peer, QQLevel } from '@/core';
|
||||||
|
|
||||||
export async function solveProblem<T extends (...arg: any[]) => any>(func: T, ...args: Parameters<T>): Promise<ReturnType<T> | undefined> {
|
export async function solveProblem<T extends (...arg: any[]) => any>(func: T, ...args: Parameters<T>): Promise<ReturnType<T> | undefined> {
|
||||||
return new Promise<ReturnType<T> | undefined>((resolve) => {
|
return new Promise<ReturnType<T> | undefined>((resolve) => {
|
||||||
@ -45,7 +45,29 @@ export class UUIDConverter {
|
|||||||
return { high: high.toString(), low: low.toString() };
|
return { high: high.toString(), low: low.toString() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export class FileNapCatOneBotUUID {
|
||||||
|
static encode(peer: Peer, msgId: string, elementId: string): string {
|
||||||
|
return `NapCatOneBot-File-${peer.chatType}-${peer.peerUid}-${msgId}-${elementId}`;
|
||||||
|
}
|
||||||
|
static decode(uuid: string): undefined | {
|
||||||
|
peer: Peer,
|
||||||
|
msgId: string,
|
||||||
|
elementId: string
|
||||||
|
} {
|
||||||
|
if (!uuid.startsWith('NapCatOneBot-File-')) return undefined;
|
||||||
|
const data = uuid.split('-');
|
||||||
|
if (data.length !== 6) return undefined;
|
||||||
|
const [, , chatType, peerUid, msgId, elementId] = data;
|
||||||
|
return {
|
||||||
|
peer: {
|
||||||
|
chatType: chatType as any,
|
||||||
|
peerUid: peerUid
|
||||||
|
},
|
||||||
|
msgId,
|
||||||
|
elementId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
export function sleep(ms: number): Promise<void> {
|
export function sleep(ms: number): Promise<void> {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { UUIDConverter } from '@/common/helper';
|
import { FileNapCatOneBotUUID } from '@/common/helper';
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { ChatType, ElementType, Peer, RawMessage } from '@/core/entities';
|
import { ChatType, Peer, RawMessage } from '@/core/entities';
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
|
|
||||||
export interface GetFilePayload {
|
export interface GetFilePayload {
|
||||||
@ -29,64 +29,44 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
payloadSchema: any = GetFileBase_PayloadSchema;
|
payloadSchema: any = GetFileBase_PayloadSchema;
|
||||||
|
|
||||||
async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
|
async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
|
||||||
const NTQQFriendApi = this.core.apis.FriendApi;
|
|
||||||
const NTQQUserApi = this.core.apis.UserApi;
|
|
||||||
const NTQQMsgApi = this.core.apis.MsgApi;
|
const NTQQMsgApi = this.core.apis.MsgApi;
|
||||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
|
||||||
const NTQQFileApi = this.core.apis.FileApi;
|
const NTQQFileApi = this.core.apis.FileApi;
|
||||||
try {
|
|
||||||
const uuidData = UUIDConverter.decode(payload.file);
|
const contextFile = FileNapCatOneBotUUID.decode(payload.file);
|
||||||
const peerUin = uuidData.high;
|
|
||||||
const msgId = uuidData.low;
|
//接收消息标记模式
|
||||||
const isGroup: boolean = !!(await NTQQGroupApi.getGroups(false)).find(e => e.groupCode == peerUin);
|
if (contextFile) {
|
||||||
let peer: Peer | undefined;
|
const { peer, msgId, elementId } = contextFile;
|
||||||
//识别Peer
|
|
||||||
if (isGroup) {
|
const downloadPath = await NTQQFileApi.downloadMedia(msgId, peer.chatType, peer.peerUid, elementId, '', '');
|
||||||
peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: peerUin };
|
|
||||||
}
|
const mixElement = (await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]))?.msgList
|
||||||
const PeerUid = await NTQQUserApi.getUidByUinV2(peerUin);
|
.find(msg => msg.msgId === msgId)?.elements.find(e => e.elementId === elementId);
|
||||||
if (PeerUid) {
|
const mixElementInner = mixElement?.videoElement ?? mixElement?.fileElement ?? mixElement?.pttElement ?? mixElement?.picElement ;
|
||||||
const isBuddy = await NTQQFriendApi.isBuddy(PeerUid);
|
if(!mixElementInner) throw new Error('element not found');
|
||||||
if (isBuddy) {
|
|
||||||
peer = { chatType: ChatType.KCHATTYPEC2C, peerUid: PeerUid };
|
const fileSize = mixElementInner.fileSize?.toString() || '';
|
||||||
} else {
|
const fileName = mixElementInner.fileName || '';
|
||||||
peer = { chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid: PeerUid };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!peer) {
|
|
||||||
throw new Error('chattype not support');
|
|
||||||
}
|
|
||||||
const msgList = await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]);
|
|
||||||
if (msgList.msgList.length == 0) {
|
|
||||||
throw new Error('msg not found');
|
|
||||||
}
|
|
||||||
const msg = msgList.msgList[0];
|
|
||||||
const findEle = msg.elements.find(e => e.elementType == ElementType.VIDEO || e.elementType == ElementType.FILE || e.elementType == ElementType.PTT);
|
|
||||||
if (!findEle) {
|
|
||||||
throw new Error('element not found');
|
|
||||||
}
|
|
||||||
const downloadPath = await NTQQFileApi.downloadMedia(msgId, msg.chatType, msg.peerUid, findEle.elementId, '', '');
|
|
||||||
const fileSize = findEle?.videoElement?.fileSize || findEle?.fileElement?.fileSize || findEle?.pttElement?.fileSize || '0';
|
|
||||||
const fileName = findEle?.videoElement?.fileName || findEle?.fileElement?.fileName || findEle?.pttElement?.fileName || '';
|
|
||||||
const res: GetFileResponse = {
|
const res: GetFileResponse = {
|
||||||
file: downloadPath,
|
file: downloadPath,
|
||||||
url: downloadPath,
|
url: downloadPath,
|
||||||
file_size: fileSize,
|
file_size: fileSize,
|
||||||
file_name: fileName,
|
file_name: fileName,
|
||||||
};
|
};
|
||||||
if (/* enableLocalFile2Url && */ downloadPath) {
|
|
||||||
|
if (this.obContext.configLoader.configData.enableLocalFile2Url && downloadPath) {
|
||||||
try {
|
try {
|
||||||
res.base64 = await fs.readFile(downloadPath, 'base64');
|
res.base64 = await fs.readFile(downloadPath, 'base64');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error('文件下载失败. ' + e);
|
throw new Error('文件下载失败. ' + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//不手动删除?文件持久化了
|
|
||||||
return res;
|
return res;
|
||||||
} catch {
|
|
||||||
this.core.context.logger.logDebug('GetFileBase Mode - 1 Error');
|
|
||||||
}
|
}
|
||||||
|
//群文件模式
|
||||||
|
|
||||||
|
//搜索名字模式
|
||||||
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
||||||
if (NTSearchNameResult.length !== 0) {
|
if (NTSearchNameResult.length !== 0) {
|
||||||
const MsgId = NTSearchNameResult[0].msgId;
|
const MsgId = NTSearchNameResult[0].msgId;
|
||||||
@ -94,9 +74,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
if (NTSearchNameResult[0].chatType == ChatType.KCHATTYPEGROUP) {
|
if (NTSearchNameResult[0].chatType == ChatType.KCHATTYPEGROUP) {
|
||||||
peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: NTSearchNameResult[0].groupChatInfo[0].groupCode };
|
peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: NTSearchNameResult[0].groupChatInfo[0].groupCode };
|
||||||
}
|
}
|
||||||
if (!peer) {
|
if (!peer) throw new Error('chattype not support');
|
||||||
throw new Error('chattype not support');
|
|
||||||
}
|
|
||||||
const msgList: RawMessage[] = (await NTQQMsgApi.getMsgsByMsgId(peer, [MsgId]))?.msgList;
|
const msgList: RawMessage[] = (await NTQQMsgApi.getMsgsByMsgId(peer, [MsgId]))?.msgList;
|
||||||
if (!msgList || msgList.length == 0) {
|
if (!msgList || msgList.length == 0) {
|
||||||
throw new Error('msg not found');
|
throw new Error('msg not found');
|
||||||
@ -113,16 +91,16 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
file_size: NTSearchNameResult[0].fileSize.toString(),
|
file_size: NTSearchNameResult[0].fileSize.toString(),
|
||||||
file_name: NTSearchNameResult[0].fileName,
|
file_name: NTSearchNameResult[0].fileName,
|
||||||
};
|
};
|
||||||
if (/* enableLocalFile2Url && */ downloadPath) {
|
if (this.obContext.configLoader.configData.enableLocalFile2Url && downloadPath) {
|
||||||
try {
|
try {
|
||||||
res.base64 = await fs.readFile(downloadPath, 'base64');
|
res.base64 = await fs.readFile(downloadPath, 'base64');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error('文件下载失败. ' + e);
|
throw new Error('文件下载失败. ' + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//不手动删除?文件持久化了
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error('file not found');
|
throw new Error('file not found');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UUIDConverter } from '@/common/helper';
|
import { FileNapCatOneBotUUID } from '@/common/helper';
|
||||||
import { MessageUnique } from '@/common/message-unique';
|
import { MessageUnique } from '@/common/message-unique';
|
||||||
import {
|
import {
|
||||||
AtType,
|
AtType,
|
||||||
@ -98,14 +98,19 @@ export class OneBotMsgApi {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
picElement: async (element, msg) => {
|
picElement: async (element, msg, elementWrapper) => {
|
||||||
try {
|
try {
|
||||||
|
const peer = {
|
||||||
|
chatType: msg.chatType,
|
||||||
|
peerUid: msg.peerUid,
|
||||||
|
guildId: '',
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
type: OB11MessageDataType.image,
|
type: OB11MessageDataType.image,
|
||||||
data: {
|
data: {
|
||||||
file: element.fileName,
|
file: element.fileName,
|
||||||
sub_type: element.picSubType,
|
sub_type: element.picSubType,
|
||||||
file_id: UUIDConverter.encode(msg.peerUin, msg.msgId),
|
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
||||||
url: await this.core.apis.FileApi.getImageUrl(element),
|
url: await this.core.apis.FileApi.getImageUrl(element),
|
||||||
file_size: element.fileSize,
|
file_size: element.fileSize,
|
||||||
},
|
},
|
||||||
@ -117,6 +122,11 @@ export class OneBotMsgApi {
|
|||||||
},
|
},
|
||||||
|
|
||||||
fileElement: async (element, msg, elementWrapper) => {
|
fileElement: async (element, msg, elementWrapper) => {
|
||||||
|
const peer = {
|
||||||
|
chatType: msg.chatType,
|
||||||
|
peerUid: msg.peerUid,
|
||||||
|
guildId: '',
|
||||||
|
};
|
||||||
await this.core.apis.FileApi.addFileCache(
|
await this.core.apis.FileApi.addFileCache(
|
||||||
{
|
{
|
||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
@ -137,7 +147,7 @@ export class OneBotMsgApi {
|
|||||||
file: element.fileName,
|
file: element.fileName,
|
||||||
path: element.filePath,
|
path: element.filePath,
|
||||||
url: element.filePath,
|
url: element.filePath,
|
||||||
file_id: UUIDConverter.encode(msg.peerUin, msg.msgId),
|
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
||||||
file_size: element.fileSize,
|
file_size: element.fileSize,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -184,11 +194,16 @@ export class OneBotMsgApi {
|
|||||||
'0',
|
'0',
|
||||||
'marketface',
|
'marketface',
|
||||||
);
|
);
|
||||||
|
const peer = {
|
||||||
|
chatType: msg.chatType,
|
||||||
|
peerUid: msg.peerUid,
|
||||||
|
guildId: '',
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
type: OB11MessageDataType.image,
|
type: OB11MessageDataType.image,
|
||||||
data: {
|
data: {
|
||||||
file: 'marketface',
|
file: 'marketface',
|
||||||
file_id: UUIDConverter.encode(msg.peerUin, msg.msgId),
|
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
||||||
path: elementWrapper.elementId,
|
path: elementWrapper.elementId,
|
||||||
url: elementWrapper.elementId,
|
url: elementWrapper.elementId,
|
||||||
},
|
},
|
||||||
@ -247,7 +262,11 @@ export class OneBotMsgApi {
|
|||||||
|
|
||||||
videoElement: async (element, msg, elementWrapper) => {
|
videoElement: async (element, msg, elementWrapper) => {
|
||||||
const NTQQFileApi = this.core.apis.FileApi;
|
const NTQQFileApi = this.core.apis.FileApi;
|
||||||
|
const peer = {
|
||||||
|
chatType: msg.chatType,
|
||||||
|
peerUid: msg.peerUid,
|
||||||
|
guildId: '',
|
||||||
|
};
|
||||||
//读取视频链接并兜底
|
//读取视频链接并兜底
|
||||||
let videoUrlWrappers: Awaited<ReturnType<typeof NTQQFileApi.getVideoUrl>> | undefined;
|
let videoUrlWrappers: Awaited<ReturnType<typeof NTQQFileApi.getVideoUrl>> | undefined;
|
||||||
|
|
||||||
@ -302,13 +321,18 @@ export class OneBotMsgApi {
|
|||||||
file: element.fileName,
|
file: element.fileName,
|
||||||
path: videoDownUrl,
|
path: videoDownUrl,
|
||||||
url: videoDownUrl,
|
url: videoDownUrl,
|
||||||
file_id: UUIDConverter.encode(msg.peerUin, msg.msgId),
|
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
||||||
file_size: element.fileSize,
|
file_size: element.fileSize,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
pttElement: async (element, msg, elementWrapper) => {
|
pttElement: async (element, msg, elementWrapper) => {
|
||||||
|
const peer = {
|
||||||
|
chatType: msg.chatType,
|
||||||
|
peerUid: msg.peerUid,
|
||||||
|
guildId: '',
|
||||||
|
};
|
||||||
await this.core.apis.FileApi.addFileCache(
|
await this.core.apis.FileApi.addFileCache(
|
||||||
{
|
{
|
||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
@ -328,7 +352,7 @@ export class OneBotMsgApi {
|
|||||||
data: {
|
data: {
|
||||||
file: element.fileName,
|
file: element.fileName,
|
||||||
path: element.filePath,
|
path: element.filePath,
|
||||||
file_id: UUIDConverter.encode(msg.peerUin, msg.msgId),
|
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
||||||
file_size: element.fileSize,
|
file_size: element.fileSize,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user