mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
efc1875e35 | ||
![]() |
df063e6762 | ||
![]() |
e5c55b4339 | ||
![]() |
bee9095d6f | ||
![]() |
92f8eaaac9 | ||
![]() |
f5e7288fe5 | ||
![]() |
214aa7b6e4 | ||
![]() |
5b5d5b41f5 | ||
![]() |
23d613321e | ||
![]() |
0b6be0923f | ||
![]() |
aba748ea13 | ||
![]() |
f1f1ac582d | ||
![]() |
54a7cbc3f4 | ||
![]() |
2f4dbaec4c | ||
![]() |
578f518aaf | ||
![]() |
077ba74b22 | ||
![]() |
e0efe635c7 | ||
![]() |
1a06841de0 | ||
![]() |
3987e0ee0b | ||
![]() |
9f53bea02f | ||
![]() |
737709f9e7 | ||
![]() |
39477aa6a0 | ||
![]() |
f097050b56 | ||
![]() |
f14726ed1a | ||
![]() |
e1e4d038d9 | ||
![]() |
d2db4cf887 | ||
![]() |
2f3ece9ca3 |
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@@ -1,15 +1,11 @@
|
||||
name: "Build Action"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
Build-LiteLoader:
|
||||
if: ${{ startsWith(github.event.head_commit.message, 'build:') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone Main Repository
|
||||
@@ -37,7 +33,6 @@ jobs:
|
||||
name: NapCat.Framework
|
||||
path: dist
|
||||
Build-Shell:
|
||||
if: ${{ startsWith(github.event.head_commit.message, 'build:') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone Main Repository
|
||||
@@ -63,4 +58,4 @@ jobs:
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: NapCat.Shell
|
||||
path: dist
|
||||
path: dist
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"name": "NapCatQQ",
|
||||
"slug": "NapCat.Framework",
|
||||
"description": "高性能的 OneBot 11 协议实现",
|
||||
"version": "2.2.24",
|
||||
"version": "2.2.29",
|
||||
"icon": "./logo.png",
|
||||
"authors": [
|
||||
{
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"name": "napcat",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "2.2.24",
|
||||
"version": "2.2.29",
|
||||
"scripts": {
|
||||
"build:framework": "vite build --mode framework",
|
||||
"build:shell": "vite build --mode shell",
|
||||
|
@@ -23,29 +23,33 @@ export async function solveAsyncProblem<T extends (...args: any[]) => Promise<an
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export class FileNapCatOneBotUUID {
|
||||
static encodeModelId(peer: Peer, modelId: string): string {
|
||||
return `NapCatOneBot-ModeldFile-${peer.chatType}-${peer.peerUid}-${modelId}`;
|
||||
return `NapCatOneBot-ModelIdFile-${peer.chatType}-${peer.peerUid}-${modelId}`;
|
||||
}
|
||||
|
||||
static decodeModelId(uuid: string): undefined | {
|
||||
peer: Peer,
|
||||
modelId: string
|
||||
} {
|
||||
if (!uuid.startsWith('NapCatOneBot-ModeldFile-')) return undefined;
|
||||
if (!uuid.startsWith('NapCatOneBot-ModelIdFile-')) return undefined;
|
||||
const data = uuid.split('-');
|
||||
if (data.length !== 5) return undefined;
|
||||
const [, , chatType, peerUid, modelId] = data;
|
||||
return {
|
||||
peer: {
|
||||
chatType: chatType as any,
|
||||
peerUid: peerUid
|
||||
peerUid: peerUid,
|
||||
},
|
||||
modelId,
|
||||
};
|
||||
}
|
||||
|
||||
static encode(peer: Peer, msgId: string, elementId: string): string {
|
||||
return `NapCatOneBot-MsgFile-${peer.chatType}-${peer.peerUid}-${msgId}-${elementId}`;
|
||||
}
|
||||
|
||||
static decode(uuid: string): undefined | {
|
||||
peer: Peer,
|
||||
msgId: string,
|
||||
@@ -58,13 +62,14 @@ export class FileNapCatOneBotUUID {
|
||||
return {
|
||||
peer: {
|
||||
chatType: chatType as any,
|
||||
peerUid: peerUid
|
||||
peerUid: peerUid,
|
||||
},
|
||||
msgId,
|
||||
elementId,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
@@ -1 +1 @@
|
||||
export const napCatVersion = '2.2.24';
|
||||
export const napCatVersion = '2.2.29';
|
||||
|
@@ -17,7 +17,7 @@ import {
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import fsPromises from 'fs/promises';
|
||||
import { InstanceContext, NapCatCore } from '@/core';
|
||||
import { InstanceContext, NapCatCore, SearchResultItem } from '@/core';
|
||||
import * as fileType from 'file-type';
|
||||
import imageSize from 'image-size';
|
||||
import { ISizeCalculationResult } from 'image-size/dist/types/interface';
|
||||
@@ -308,10 +308,7 @@ export class NTQQFileApi {
|
||||
'NodeIKernelMsgListener/onRichMediaDownloadComplete',
|
||||
[peer, [modelId], unknown],
|
||||
() => true,
|
||||
(arg) => {
|
||||
console.log(arg);
|
||||
return arg?.commonFileInfo?.fileModelId === modelId
|
||||
},
|
||||
(arg) => arg?.commonFileInfo?.fileModelId === modelId,
|
||||
1,
|
||||
timeout,
|
||||
);
|
||||
@@ -356,15 +353,12 @@ export class NTQQFileApi {
|
||||
chatType: chatType,
|
||||
peerUid: peerUid,
|
||||
}, [msgId]);
|
||||
if (msg.msgList.length === 0) {
|
||||
return fileTransNotifyInfo.filePath;
|
||||
}
|
||||
const mixElement = msg.msgList.find((msg) => msg.msgId === msgId)?.elements.find((e) => e.elementId === elementId);
|
||||
const mixElementInner = mixElement?.videoElement ?? mixElement?.fileElement ?? mixElement?.pttElement ?? mixElement?.picElement;
|
||||
let realPath = mixElementInner?.filePath;
|
||||
if (!realPath) {
|
||||
let picThumbPath: Map<number, string> = (mixElementInner as any)?.picThumbPath;
|
||||
let picThumbPathList = Array.from(picThumbPath.values());
|
||||
const picThumbPath: Map<number, string> = (mixElementInner as any)?.picThumbPath;
|
||||
const picThumbPathList = Array.from(picThumbPath.values());
|
||||
if (picThumbPathList.length > 0) realPath = picThumbPathList[0];
|
||||
}
|
||||
return realPath;
|
||||
@@ -441,17 +435,44 @@ export class NTQQFileApi {
|
||||
});
|
||||
}
|
||||
|
||||
async searchfile(keys: string[]) {
|
||||
const Event = this.core.eventWrapper.createEventFunction('NodeIKernelSearchService/searchFileWithKeywords');
|
||||
const id = await Event!(keys, 12);
|
||||
const Listener = this.core.eventWrapper.registerListen(
|
||||
'NodeIKernelSearchListener/onSearchFileKeywordsResult',
|
||||
1,
|
||||
20000,
|
||||
(params) => id !== '' && params.searchId == id,
|
||||
async searchForFile(keys: string[]): Promise<SearchResultItem | undefined> {
|
||||
const randomResultId = 100000 + Math.floor(Math.random() * 10000);
|
||||
let searchId = 0;
|
||||
const [, searchResult] = await this.core.eventWrapper.callNormalEventV2(
|
||||
'NodeIKernelFileAssistantService/searchFile',
|
||||
'NodeIKernelFileAssistantListener/onFileSearch',
|
||||
[
|
||||
keys,
|
||||
{
|
||||
resultType: 2,
|
||||
pageLimit: 1,
|
||||
},
|
||||
randomResultId
|
||||
],
|
||||
(ret) => {
|
||||
searchId = ret;
|
||||
return true;
|
||||
},
|
||||
result => result.searchId === searchId && result.resultId === randomResultId,
|
||||
);
|
||||
const [ret] = (await Listener);
|
||||
return ret;
|
||||
return searchResult.resultItems[0];
|
||||
}
|
||||
|
||||
async downloadFileById(
|
||||
fileId: string,
|
||||
fileSize: number = 1024576,
|
||||
estimatedTime: number = (fileSize * 1000 / 1024576) + 5000,
|
||||
) {
|
||||
const [, ret] = await this.core.eventWrapper.callNormalEventV2(
|
||||
'NodeIKernelFileAssistantService/downloadFile',
|
||||
'NodeIKernelFileAssistantListener/onFileStatusChanged',
|
||||
[[fileId]],
|
||||
ret => ret.result === 0,
|
||||
status => status.fileStatus === 2 && status.fileProgress === '0',
|
||||
1,
|
||||
estimatedTime, // estimate 1MB/s
|
||||
);
|
||||
return ret.filePath!;
|
||||
}
|
||||
|
||||
async getImageUrl(element: PicElement) {
|
||||
|
@@ -2,7 +2,6 @@ import {
|
||||
ChatType,
|
||||
GeneralCallResult,
|
||||
Group,
|
||||
GroupInfoSource,
|
||||
GroupMember,
|
||||
GroupMemberRole,
|
||||
GroupRequestOperateTypes,
|
||||
@@ -402,7 +401,7 @@ export class NTQQGroupApi {
|
||||
|
||||
}
|
||||
|
||||
async GetGroupFileCount(Gids: Array<string>) {
|
||||
async getGroupFileCount(Gids: Array<string>) {
|
||||
return this.context.session.getRichMediaService().batchGetGroupFileCount(Gids);
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@ export interface GetFileListParam {
|
||||
startIndex: number;
|
||||
sortOrder: number;
|
||||
showOnlinedocFolder: number;
|
||||
folderId?: string;
|
||||
}
|
||||
|
||||
export enum ElementType {
|
||||
|
@@ -1,5 +1,13 @@
|
||||
export class NodeIKernelFileAssistantListener {
|
||||
onFileStatusChanged(...args: unknown[]) {
|
||||
onFileStatusChanged(fileStatus: {
|
||||
id: string,
|
||||
fileStatus: number,
|
||||
fileProgress: `${number}`,
|
||||
fileSize: `${number}`,
|
||||
fileSpeed: number,
|
||||
thumbPath: string | null,
|
||||
filePath: string | null,
|
||||
}) {
|
||||
}
|
||||
|
||||
onSessionListChanged(...args: unknown[]) {
|
||||
@@ -11,6 +19,42 @@ export class NodeIKernelFileAssistantListener {
|
||||
onFileListChanged(...args: unknown[]) {
|
||||
}
|
||||
|
||||
onFileSearch(...args: unknown[]) {
|
||||
onFileSearch(searchResult: SearchResultWrapper) {
|
||||
}
|
||||
}
|
||||
|
||||
export type SearchResultWrapper = {
|
||||
searchId: number,
|
||||
resultId: number,
|
||||
hasMore: boolean,
|
||||
resultItems: SearchResultItem[],
|
||||
};
|
||||
|
||||
export type SearchResultItem = {
|
||||
id: string,
|
||||
fileName: string,
|
||||
fileNameHits: string[],
|
||||
fileStatus: number,
|
||||
fileSize: string,
|
||||
isSend: boolean,
|
||||
source: number,
|
||||
fileTime: string,
|
||||
expTime: string,
|
||||
session: {
|
||||
context: null,
|
||||
uid: string,
|
||||
nick: string,
|
||||
remark: string,
|
||||
memberCard: string,
|
||||
groupCode: string,
|
||||
groupName: string,
|
||||
groupRemark: string,
|
||||
count: number,
|
||||
},
|
||||
thumbPath: string,
|
||||
filePath: string,
|
||||
msgId: string,
|
||||
chatType: number,
|
||||
peerUid: string,
|
||||
fileType: number,
|
||||
};
|
||||
|
@@ -29,7 +29,47 @@ export interface GroupFileInfoUpdateParamType {
|
||||
retMsg: string;
|
||||
clientWording: string;
|
||||
isEnd: boolean;
|
||||
item: Array<any>;
|
||||
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;
|
||||
|
@@ -1,15 +1,15 @@
|
||||
// @generated by protobuf-ts 2.9.4
|
||||
// @generated from protobuf file "EmojiLikeToOthers.proto" (package "SysMessage", syntax proto3)
|
||||
// tslint:disable
|
||||
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryWriter } from "@protobuf-ts/runtime";
|
||||
import { WireType } from "@protobuf-ts/runtime";
|
||||
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryReader } from "@protobuf-ts/runtime";
|
||||
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
|
||||
import type { PartialMessage } from "@protobuf-ts/runtime";
|
||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||
import { MessageType } from "@protobuf-ts/runtime";
|
||||
import type {
|
||||
BinaryReadOptions,
|
||||
BinaryWriteOptions,
|
||||
IBinaryReader,
|
||||
IBinaryWriter,
|
||||
PartialMessage,
|
||||
} from '@protobuf-ts/runtime';
|
||||
import { MessageType, reflectionMergePartial, UnknownFieldHandler, WireType } from '@protobuf-ts/runtime';
|
||||
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.EmojiLikeToOthersWrapper1
|
||||
*/
|
||||
|
@@ -1,15 +1,15 @@
|
||||
// @generated by protobuf-ts 2.9.4
|
||||
// @generated from protobuf file "GreyTipWrapper.proto" (package "SysMessage", syntax proto3)
|
||||
// tslint:disable
|
||||
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryWriter } from "@protobuf-ts/runtime";
|
||||
import { WireType } from "@protobuf-ts/runtime";
|
||||
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryReader } from "@protobuf-ts/runtime";
|
||||
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
|
||||
import type { PartialMessage } from "@protobuf-ts/runtime";
|
||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||
import { MessageType } from "@protobuf-ts/runtime";
|
||||
import type {
|
||||
BinaryReadOptions,
|
||||
BinaryWriteOptions,
|
||||
IBinaryReader,
|
||||
IBinaryWriter,
|
||||
PartialMessage,
|
||||
} from '@protobuf-ts/runtime';
|
||||
import { MessageType, reflectionMergePartial, UnknownFieldHandler, WireType } from '@protobuf-ts/runtime';
|
||||
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.GreyTipWrapper
|
||||
*/
|
||||
|
@@ -1,15 +1,15 @@
|
||||
// @generated by protobuf-ts 2.9.4
|
||||
// @generated from protobuf file "SysMessage.proto" (package "SysMessage", syntax proto3)
|
||||
// tslint:disable
|
||||
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryWriter } from "@protobuf-ts/runtime";
|
||||
import { WireType } from "@protobuf-ts/runtime";
|
||||
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryReader } from "@protobuf-ts/runtime";
|
||||
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
|
||||
import type { PartialMessage } from "@protobuf-ts/runtime";
|
||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||
import { MessageType } from "@protobuf-ts/runtime";
|
||||
import type {
|
||||
BinaryReadOptions,
|
||||
BinaryWriteOptions,
|
||||
IBinaryReader,
|
||||
IBinaryWriter,
|
||||
PartialMessage,
|
||||
} from '@protobuf-ts/runtime';
|
||||
import { MessageType, reflectionMergePartial, UnknownFieldHandler, WireType } from '@protobuf-ts/runtime';
|
||||
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.SysMessage
|
||||
*/
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import { NodeIKernelFileAssistantListener } from '@/core';
|
||||
|
||||
export interface NodeIKernelFileAssistantService {
|
||||
addKernelFileAssistantListener(arg1: unknown[]): unknown;
|
||||
addKernelFileAssistantListener(listener: NodeIKernelFileAssistantListener): unknown;
|
||||
|
||||
removeKernelFileAssistantListener(arg1: unknown[]): unknown;
|
||||
|
||||
@@ -9,7 +11,7 @@ export interface NodeIKernelFileAssistantService {
|
||||
|
||||
getFileSessionList(): unknown;
|
||||
|
||||
searchFile(arg1: unknown, arg2: unknown, arg3: unknown): unknown;
|
||||
searchFile(keywords: string[], params: { resultType: number, pageLimit: number }, resultId: number): number;
|
||||
|
||||
resetSearchFileSortType(arg1: unknown, arg2: unknown, arg3: unknown): unknown;
|
||||
|
||||
@@ -17,7 +19,7 @@ export interface NodeIKernelFileAssistantService {
|
||||
|
||||
cancelSearchFile(arg1: unknown, arg2: unknown, arg3: unknown): unknown;
|
||||
|
||||
downloadFile(arg1: unknown[]): unknown;
|
||||
downloadFile(fileIds: string[]): { result: number, errMsg: string };
|
||||
|
||||
forwardFile(arg1: unknown, arg2: unknown, arg3: unknown): unknown;
|
||||
|
||||
@@ -32,4 +34,4 @@ export interface NodeIKernelFileAssistantService {
|
||||
saveAsWithRename(arg1: unknown, arg2: unknown, arg3: unknown): unknown;
|
||||
|
||||
isNull(): boolean;
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,7 @@ import { NapCatPathWrapper } from '@/common/path';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { proxiedListenerOf } from '@/common/proxy-handler';
|
||||
import { QQBasicInfoWrapper } from '@/common/qq-basic-info';
|
||||
import { loadQQWrapper, NapCatCore, NapCatCoreWorkingEnv } from '@/core';
|
||||
import { InstanceContext } from '@/core';
|
||||
import { InstanceContext, loadQQWrapper, NapCatCore, NapCatCoreWorkingEnv } from '@/core';
|
||||
import { SelfInfo } from '@/core/entities';
|
||||
import { NodeIKernelLoginListener } from '@/core/listeners';
|
||||
import { NodeIKernelLoginService } from '@/core/services';
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { createServer } from 'node:net';
|
||||
|
||||
export class NewAdapterNetwork {
|
||||
constructor(public host: number, public port: number) { }
|
||||
async open() {
|
||||
@@ -11,8 +12,8 @@ export class NewAdapterNetwork {
|
||||
});
|
||||
socket.on('connect', () => {
|
||||
|
||||
})
|
||||
});
|
||||
});
|
||||
server.listen(this.port, this.host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,10 +7,10 @@ const SchemaData = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
status: { type: ['number', 'string'] },
|
||||
extStatus: { type: ['number', 'string'] },
|
||||
batteryStatus: { type: ['number', 'string'] },
|
||||
ext_status: { type: ['number', 'string'] },
|
||||
battery_status: { type: ['number', 'string'] },
|
||||
},
|
||||
required: ['status', 'extStatus', 'batteryStatus'],
|
||||
required: ['status', 'ext_status', 'battery_status'],
|
||||
} as const satisfies JSONSchema;
|
||||
|
||||
type Payload = FromSchema<typeof SchemaData>;
|
||||
@@ -23,8 +23,8 @@ export class SetOnlineStatus extends BaseAction<Payload, null> {
|
||||
const NTQQUserApi = this.core.apis.UserApi;
|
||||
const ret = await NTQQUserApi.setSelfOnlineStatus(
|
||||
parseInt(payload.status.toString()),
|
||||
parseInt(payload.extStatus.toString()),
|
||||
parseInt(payload.batteryStatus.toString()),
|
||||
parseInt(payload.ext_status.toString()),
|
||||
parseInt(payload.battery_status.toString()),
|
||||
);
|
||||
if (ret.result !== 0) {
|
||||
throw new Error('设置在线状态失败');
|
||||
|
@@ -2,7 +2,6 @@ import BaseAction from '../BaseAction';
|
||||
import fs from 'fs/promises';
|
||||
import { FileNapCatOneBotUUID } from '@/common/helper';
|
||||
import { ActionName } from '../types';
|
||||
import { ChatType, Peer, RawMessage } from '@/core/entities';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
||||
export interface GetFilePayload {
|
||||
@@ -32,8 +31,8 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
||||
const NTQQMsgApi = this.core.apis.MsgApi;
|
||||
const NTQQFileApi = this.core.apis.FileApi;
|
||||
|
||||
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file);
|
||||
//接收消息标记模式
|
||||
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file);
|
||||
if (contextMsgFile) {
|
||||
const { peer, msgId, elementId } = contextMsgFile;
|
||||
const downloadPath = await NTQQFileApi.downloadMedia(msgId, peer.chatType, peer.peerUid, elementId, '', '');
|
||||
@@ -60,11 +59,12 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//群文件模式
|
||||
const contextModelIdFile = FileNapCatOneBotUUID.decodeModelId(payload.file);
|
||||
if (contextModelIdFile) {
|
||||
const { peer, modelId } = contextModelIdFile;
|
||||
const downloadPath = await NTQQFileApi.downloadFileForModelId(peer, modelId,'');
|
||||
const downloadPath = await NTQQFileApi.downloadFileForModelId(peer, modelId, '');
|
||||
const res: GetFileResponse = {
|
||||
file: downloadPath,
|
||||
url: downloadPath,
|
||||
@@ -83,29 +83,14 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
||||
}
|
||||
|
||||
//搜索名字模式
|
||||
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
||||
if (NTSearchNameResult.length !== 0) {
|
||||
const MsgId = NTSearchNameResult[0].msgId;
|
||||
let peer: Peer | undefined = undefined;
|
||||
if (NTSearchNameResult[0].chatType == ChatType.KCHATTYPEGROUP) {
|
||||
peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: NTSearchNameResult[0].groupChatInfo[0].groupCode };
|
||||
}
|
||||
if (!peer) throw new Error('chattype not support');
|
||||
const msgList: RawMessage[] = (await NTQQMsgApi.getMsgsByMsgId(peer, [MsgId]))?.msgList;
|
||||
if (!msgList || msgList.length == 0) {
|
||||
throw new Error('msg not found');
|
||||
}
|
||||
const msg = msgList[0];
|
||||
const file = msg.elements.filter(e => e.elementType == NTSearchNameResult[0].elemType);
|
||||
if (file.length == 0) {
|
||||
throw new Error('file not found');
|
||||
}
|
||||
const downloadPath = await NTQQFileApi.downloadMedia(msg.msgId, msg.chatType, msg.peerUid, file[0].elementId, '', '');
|
||||
const searchResult = (await NTQQFileApi.searchForFile([payload.file]));
|
||||
if (searchResult) {
|
||||
const downloadPath = await NTQQFileApi.downloadFileById(searchResult.id, parseInt(searchResult.fileSize));
|
||||
const res: GetFileResponse = {
|
||||
file: downloadPath,
|
||||
url: downloadPath,
|
||||
file_size: NTSearchNameResult[0].fileSize.toString(),
|
||||
file_name: NTSearchNameResult[0].fileName,
|
||||
file_size: searchResult.fileSize.toString(),
|
||||
file_name: searchResult.fileName,
|
||||
};
|
||||
if (this.obContext.configLoader.configData.enableLocalFile2Url && downloadPath) {
|
||||
try {
|
||||
|
@@ -17,8 +17,7 @@ export class GetGroupFileCount extends BaseAction<Payload, { count: number }> {
|
||||
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] };
|
||||
}
|
||||
}
|
||||
|
@@ -35,15 +35,16 @@ export class GetGroupFileList extends BaseAction<Payload, { FileList: Array<any>
|
||||
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 };
|
||||
}
|
||||
|
32
src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts
Normal file
32
src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts
Normal file
@@ -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<typeof SchemaData>;
|
||||
|
||||
export class CreateGroupFileFolder extends BaseAction<Payload, null> {
|
||||
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;
|
||||
}
|
||||
}
|
32
src/onebot/action/go-cqhttp/DeleteGroupFile.ts
Normal file
32
src/onebot/action/go-cqhttp/DeleteGroupFile.ts
Normal file
@@ -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<typeof SchemaData>;
|
||||
|
||||
export class DeleteGroupFile extends BaseAction<Payload, null> {
|
||||
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;
|
||||
}
|
||||
}
|
32
src/onebot/action/go-cqhttp/DeleteGroupFileFolder.ts
Normal file
32
src/onebot/action/go-cqhttp/DeleteGroupFileFolder.ts
Normal file
@@ -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<typeof SchemaData>;
|
||||
|
||||
export class DeleteGroupFileFolder extends BaseAction<Payload, null> {
|
||||
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;
|
||||
}
|
||||
}
|
35
src/onebot/action/go-cqhttp/GetGroupFileSystemInfo.ts
Normal file
35
src/onebot/action/go-cqhttp/GetGroupFileSystemInfo.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
group_id: { type: ['string', 'number'] },
|
||||
},
|
||||
required: ['group_id'],
|
||||
} as const satisfies JSONSchema;
|
||||
|
||||
type Payload = FromSchema<typeof SchemaData>;
|
||||
|
||||
export class GetGroupFileSystemInfo extends BaseAction<Payload, {
|
||||
file_count: number,
|
||||
limit_count: number, // unimplemented
|
||||
used_space: number, // todo: unimplemented, but can be implemented later
|
||||
total_space: number, // unimplemented, 10 GB by default
|
||||
}> {
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
52
src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts
Normal file
52
src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts
Normal file
@@ -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<typeof SchemaData>;
|
||||
|
||||
export class GetGroupFilesByFolder extends BaseAction<Payload, {
|
||||
files: OB11GroupFile[],
|
||||
folders: [] // QQ does not allow nested folders
|
||||
}> {
|
||||
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 [],
|
||||
};
|
||||
}
|
||||
}
|
47
src/onebot/action/go-cqhttp/GetGroupRootFiles.ts
Normal file
47
src/onebot/action/go-cqhttp/GetGroupRootFiles.ts
Normal file
@@ -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<typeof SchemaData>;
|
||||
|
||||
export class GetGroupRootFiles extends BaseAction<Payload, {
|
||||
files: OB11GroupFile[],
|
||||
folders: OB11GroupFileFolder[],
|
||||
}> {
|
||||
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!)),
|
||||
};
|
||||
}
|
||||
}
|
@@ -31,18 +31,18 @@ class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> {
|
||||
NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache),
|
||||
NTQQUserApi.getUserDetailInfo(uid),
|
||||
]);
|
||||
if (member.status !== 'fulfilled') throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在 ${member.reason}`);
|
||||
if (member.status !== 'fulfilled') throw new Error(`群(${payload.group_id})成员${payload.user_id}获取失败 ${member.reason}`);
|
||||
if (!member.value) throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在`);
|
||||
if (info.status === 'fulfilled') {
|
||||
this.core.context.logger.logDebug('群成员详细信息结果', info.value);
|
||||
Object.assign(member, info.value);
|
||||
Object.assign(member.value, info.value);
|
||||
} else {
|
||||
this.core.context.logger.logDebug(`获取群成员详细信息失败, 只能返回基础信息 ${info.reason}`);
|
||||
}
|
||||
const date = Math.round(Date.now() / 1000);
|
||||
const retMember = OB11Entities.groupMember(payload.group_id.toString(), member.value as GroupMember);
|
||||
const Member = await this.core.apis.GroupApi.getGroupMember(payload.group_id.toString(), retMember.user_id);
|
||||
retMember.last_sent_time = parseInt(Member?.lastSpeakTime || date.toString());
|
||||
retMember.join_time = parseInt(Member?.joinTime || date.toString());
|
||||
retMember.last_sent_time = parseInt(Member?.lastSpeakTime ?? date.toString());
|
||||
retMember.join_time = parseInt(Member?.joinTime ?? date.toString());
|
||||
return retMember;
|
||||
}
|
||||
}
|
||||
|
@@ -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<string, BaseAction<any, any>>;
|
||||
|
||||
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) {
|
||||
|
@@ -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',
|
||||
|
@@ -18,6 +18,7 @@ import { OB11GroupUploadNoticeEvent } from '@/onebot/event/notice/OB11GroupUploa
|
||||
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';
|
||||
|
||||
export class OneBotGroupApi {
|
||||
obContext: NapCatOneBot11Adapter;
|
||||
@@ -76,7 +77,10 @@ export class OneBotGroupApi {
|
||||
this.core,
|
||||
parseInt(msg.peerUid), parseInt(msg.senderUin || ''),
|
||||
{
|
||||
id: element.fileElement.fileUuid!,
|
||||
id: FileNapCatOneBotUUID.encode({
|
||||
chatType: ChatType.KCHATTYPEGROUP,
|
||||
peerUid: msg.peerUid,
|
||||
}, msg.msgId, element.elementId),
|
||||
name: element.fileElement.fileName,
|
||||
size: parseInt(element.fileElement.fileSize),
|
||||
busid: element.fileElement.fileBizId || 0,
|
||||
@@ -124,8 +128,8 @@ export class OneBotGroupApi {
|
||||
peerUid: Group,
|
||||
};
|
||||
const msgData = await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true);
|
||||
let msgList = (await this.core.apis.WebApi.getGroupEssenceMsgAll(Group)).flatMap((e) => e.data.msg_list);
|
||||
let realMsg = msgList.find((e) => e.msg_seq.toString() == msgSeq);
|
||||
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),
|
||||
|
@@ -9,7 +9,8 @@ import {
|
||||
FaceType,
|
||||
IdMusicSignPostData,
|
||||
MessageElement,
|
||||
NapCatCore, NTGrayTipElementSubTypeV2,
|
||||
NapCatCore,
|
||||
NTGrayTipElementSubTypeV2,
|
||||
Peer,
|
||||
RawMessage,
|
||||
SendMessageElement,
|
||||
|
@@ -10,12 +10,12 @@ import {
|
||||
QuickActionGroupMessage,
|
||||
QuickActionGroupRequest,
|
||||
} from '@/onebot';
|
||||
import { ChatType, GroupRequestOperateTypes, NapCatCore, Peer } from '@/core';
|
||||
import { GroupRequestOperateTypes, NapCatCore, Peer } from '@/core';
|
||||
import { OB11FriendRequestEvent } from '@/onebot/event/request/OB11FriendRequest';
|
||||
import { OB11GroupRequestEvent } from '@/onebot/event/request/OB11GroupRequest';
|
||||
import { ContextMode, normalize } from '@/onebot/action/msg/SendMsg';
|
||||
import { ContextMode, createContext, normalize } from '@/onebot/action/msg/SendMsg';
|
||||
import { isNull } from '@/common/helper';
|
||||
import { createContext } from '@/onebot/action/msg/SendMsg';
|
||||
|
||||
export class OneBotQuickActionApi {
|
||||
constructor(
|
||||
public obContext: NapCatOneBot11Adapter,
|
||||
@@ -78,7 +78,7 @@ export class OneBotQuickActionApi {
|
||||
sendElements,
|
||||
deleteAfterSentFiles,
|
||||
} = await this.obContext.apis.MsgApi.createSendElements(replyMessage, peer);
|
||||
this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(peer, sendElements, deleteAfterSentFiles, false).then().catch(this.core.context.logger.logError);
|
||||
this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(peer, sendElements, deleteAfterSentFiles, false).then().catch(this.core.context.logger.logError.bind(this.core.context.logger));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,13 +88,13 @@ export class OneBotQuickActionApi {
|
||||
request.flag,
|
||||
quickAction.approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject,
|
||||
quickAction.reason,
|
||||
).catch(this.core.context.logger.logError);
|
||||
).catch(this.core.context.logger.logError.bind(this.core.context.logger));
|
||||
}
|
||||
}
|
||||
|
||||
async handleFriendRequest(request: OB11FriendRequestEvent, quickAction: QuickActionFriendRequest) {
|
||||
if (!isNull(quickAction.approve)) {
|
||||
this.core.apis.FriendApi.handleFriendRequest(request.flag, !!quickAction.approve).then().catch(this.core.context.logger.logError);
|
||||
this.core.apis.FriendApi.handleFriendRequest(request.flag, !!quickAction.approve).then().catch(this.core.context.logger.logError.bind(this.core.context.logger));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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<GroupFileInfoUpdateParamType['item'][0]['fileInfo'], undefined>): 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<GroupFileInfoUpdateParamType['item'][0]['folderInfo'], undefined>): 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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -139,7 +139,7 @@ export class NapCatOneBot11Adapter {
|
||||
|
||||
initRecentContactListener() {
|
||||
const recentContactListener = new NodeIKernelRecentContactListener();
|
||||
recentContactListener.onRecentContactNotification = function(msgList: any[] /* arg0: { msgListUnreadCnt: string }, arg1: number */) {
|
||||
recentContactListener.onRecentContactNotification = function (msgList: any[] /* arg0: { msgListUnreadCnt: string }, arg1: number */) {
|
||||
msgList.forEach((msg) => {
|
||||
if (msg.chatType == ChatType.KCHATTYPEGROUP) {
|
||||
// log("recent contact", msgList, arg0, arg1);
|
||||
@@ -248,7 +248,7 @@ export class NapCatOneBot11Adapter {
|
||||
return;
|
||||
}
|
||||
const { msgType, subType, subSubType } = sysMsg.msgSpec[0];
|
||||
if (msgType === 732 && subType === 16 && subSubType === 16 ) {
|
||||
if (msgType === 732 && subType === 16 && subSubType === 16) {
|
||||
const greyTip = GreyTipWrapper.fromBinary(Uint8Array.from(sysMsg.bodyWrapper!.wrappedBody.slice(7)));
|
||||
if (greyTip.subTypeId === 36) {
|
||||
const emojiLikeToOthers = EmojiLikeToOthersWrapper1
|
||||
@@ -371,7 +371,7 @@ export class NapCatOneBot11Adapter {
|
||||
|
||||
private initGroupListener() {
|
||||
const groupListener = new NodeIKernelGroupListener();
|
||||
|
||||
|
||||
groupListener.onGroupNotifiesUpdated = async (_, notifies) => {
|
||||
//console.log('ob11 onGroupNotifiesUpdated', notifies[0]);
|
||||
await this.core.apis.GroupApi.clearGroupNotifiesUnreadCount(false);
|
||||
@@ -473,6 +473,18 @@ export class NapCatOneBot11Adapter {
|
||||
);
|
||||
this.networkManager.emitEvent(groupInviteEvent)
|
||||
.catch(e => this.context.logger.logError('处理邀请本人加群失败', e));
|
||||
} else if (notify.type == GroupNotifyMsgType.INVITED_NEED_ADMINI_STRATOR_PASS && notify.status == GroupNotifyMsgStatus.KUNHANDLE) {
|
||||
this.context.logger.logDebug(`收到群员邀请加群通知:${notify}`);
|
||||
const groupInviteEvent = new OB11GroupRequestEvent(
|
||||
this.core,
|
||||
parseInt(notify.group.groupCode),
|
||||
parseInt(await this.core.apis.UserApi.getUinByUidV2(notify.user1.uid)),
|
||||
'add',
|
||||
notify.postscript,
|
||||
flag,
|
||||
);
|
||||
this.networkManager.emitEvent(groupInviteEvent)
|
||||
.catch(e => this.context.logger.logError('处理邀请本人加群失败', e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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,
|
||||
}
|
||||
|
@@ -5,8 +5,8 @@ import { NodeIKernelLoginListener, NodeIKernelSessionListener } from '@/core/lis
|
||||
import { NodeIDependsAdapter, NodeIDispatcherAdapter, NodeIGlobalAdapter } from '@/core/adapters';
|
||||
import { NapCatPathWrapper } from '@/common/path';
|
||||
import {
|
||||
InstanceContext,
|
||||
genSessionConfig,
|
||||
InstanceContext,
|
||||
loadQQWrapper,
|
||||
NapCatCore,
|
||||
NapCatCoreWorkingEnv,
|
||||
|
@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
undefined,
|
||||
SettingButton('V2.2.24', 'napcat-update-button', 'secondary'),
|
||||
SettingButton('V2.2.29', 'napcat-update-button', 'secondary'),
|
||||
),
|
||||
]),
|
||||
SettingList([
|
||||
|
@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
void 0,
|
||||
SettingButton("V2.2.24", "napcat-update-button", "secondary")
|
||||
SettingButton("V2.2.29", "napcat-update-button", "secondary")
|
||||
)
|
||||
]),
|
||||
SettingList([
|
||||
|
Reference in New Issue
Block a user