From 54a7cbc3f4f0708dc3cca33fdcad39dd7817d2cc Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Fri, 30 Aug 2024 11:44:15 +0800 Subject: [PATCH] feat: go-cqhttp style group file apis --- src/core/apis/group.ts | 2 +- src/core/entities/msg.ts | 1 + src/core/listeners/NodeIKernelMsgListener.ts | 42 ++++++++++++++- src/onebot/action/file/GetGroupFileCount.ts | 3 +- src/onebot/action/file/GetGroupFileList.ts | 10 ++-- .../action/go-cqhttp/CreateGroupFileFolder.ts | 32 ++++++++++++ .../action/go-cqhttp/DeleteGroupFile.ts | 32 ++++++++++++ .../action/go-cqhttp/DeleteGroupFileFolder.ts | 32 ++++++++++++ .../go-cqhttp/GetGroupFileSystemInfo.ts | 36 +++++++++++++ .../action/go-cqhttp/GetGroupFilesByFolder.ts | 52 +++++++++++++++++++ .../action/go-cqhttp/GetGroupRootFiles.ts | 47 +++++++++++++++++ src/onebot/action/index.ts | 26 ++++++++-- src/onebot/action/types.ts | 6 +++ src/onebot/entities.ts | 42 +++++++++++++-- src/onebot/types/entity.ts | 24 +++++++++ 15 files changed, 370 insertions(+), 17 deletions(-) create mode 100644 src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts create mode 100644 src/onebot/action/go-cqhttp/DeleteGroupFile.ts create mode 100644 src/onebot/action/go-cqhttp/DeleteGroupFileFolder.ts create mode 100644 src/onebot/action/go-cqhttp/GetGroupFileSystemInfo.ts create mode 100644 src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts create mode 100644 src/onebot/action/go-cqhttp/GetGroupRootFiles.ts diff --git a/src/core/apis/group.ts b/src/core/apis/group.ts index 4145cd31..818f7d03 100644 --- a/src/core/apis/group.ts +++ b/src/core/apis/group.ts @@ -402,7 +402,7 @@ export class NTQQGroupApi { } - async GetGroupFileCount(Gids: Array) { + async getGroupFileCount(Gids: Array) { return this.context.session.getRichMediaService().batchGetGroupFileCount(Gids); } diff --git a/src/core/entities/msg.ts b/src/core/entities/msg.ts index 40e4a292..4f7f7bde 100644 --- a/src/core/entities/msg.ts +++ b/src/core/entities/msg.ts @@ -22,6 +22,7 @@ export interface GetFileListParam { startIndex: number; sortOrder: number; showOnlinedocFolder: number; + folderId?: string; } export enum ElementType { diff --git a/src/core/listeners/NodeIKernelMsgListener.ts b/src/core/listeners/NodeIKernelMsgListener.ts index dca6627c..08636920 100644 --- a/src/core/listeners/NodeIKernelMsgListener.ts +++ b/src/core/listeners/NodeIKernelMsgListener.ts @@ -29,7 +29,47 @@ export interface GroupFileInfoUpdateParamType { retMsg: string; clientWording: string; isEnd: boolean; - item: Array; + item: Array<{ + peerId: string; + type: number; + folderInfo?: { + folderId: string; + parentFolderId: string; + folderName: string; + createTime: number; + modifyTime: number; + createUin: string; + creatorName: string; + totalFileCount: number; + modifyUin: string; + modifyName: string; + usedSpace: string; + }, + fileInfo?: { + fileModelId: string; + fileId: string; + fileName: string; + fileSize: string; + busId: number; + uploadedSize: string; + uploadTime: number; + deadTime: number; + modifyTime: number; + downloadTimes: number; + sha: string; + sha3: string; + md5: string; + uploaderLocalPath: string; + uploaderName: string; + uploaderUin: string; + parentFolderId: string; + localPath: string; + transStatus: number; + transType: number; + elementId: string; + isFolder: boolean; + }, + }>; allFileCount: string; nextIndex: string; reqId: string; diff --git a/src/onebot/action/file/GetGroupFileCount.ts b/src/onebot/action/file/GetGroupFileCount.ts index a42f5ce9..0fde4908 100644 --- a/src/onebot/action/file/GetGroupFileCount.ts +++ b/src/onebot/action/file/GetGroupFileCount.ts @@ -17,8 +17,7 @@ export class GetGroupFileCount extends BaseAction { payloadSchema = SchemaData; async _handle(payload: Payload) { - const NTQQGroupApi = this.core.apis.GroupApi; - const ret = await NTQQGroupApi.GetGroupFileCount([payload.group_id?.toString()]); + const ret = await this.core.apis.GroupApi.getGroupFileCount([payload.group_id?.toString()]); return { count: ret.groupFileCounts[0] }; } } diff --git a/src/onebot/action/file/GetGroupFileList.ts b/src/onebot/action/file/GetGroupFileList.ts index f9d414f6..3a8755e8 100644 --- a/src/onebot/action/file/GetGroupFileList.ts +++ b/src/onebot/action/file/GetGroupFileList.ts @@ -35,15 +35,13 @@ export class GetGroupFileList extends BaseAction sortOrder: 2, showOnlinedocFolder: 0, ...param - }).catch((e) => { + }).catch(() => { return []; }); ret.forEach((e) => { - let fileModelId = e?.fileInfo?.fileModelId; - if (fileModelId) { - e.fileModelId = fileModelId; - } - e.fileId = FileNapCatOneBotUUID.encodeModelId({ chatType: 2, peerUid: payload.group_id.toString() }, fileModelId); + const fileModelId = e?.fileInfo?.fileModelId; + if (fileModelId) + e.fileInfo!.fileId = FileNapCatOneBotUUID.encodeModelId({ chatType: 2, peerUid: payload.group_id.toString() }, fileModelId); }); return { FileList: ret }; } diff --git a/src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts b/src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts new file mode 100644 index 00000000..bd831260 --- /dev/null +++ b/src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts @@ -0,0 +1,32 @@ +import { FromSchema, JSONSchema } from 'json-schema-to-ts'; +import BaseAction from '../BaseAction'; +import { ActionName } from '../types'; +import { NapCatOneBot11Adapter } from '@/onebot'; +import { NapCatCore } from '@/core'; +import { SetGroupFileFolder } from '@/onebot/action/file/SetGroupFileFolder'; + +const SchemaData = { + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + folder_name: { type: 'string' }, + }, + required: ['group_id', 'folder_name'], +} as const satisfies JSONSchema; + +type Payload = FromSchema; + +export class CreateGroupFileFolder extends BaseAction { + actionName = ActionName.GoCQHTTP_CreateGroupFileFolder; + payloadSchema = SchemaData; + + constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore, + private ncSetGroupFileFolderImpl: SetGroupFileFolder) { + super(obContext, core); + } + + async _handle(payload: Payload) { + await this.ncSetGroupFileFolderImpl._handle(payload); + return null; + } +} diff --git a/src/onebot/action/go-cqhttp/DeleteGroupFile.ts b/src/onebot/action/go-cqhttp/DeleteGroupFile.ts new file mode 100644 index 00000000..ec8df16c --- /dev/null +++ b/src/onebot/action/go-cqhttp/DeleteGroupFile.ts @@ -0,0 +1,32 @@ +import { FromSchema, JSONSchema } from 'json-schema-to-ts'; +import BaseAction from '../BaseAction'; +import { ActionName } from '../types'; +import { NapCatCore } from '@/core'; +import { NapCatOneBot11Adapter } from '@/onebot'; +import { DelGroupFile } from '@/onebot/action/file/DelGroupFile'; + +const SchemaData = { + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + file_id: { type: 'string' }, + }, + required: ['group_id', 'file_id'], +} as const satisfies JSONSchema; + +type Payload = FromSchema; + +export class DeleteGroupFile extends BaseAction { + actionName = ActionName.GOCQHTTP_DeleteGroupFile; + payloadSchema = SchemaData; + + constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore, + private ncDelGroupFileImpl: DelGroupFile) { + super(obContext, core); + } + + async _handle(payload: Payload) { + await this.ncDelGroupFileImpl._handle(payload); + return null; + } +} diff --git a/src/onebot/action/go-cqhttp/DeleteGroupFileFolder.ts b/src/onebot/action/go-cqhttp/DeleteGroupFileFolder.ts new file mode 100644 index 00000000..e9c13d64 --- /dev/null +++ b/src/onebot/action/go-cqhttp/DeleteGroupFileFolder.ts @@ -0,0 +1,32 @@ +import { FromSchema, JSONSchema } from 'json-schema-to-ts'; +import BaseAction from '../BaseAction'; +import { ActionName } from '../types'; +import { NapCatCore } from '@/core'; +import { NapCatOneBot11Adapter } from '@/onebot'; +import { DelGroupFileFolder } from '@/onebot/action/file/DelGroupFileFolder'; + +const SchemaData = { + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + folder_id: { type: 'string' }, + }, + required: ['group_id', 'folder_id'], +} as const satisfies JSONSchema; + +type Payload = FromSchema; + +export class DeleteGroupFileFolder extends BaseAction { + actionName = ActionName.GoCQHTTP_DeleteGroupFileFolder; + payloadSchema = SchemaData; + + constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore, + private ncDelGroupFileFolderImpl: DelGroupFileFolder) { + super(obContext, core); + } + + async _handle(payload: Payload) { + await this.ncDelGroupFileFolderImpl._handle(payload); + return null; + } +} diff --git a/src/onebot/action/go-cqhttp/GetGroupFileSystemInfo.ts b/src/onebot/action/go-cqhttp/GetGroupFileSystemInfo.ts new file mode 100644 index 00000000..96344756 --- /dev/null +++ b/src/onebot/action/go-cqhttp/GetGroupFileSystemInfo.ts @@ -0,0 +1,36 @@ +import { FromSchema, JSONSchema } from 'json-schema-to-ts'; +import BaseAction from '../BaseAction'; +import { ActionName } from '../types'; +import { FileNapCatOneBotUUID } from '@/common/helper'; + +const SchemaData = { + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + }, + required: ['group_id'], +} as const satisfies JSONSchema; + +type Payload = FromSchema; + +export class GetGroupFileSystemInfo extends BaseAction { + actionName = ActionName.GoCQHTTP_GetGroupFileSystemInfo; + payloadSchema = SchemaData; + + async _handle(payload: Payload) { + return { + file_count: + (await this.core.apis.GroupApi + .getGroupFileCount([payload.group_id.toString()])) + .groupFileCounts[0], + limit_count: 10000, + used_space: 0, + total_space: 10 * 1024 * 1024 * 1024, + }; + } +} diff --git a/src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts b/src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts new file mode 100644 index 00000000..8a0fabe9 --- /dev/null +++ b/src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts @@ -0,0 +1,52 @@ +import { FromSchema, JSONSchema } from 'json-schema-to-ts'; +import BaseAction from '../BaseAction'; +import { ActionName } from '../types'; +import { NapCatOneBot11Adapter, OB11GroupFile } from '@/onebot'; +import { NapCatCore } from '@/core'; +import { GetGroupRootFiles } from '@/onebot/action/go-cqhttp/GetGroupRootFiles'; +import { OB11Entities } from '@/onebot/entities'; + +const SchemaData = { + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + folder_id: { type: 'string' }, + }, + required: ['group_id', 'folder_id'], +} as const satisfies JSONSchema; + +type Payload = FromSchema; + +export class GetGroupFilesByFolder extends BaseAction { + actionName = ActionName.GoCQHTTP_GetGroupFilesByFolder; + payloadSchema = SchemaData; + + constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore, + private getGroupRootFilesImpl: GetGroupRootFiles) { + super(obContext, core); + } + + async _handle(payload: Payload) { + const folder = (await this.getGroupRootFilesImpl._handle({ group_id: payload.group_id })) + .folders.find(folder => folder.folder_id === payload.folder_id); + if (!folder) { + throw new Error('Folder not found'); + } + const ret = await this.core.apis.MsgApi.getGroupFileList(payload.group_id.toString(), { + sortType: 1, + fileCount: folder.total_file_count, + startIndex: 0, + sortOrder: 2, + showOnlinedocFolder: 0, + folderId: payload.folder_id, + }).catch(() => []); + return { + files: ret.filter(item => item.fileInfo) + .map(item => OB11Entities.file(item.peerId, item.fileInfo!)), + folders: [] as [], + }; + } +} diff --git a/src/onebot/action/go-cqhttp/GetGroupRootFiles.ts b/src/onebot/action/go-cqhttp/GetGroupRootFiles.ts new file mode 100644 index 00000000..499a9abd --- /dev/null +++ b/src/onebot/action/go-cqhttp/GetGroupRootFiles.ts @@ -0,0 +1,47 @@ +import { FromSchema, JSONSchema } from 'json-schema-to-ts'; +import BaseAction from '../BaseAction'; +import { ActionName } from '../types'; +import { NapCatOneBot11Adapter, OB11GroupFile, OB11GroupFileFolder } from '@/onebot'; +import { NapCatCore } from '@/core'; +import { GetGroupFileCount } from '@/onebot/action/file/GetGroupFileCount'; +import { OB11Entities } from '@/onebot/entities'; + +const SchemaData = { + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + }, + required: ['group_id'], +} as const satisfies JSONSchema; + +type Payload = FromSchema; + +export class GetGroupRootFiles extends BaseAction { + actionName = ActionName.GoCQHTTP_GetGroupRootFiles; + payloadSchema = SchemaData; + + constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore, + private ncGetGroupFileCountImpl: GetGroupFileCount) { + super(obContext, core); + } + + async _handle(payload: Payload) { + const ret = await this.core.apis.MsgApi.getGroupFileList(payload.group_id.toString(), { + sortType: 1, + fileCount: (await this.ncGetGroupFileCountImpl._handle({ group_id: payload.group_id.toString() })).count, + startIndex: 0, + sortOrder: 2, + showOnlinedocFolder: 0, + }).catch(() => []); + + return { + files: ret.filter(item => item.fileInfo) + .map(item => OB11Entities.file(item.peerId, item.fileInfo!)), + folders: ret.filter(item => item.folderInfo) + .map(item => OB11Entities.folder(item.peerId, item.folderInfo!)), + }; + } +} diff --git a/src/onebot/action/index.ts b/src/onebot/action/index.ts index 4f32c38e..daab7552 100644 --- a/src/onebot/action/index.ts +++ b/src/onebot/action/index.ts @@ -82,10 +82,22 @@ import { SetInputStatus } from './extends/SetInputStatus'; import { GetCSRF } from './system/GetCSRF'; import { DelGroupNotice } from './group/DelGroupNotice'; import { GetGroupInfoEx } from './extends/GetGroupInfoEx'; +import { DeleteGroupFile } from '@/onebot/action/go-cqhttp/DeleteGroupFile'; +import { CreateGroupFileFolder } from '@/onebot/action/go-cqhttp/CreateGroupFileFolder'; +import { DeleteGroupFileFolder } from '@/onebot/action/go-cqhttp/DeleteGroupFileFolder'; +import { GetGroupFileSystemInfo } from '@/onebot/action/go-cqhttp/GetGroupFileSystemInfo'; +import { GetGroupRootFiles } from '@/onebot/action/go-cqhttp/GetGroupRootFiles'; +import { GetGroupFilesByFolder } from '@/onebot/action/go-cqhttp/GetGroupFilesByFolder'; export type ActionMap = Map>; export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore): ActionMap { + const ncDelGroupFile = new DelGroupFile(obContext, core); + const ncSetGroupFileFolder = new SetGroupFileFolder(obContext, core); + const ncDelGroupFileFolder = new DelGroupFileFolder(obContext, core); + const ncGetGroupFileCount = new GetGroupFileCount(obContext, core); + const goCqHttpGetGroupRootFiles = new GetGroupRootFiles(obContext, core, ncGetGroupFileCount); + const actionHandlers = [ new GetGroupInfoEx(obContext, core), new FetchEmojiLike(obContext, core), @@ -101,11 +113,11 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo new MarkPrivateMsgAsRead(obContext, core), new SetQQAvatar(obContext, core), new TranslateEnWordToZn(obContext, core), - new GetGroupFileCount(obContext, core), + ncGetGroupFileCount, new GetGroupFileList(obContext, core), - new SetGroupFileFolder(obContext, core), - new DelGroupFile(obContext, core), - new DelGroupFileFolder(obContext, core), + ncSetGroupFileFolder, + ncDelGroupFile, + ncDelGroupFileFolder, // onebot11 new SendLike(obContext, core), new GetMsg(obContext, core), @@ -173,6 +185,12 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo new SetInputStatus(obContext, core), new GetCSRF(obContext, core), new DelGroupNotice(obContext, core), + new DeleteGroupFile(obContext, core, ncDelGroupFile), + new CreateGroupFileFolder(obContext, core, ncSetGroupFileFolder), + new DeleteGroupFileFolder(obContext, core, ncDelGroupFileFolder), + new GetGroupFileSystemInfo(obContext, core), + goCqHttpGetGroupRootFiles, + new GetGroupFilesByFolder(obContext, core, goCqHttpGetGroupRootFiles), ]; const actionMap = new Map(); for (const action of actionHandlers) { diff --git a/src/onebot/action/types.ts b/src/onebot/action/types.ts index ea08c883..b8ccc078 100644 --- a/src/onebot/action/types.ts +++ b/src/onebot/action/types.ts @@ -83,6 +83,12 @@ export enum ActionName { MarkPrivateMsgAsRead = 'mark_private_msg_as_read', MarkGroupMsgAsRead = 'mark_group_msg_as_read', GoCQHTTP_UploadGroupFile = 'upload_group_file', + GOCQHTTP_DeleteGroupFile = 'delete_group_file', + GoCQHTTP_CreateGroupFileFolder = 'create_group_file_folder', + GoCQHTTP_DeleteGroupFileFolder = 'delete_group_file_folder', + GoCQHTTP_GetGroupFileSystemInfo = 'get_group_file_system_info', + GoCQHTTP_GetGroupRootFiles = 'get_group_root_files', + GoCQHTTP_GetGroupFilesByFolder = 'get_group_files_by_folder', GoCQHTTP_DownloadFile = 'download_file', GoCQHTTP_GetGroupMsgHistory = 'get_group_msg_history', GoCQHTTP_GetForwardMsg = 'get_forward_msg', diff --git a/src/onebot/entities.ts b/src/onebot/entities.ts index 516ea5e8..a043dd0d 100644 --- a/src/onebot/entities.ts +++ b/src/onebot/entities.ts @@ -1,6 +1,14 @@ -import { calcQQLevel } from '@/common/helper'; -import { Friend, FriendV2, Group, GroupMember, SelfInfo, Sex, User } from '@/core'; -import { OB11Group, OB11GroupMember, OB11GroupMemberRole, OB11User, OB11UserSex } from './types'; +import { calcQQLevel, FileNapCatOneBotUUID } from '@/common/helper'; +import { Friend, FriendV2, Group, GroupFileInfoUpdateParamType, GroupMember, SelfInfo, Sex, User } from '@/core'; +import { + OB11Group, + OB11GroupFile, + OB11GroupFileFolder, + OB11GroupMember, + OB11GroupMemberRole, + OB11User, + OB11UserSex, +} from './types'; export class OB11Entities { static selfInfo(selfInfo: SelfInfo): OB11User { @@ -97,4 +105,32 @@ export class OB11Entities { static groups(groups: Group[]): OB11Group[] { return groups.map(OB11Entities.group); } + + static file(peerId: string, file: Exclude): OB11GroupFile { + return { + group_id: parseInt(peerId), + file_id: FileNapCatOneBotUUID.encodeModelId({ chatType: 2, peerUid: peerId }, file.fileModelId), + file_name: file.fileName, + busid: file.busId, + size: parseInt(file.fileSize), + upload_time: file.uploadTime, + dead_time: file.deadTime, + modify_time: file.modifyTime, + download_times: file.downloadTimes, + uploader: parseInt(file.uploaderUin), + uploader_name: file.uploaderName, + }; + } + + static folder(peerId: string, folder: Exclude): OB11GroupFileFolder { + return { + group_id: parseInt(peerId), + folder_id: folder.folderId, + folder_name: folder.folderName, + create_time: folder.createTime, + creator: parseInt(folder.createUin), + creator_name: folder.creatorName, + total_file_count: folder.totalFileCount, + }; + } } diff --git a/src/onebot/types/entity.ts b/src/onebot/types/entity.ts index 279b2866..1356eb90 100644 --- a/src/onebot/types/entity.ts +++ b/src/onebot/types/entity.ts @@ -63,3 +63,27 @@ export interface OB11Sender { level?: string, // 群等级 role?: OB11GroupMemberRole } + +export interface OB11GroupFile { + group_id: number, + file_id: string, + file_name: string, + busid: number, + size: number, + upload_time: number, + dead_time: number, + modify_time: number, + download_times: number, + uploader: number, + uploader_name: string +} + +export interface OB11GroupFileFolder { + group_id: number, + folder_id: string, + folder_name: string, + create_time: number, + creator: number, + creator_name: string, + total_file_count: number, +}