Compare commits

..

51 Commits

Author SHA1 Message Date
手瓜一十雪
f8260067ab Merge pull request #944 from clansty/fix/isReverseOrder
fix: isReverseOrder
2025-04-14 21:44:42 +08:00
手瓜一十雪
40b06daf1e fix 2025-04-14 21:44:25 +08:00
手瓜一十雪
e30915a06b Merge pull request #946 from NapNeko/fix-923
feat: 区分resId和普通消息Id
2025-04-14 19:05:01 +08:00
手瓜一十雪
2ab3898d28 readme: new 2025-04-14 13:25:00 +08:00
Clansty
6e38e748b8 fix: isReverseOrder 2025-04-14 05:40:11 +08:00
手瓜一十雪
7ecdd63bef feat: 区分resId和普通消息Id 2025-04-13 20:33:25 +08:00
手瓜一十雪
8056962203 Merge pull request #943 from NapNeko/zod-refactor
fix: 修掉漏掉的
2025-04-13 20:17:08 +08:00
手瓜一十雪
7a42f8c26f fix: 修掉漏掉的 2025-04-13 20:14:35 +08:00
手瓜一十雪
6c510e42e8 Merge pull request #942 from NapNeko/zod-refactor
迁移类型校验到zod
2025-04-13 20:10:43 +08:00
手瓜一十雪
45d6ebf084 package->dev 2025-04-13 20:06:30 +08:00
手瓜一十雪
2147c4ffee 迁移类型校验到zod 2025-04-13 20:05:11 +08:00
Mlikiowa
d4ab191f34 release: v4.7.19 2025-04-12 04:25:39 +00:00
手瓜一十雪
a5e53a713b feat: 增强win 输出可读性 2025-04-12 12:23:38 +08:00
Mlikiowa
e3f965a9d6 release: v4.7.18 2025-04-12 04:04:09 +00:00
手瓜一十雪
dd00d4c8a5 fix: 小问题 2025-04-12 11:59:29 +08:00
手瓜一十雪
4d292a75fa fix 2025-04-12 11:36:46 +08:00
pk5ls20
50b6733f57 Merge pull request #938 from Fahaxikiii/patch-2
Update README.md
2025-04-12 00:11:23 +08:00
万里
19479b4b3c Update README.md
换成美国vps
2025-04-12 00:09:19 +08:00
pk5ls20
540f58d8ec Merge pull request #937 from Fahaxikiii/patch-1 2025-04-11 23:18:46 +08:00
万里
749f1dfcf9 Update README.md
服务器到期了呜呜呜
2025-04-11 22:03:28 +08:00
Mlikiowa
176691bb96 release: v4.7.17 2025-04-11 07:12:53 +00:00
手瓜一十雪
b9ec8ac9b1 feat: LL Framework适配 2025-04-11 15:12:32 +08:00
手瓜一十雪
28d973b9cb Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2025-04-11 14:40:31 +08:00
手瓜一十雪
a6be54937c feat: 删掉不必要的启动脚本 2025-04-11 14:40:22 +08:00
Mlikiowa
0664b9af84 release: v4.7.16 2025-04-11 06:21:19 +00:00
手瓜一十雪
407d8d1fd2 feat: 34231 2025-04-11 14:20:27 +08:00
手瓜一十雪
108897f6ad feat: shell 能力 launcher-user-34231 2025-04-11 14:18:12 +08:00
手瓜一十雪
3d2decb0ec feat: 34231 2025-04-11 12:47:25 +08:00
Mlikiowa
386b884f1b release: v4.7.15 2025-04-10 11:00:12 +00:00
手瓜一十雪
ace4da2297 fix: rkey server部署 2025-04-10 18:59:49 +08:00
Mlikiowa
a8fb48fb50 release: v4.7.14 2025-04-10 10:55:24 +00:00
手瓜一十雪
61f065c0c6 feat: rkey标准化&rkey server增强&简化rkey端部署 2025-04-10 18:54:18 +08:00
手瓜一十雪
d6cf6d120a feat: group_all_shut 2025-04-10 09:00:00 +08:00
手瓜一十雪
c20c19d8e0 feat: 更新类型 fetchUserDetailInfo 2025-04-08 10:12:18 +08:00
手瓜一十雪
bd8bbf76ab feat: moveGroupFile 2025-04-08 09:42:28 +08:00
手瓜一十雪
faccff1834 Merge pull request #927 from NapNeko/dependabot/npm_and_yarn/vite-plugin-cp-6.0.0
chore(deps-dev): bump vite-plugin-cp from 4.0.8 to 6.0.0
2025-04-08 09:19:58 +08:00
手瓜一十雪
99d3c5a117 Merge pull request #930 from clansty/feat/gfs
增加更多群文件相关功能
2025-04-08 09:19:41 +08:00
Clansty
31eb09edef feat: 重命名群文件 2025-04-08 05:14:53 +08:00
Clansty
4180c2d754 feat: 群文件转存永久 2025-04-08 04:40:34 +08:00
Clansty
68f5deedff feat: 移动群文件 2025-04-08 02:48:48 +08:00
dependabot[bot]
9f72196414 chore(deps-dev): bump vite-plugin-cp from 4.0.8 to 6.0.0
Bumps [vite-plugin-cp](https://github.com/fengxinming/vite-plugins/tree/HEAD/packages/vite-plugin-cp) from 4.0.8 to 6.0.0.
- [Commits](https://github.com/fengxinming/vite-plugins/commits/HEAD/packages/vite-plugin-cp)

---
updated-dependencies:
- dependency-name: vite-plugin-cp
  dependency-version: 6.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 09:33:04 +00:00
手瓜一十雪
b32efa9131 fix: 更新逻辑 2025-04-05 11:45:21 +08:00
pk5ls20
3cf502fea3 chore: improve log output for protocol fetch with multiple messages 2025-04-04 01:59:31 +08:00
手瓜一十雪
863a953ae1 style: lint 2025-04-03 15:06:34 +08:00
手瓜一十雪
a44104d8f7 Update OneBotAction.ts 2025-04-03 15:03:00 +08:00
手瓜一十雪
f602bbb0cf fix: 启用类型强制转换 2025-04-03 14:52:33 +08:00
手瓜一十雪
2807ff5927 fix: 刷新群头衔缓存 2025-04-03 14:46:56 +08:00
手瓜一十雪
4fb8e6a4da fix: typo 2025-04-03 14:44:59 +08:00
手瓜一十雪
7ec61f089d fix 2025-04-02 21:40:10 +08:00
手瓜一十雪
f7a500a8cf feat: GroupMemberTitle 2025-04-02 21:30:25 +08:00
Mlikiowa
2b319bd694 release: v4.7.13 2025-04-02 04:05:02 +00:00
125 changed files with 1499 additions and 1008 deletions

View File

@@ -37,7 +37,7 @@ _Modern protocol-side framework implemented based on NTQQ._
| Docs | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) | | Docs | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) |
|:-:|:-:|:-:|:-:| |:-:|:-:|:-:|:-:|
| Docs | [![Cloudflare.Pages](https://img.shields.io/badge/docs%20on-Cloudflare.Pages-blue)](https://napneko.pages.dev/) | [![Server.Other](https://img.shields.io/badge/docs%20on-Server.Other-green)](https://docs.napcat.cyou/) | [![NapCat.Wiki](https://img.shields.io/badge/docs%20on-NapCat.Wiki-red)](https://www.napcat.wiki) | | Docs | [![Cloudflare.Pages](https://img.shields.io/badge/docs%20on-Cloudflare.Pages-blue)](https://napneko.pages.dev/) | [![Server.Other](https://img.shields.io/badge/docs%20on-Server.Other-green)](https://napcat.cyou/) | [![NapCat.Wiki](https://img.shields.io/badge/docs%20on-NapCat.Wiki-red)](https://www.napcat.wiki) |
|:-:|:-:|:-:|:-:| |:-:|:-:|:-:|:-:|
| Contact | [![QQ Group#1](https://img.shields.io/badge/QQ%20Group%231-Join-blue)](https://qm.qq.com/q/I6LU87a0Yq) | [![QQ Group#2](https://img.shields.io/badge/QQ%20Group%232-Join-blue)](https://qm.qq.com/q/HaRcfrHpUk) | [![Telegram](https://img.shields.io/badge/Telegram-MelodicMoonlight-blue)](https://t.me/MelodicMoonlight) | | Contact | [![QQ Group#1](https://img.shields.io/badge/QQ%20Group%231-Join-blue)](https://qm.qq.com/q/I6LU87a0Yq) | [![QQ Group#2](https://img.shields.io/badge/QQ%20Group%232-Join-blue)](https://qm.qq.com/q/HaRcfrHpUk) | [![Telegram](https://img.shields.io/badge/Telegram-MelodicMoonlight-blue)](https://t.me/MelodicMoonlight) |
@@ -47,8 +47,6 @@ _Modern protocol-side framework implemented based on NTQQ._
+ [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持 参考部分代码 已获授权 + [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持 参考部分代码 已获授权
+ [LLOneBot](https://github.com/LLOneBot/LLOneBot) 相关的开发曾参与本项目部分开发
+ 不过最最重要的 还是需要感谢屏幕前的你哦~ + 不过最最重要的 还是需要感谢屏幕前的你哦~
--- ---
@@ -60,3 +58,7 @@ _Modern protocol-side framework implemented based on NTQQ._
2. 项目其余逻辑代码采用[本仓库开源许可](./LICENSE). 2. 项目其余逻辑代码采用[本仓库开源许可](./LICENSE).
**本仓库仅用于提高易用性,实现消息推送类功能,此外,禁止任何项目未经仓库主作者授权基于 NapCat 代码开发。使用请遵守当地法律法规,由此造成的问题由使用者和提供违规使用教程者负责。** **本仓库仅用于提高易用性,实现消息推送类功能,此外,禁止任何项目未经仓库主作者授权基于 NapCat 代码开发。使用请遵守当地法律法规,由此造成的问题由使用者和提供违规使用教程者负责。**
## Warnings
[某框架抄袭部分分析](https://napneko.github.io/other/about-copy)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -4,7 +4,7 @@
"name": "NapCatQQ", "name": "NapCatQQ",
"slug": "NapCat.Framework", "slug": "NapCat.Framework",
"description": "高性能的 OneBot 11 协议实现", "description": "高性能的 OneBot 11 协议实现",
"version": "4.7.12", "version": "4.7.19",
"icon": "./logo.png", "icon": "./logo.png",
"authors": [ "authors": [
{ {

View File

@@ -2,7 +2,7 @@
"name": "napcat", "name": "napcat",
"private": true, "private": true,
"type": "module", "type": "module",
"version": "4.7.12", "version": "4.7.19",
"scripts": { "scripts": {
"build:universal": "npm run build:webui && vite build --mode universal || exit 1", "build:universal": "npm run build:webui && vite build --mode universal || exit 1",
"build:framework": "npm run build:webui && vite build --mode framework || exit 1", "build:framework": "npm run build:webui && vite build --mode framework || exit 1",
@@ -27,7 +27,6 @@
"@napneko/nap-proto-core": "^0.0.4", "@napneko/nap-proto-core": "^0.0.4",
"@rollup/plugin-node-resolve": "^16.0.0", "@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-typescript": "^12.1.2", "@rollup/plugin-typescript": "^12.1.2",
"@sinclair/typebox": "^0.34.9",
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
"@types/express": "^5.0.0", "@types/express": "^5.0.0",
"@types/multer": "^1.4.12", "@types/multer": "^1.4.12",
@@ -39,9 +38,9 @@
"@types/ws": "^8.5.12", "@types/ws": "^8.5.12",
"@typescript-eslint/eslint-plugin": "^8.3.0", "@typescript-eslint/eslint-plugin": "^8.3.0",
"@typescript-eslint/parser": "^8.3.0", "@typescript-eslint/parser": "^8.3.0",
"ajv": "^8.13.0",
"async-mutex": "^0.5.0", "async-mutex": "^0.5.0",
"commander": "^13.0.0", "commander": "^13.0.0",
"compressing": "^1.10.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"esbuild": "0.25.0", "esbuild": "0.25.0",
"eslint": "^9.14.0", "eslint": "^9.14.0",
@@ -54,14 +53,14 @@
"image-size": "^1.1.1", "image-size": "^1.1.1",
"json5": "^2.2.3", "json5": "^2.2.3",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"napcat.protobuf": "^1.1.4",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"typescript-eslint": "^8.13.0", "typescript-eslint": "^8.13.0",
"vite": "^6.0.1", "vite": "^6.0.1",
"vite-plugin-cp": "^4.0.8", "vite-plugin-cp": "^6.0.0",
"vite-tsconfig-paths": "^5.1.0", "vite-tsconfig-paths": "^5.1.0",
"napcat.protobuf": "^1.1.3",
"winston": "^3.17.0", "winston": "^3.17.0",
"compressing": "^1.10.1" "zod": "^3.24.2"
}, },
"dependencies": { "dependencies": {
"@ffmpeg.wasm/core-mt": "^0.13.2", "@ffmpeg.wasm/core-mt": "^0.13.2",
@@ -69,4 +68,4 @@
"silk-wasm": "^3.6.1", "silk-wasm": "^3.6.1",
"ws": "^8.18.0" "ws": "^8.18.0"
} }
} }

View File

@@ -2,22 +2,20 @@ import path from 'node:path';
import fs from 'node:fs'; import fs from 'node:fs';
import type { NapCatCore } from '@/core'; import type { NapCatCore } from '@/core';
import json5 from 'json5'; import json5 from 'json5';
import Ajv, { AnySchema, ValidateFunction } from 'ajv'; import { z } from 'zod';
export abstract class ConfigBase<T> { export abstract class ConfigBase<T> {
name: string; name: string;
core: NapCatCore; core: NapCatCore;
configPath: string; configPath: string;
configData: T = {} as T; configData: T = {} as T;
ajv: Ajv; schema: z.ZodType<T>;
validate: ValidateFunction<T>;
protected constructor(name: string, core: NapCatCore, configPath: string, ConfigSchema: AnySchema) { protected constructor(name: string, core: NapCatCore, configPath: string, schema: z.ZodType<T>) {
this.name = name; this.name = name;
this.core = core; this.core = core;
this.configPath = configPath; this.configPath = configPath;
this.ajv = new Ajv({ useDefaults: true, coerceTypes: true }); this.schema = schema;
this.validate = this.ajv.compile<T>(ConfigSchema);
fs.mkdirSync(this.configPath, { recursive: true }); fs.mkdirSync(this.configPath, { recursive: true });
this.read(); this.read();
} }
@@ -42,11 +40,16 @@ export abstract class ConfigBase<T> {
private loadConfig(configPath: string): T { private loadConfig(configPath: string): T {
try { try {
let newConfigData = json5.parse(fs.readFileSync(configPath, 'utf-8')); let configData = json5.parse(fs.readFileSync(configPath, 'utf-8'));
this.validate(newConfigData); const result = this.schema.safeParse(configData);
this.configData = newConfigData;
this.core.context.logger.logDebug(`[Core] [Config] 配置文件${configPath}加载`, this.configData); if (result.success) {
return this.configData; this.configData = result.data;
this.core.context.logger.logDebug(`[Core] [Config] 配置文件${configPath}加载`, this.configData);
return this.configData;
} else {
throw new Error(`配置文件验证失败: ${result.error.message}`);
}
} catch (e: unknown) { } catch (e: unknown) {
this.handleError(e, '读取配置文件时发生错误'); this.handleError(e, '读取配置文件时发生错误');
return {} as T; return {} as T;
@@ -55,10 +58,14 @@ export abstract class ConfigBase<T> {
save(newConfigData: T = this.configData): void { save(newConfigData: T = this.configData): void {
const configPath = this.getConfigPath(this.core.selfInfo.uin); const configPath = this.getConfigPath(this.core.selfInfo.uin);
this.validate(newConfigData);
this.configData = newConfigData;
try { try {
fs.writeFileSync(configPath, JSON.stringify(this.configData, null, 2)); const result = this.schema.safeParse(newConfigData);
if (result.success) {
this.configData = result.data;
fs.writeFileSync(configPath, JSON.stringify(this.configData, null, 2));
} else {
throw new Error(`配置文件验证失败: ${result.error.message}`);
}
} catch (e: unknown) { } catch (e: unknown) {
this.handleError(e, `保存配置文件 ${configPath} 时发生错误:`); this.handleError(e, `保存配置文件 ${configPath} 时发生错误:`);
} }
@@ -67,6 +74,8 @@ export abstract class ConfigBase<T> {
private handleError(e: unknown, message: string): void { private handleError(e: unknown, message: string): void {
if (e instanceof SyntaxError) { if (e instanceof SyntaxError) {
this.core.context.logger.logError('[Core] [Config] 操作配置文件格式错误,请检查配置文件:', e.message); this.core.context.logger.logError('[Core] [Config] 操作配置文件格式错误,请检查配置文件:', e.message);
} else if (e instanceof z.ZodError) {
this.core.context.logger.logError('[Core] [Config] 配置文件验证错误:', e.message);
} else { } else {
this.core.context.logger.logError(`[Core] [Config] ${message}:`, (e as Error).message); this.core.context.logger.logError(`[Core] [Config] ${message}:`, (e as Error).message);
} }

View File

@@ -128,7 +128,7 @@ class FFmpegService {
const [fileInfo, durationInfo] = await Promise.all([ const [fileInfo, durationInfo] = await Promise.all([
// 任务1: 获取文件信息和提取缩略图 // 任务1: 获取文件信息和提取缩略图
(async () => { (async () => {
sendLog(`开始任务1: 获取文件信息和提取缩略图`); sendLog('开始任务1: 获取文件信息和提取缩略图');
// 获取文件信息 (并行) // 获取文件信息 (并行)
const fileInfoStartTime = Date.now(); const fileInfoStartTime = Date.now();
@@ -147,7 +147,7 @@ class FFmpegService {
// 直接实现缩略图提取 (不调用extractThumbnail方法) // 直接实现缩略图提取 (不调用extractThumbnail方法)
const thumbStartTime = Date.now(); const thumbStartTime = Date.now();
sendLog(`开始提取缩略图`); sendLog('开始提取缩略图');
const ffmpegInstance = await withTimeout( const ffmpegInstance = await withTimeout(
FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' }), FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' }),
@@ -215,7 +215,7 @@ class FFmpegService {
// 任务2: 获取视频时长 // 任务2: 获取视频时长
(async () => { (async () => {
const task2StartTime = Date.now(); const task2StartTime = Date.now();
sendLog(`开始任务2: 获取视频时长`); sendLog('开始任务2: 获取视频时长');
// 创建FFmpeg实例 // 创建FFmpeg实例
const ffmpegCreateStartTime = Date.now(); const ffmpegCreateStartTime = Date.now();
@@ -291,16 +291,16 @@ interface FFmpegTask {
} }
export default async function handleFFmpegTask({ method, args }: FFmpegTask): Promise<any> { export default async function handleFFmpegTask({ method, args }: FFmpegTask): Promise<any> {
switch (method) { switch (method) {
case 'extractThumbnail': case 'extractThumbnail':
return await FFmpegService.extractThumbnail(...args as [string, string]); return await FFmpegService.extractThumbnail(...args as [string, string]);
case 'convertFile': case 'convertFile':
return await FFmpegService.convertFile(...args as [string, string, string]); return await FFmpegService.convertFile(...args as [string, string, string]);
case 'convert': case 'convert':
return await FFmpegService.convert(...args as [string, string]); return await FFmpegService.convert(...args as [string, string]);
case 'getVideoInfo': case 'getVideoInfo':
return await FFmpegService.getVideoInfo(...args as [string, string]); return await FFmpegService.getVideoInfo(...args as [string, string]);
default: default:
throw new Error(`Unknown method: ${method}`); throw new Error(`Unknown method: ${method}`);
} }
} }
recvTask<FFmpegTask>(async ({ method, args }: FFmpegTask) => { recvTask<FFmpegTask>(async ({ method, args }: FFmpegTask) => {

View File

@@ -182,28 +182,28 @@ export async function uriToLocalFile(dir: string, uri: string, filename: string
const filePath = path.join(dir, filename); const filePath = path.join(dir, filename);
switch (UriType) { switch (UriType) {
case FileUriType.Local: { case FileUriType.Local: {
const fileExt = path.extname(HandledUri); const fileExt = path.extname(HandledUri);
const localFileName = path.basename(HandledUri, fileExt) + fileExt; const localFileName = path.basename(HandledUri, fileExt) + fileExt;
const tempFilePath = path.join(dir, filename + fileExt); const tempFilePath = path.join(dir, filename + fileExt);
fs.copyFileSync(HandledUri, tempFilePath); fs.copyFileSync(HandledUri, tempFilePath);
return { success: true, errMsg: '', fileName: localFileName, path: tempFilePath }; return { success: true, errMsg: '', fileName: localFileName, path: tempFilePath };
} }
case FileUriType.Remote: { case FileUriType.Remote: {
const buffer = await httpDownload({ url: HandledUri, headers: headers ?? {} }); const buffer = await httpDownload({ url: HandledUri, headers: headers ?? {} });
fs.writeFileSync(filePath, buffer); fs.writeFileSync(filePath, buffer);
return { success: true, errMsg: '', fileName: filename, path: filePath }; return { success: true, errMsg: '', fileName: filename, path: filePath };
} }
case FileUriType.Base64: { case FileUriType.Base64: {
const base64 = HandledUri.replace(/^base64:\/\//, ''); const base64 = HandledUri.replace(/^base64:\/\//, '');
const base64Buffer = Buffer.from(base64, 'base64'); const base64Buffer = Buffer.from(base64, 'base64');
fs.writeFileSync(filePath, base64Buffer); fs.writeFileSync(filePath, base64Buffer);
return { success: true, errMsg: '', fileName: filename, path: filePath }; return { success: true, errMsg: '', fileName: filename, path: filePath };
} }
default: default:
return { success: false, errMsg: `识别URL失败, uri= ${uri}`, fileName: '', path: '' }; return { success: false, errMsg: `识别URL失败, uri= ${uri}`, fileName: '', path: '' };
} }
} }

View File

@@ -1 +1 @@
export const napCatVersion = '4.7.12'; export const napCatVersion = '4.7.19';

View File

@@ -9,7 +9,7 @@ export async function runTask<T, R>(workerScript: string, taskData: T): Promise<
console.error('Worker Log--->:', (result as { log: string }).log); console.error('Worker Log--->:', (result as { log: string }).log);
} }
if ((result as any)?.error) { if ((result as any)?.error) {
reject(new Error("Worker error: " + (result as { error: string }).error)); reject(new Error('Worker error: ' + (result as { error: string }).error));
} }
resolve(result); resolve(result);
}); });

View File

@@ -41,10 +41,10 @@ export class NTQQFileApi {
this.context = context; this.context = context;
this.core = core; this.core = core;
this.rkeyManager = new RkeyManager([ this.rkeyManager = new RkeyManager([
'https://ss.xingzhige.com/music_card/rkey', // 国内 'https://secret-service.bietiaop.com/rkeys',
'https://secret-service.bietiaop.com/rkeys',//国内 'http://ss.xingzhige.com/music_card/rkey',
], ],
this.context.logger this.context.logger
); );
} }
@@ -231,7 +231,7 @@ export class NTQQFileApi {
}, },
}; };
} }
async createValidSendPttElement(context: SendMessageContext, pttPath: string): Promise<SendPttElement> { async createValidSendPttElement(_context: SendMessageContext, pttPath: string): Promise<SendPttElement> {
const { converted, path: silkPath, duration } = await encodeSilk(pttPath, this.core.NapCatTempPath, this.core.context.logger); const { converted, path: silkPath, duration } = await encodeSilk(pttPath, this.core.NapCatTempPath, this.core.context.logger);
if (!silkPath) { if (!silkPath) {
@@ -308,18 +308,18 @@ export class NTQQFileApi {
element.elementType === ElementType.FILE element.elementType === ElementType.FILE
) { ) {
switch (element.elementType) { switch (element.elementType) {
case ElementType.PIC: case ElementType.PIC:
element.picElement!.sourcePath = elementResults?.[elementIndex] ?? ''; element.picElement!.sourcePath = elementResults?.[elementIndex] ?? '';
break; break;
case ElementType.VIDEO: case ElementType.VIDEO:
element.videoElement!.filePath = elementResults?.[elementIndex] ?? ''; element.videoElement!.filePath = elementResults?.[elementIndex] ?? '';
break; break;
case ElementType.PTT: case ElementType.PTT:
element.pttElement!.filePath = elementResults?.[elementIndex] ?? ''; element.pttElement!.filePath = elementResults?.[elementIndex] ?? '';
break; break;
case ElementType.FILE: case ElementType.FILE:
element.fileElement!.filePath = elementResults?.[elementIndex] ?? ''; element.fileElement!.filePath = elementResults?.[elementIndex] ?? '';
break; break;
} }
elementIndex++; elementIndex++;
} }

View File

@@ -218,6 +218,10 @@ export class NTQQGroupApi {
return this.context.session.getRichMediaService().deleteGroupFolder(groupCode, folderId); return this.context.session.getRichMediaService().deleteGroupFolder(groupCode, folderId);
} }
async transGroupFile(groupCode: string, fileId: string) {
return this.context.session.getRichMediaService().transGroupFile(groupCode, fileId);
}
async addGroupEssence(groupCode: string, msgId: string) { async addGroupEssence(groupCode: string, msgId: string) {
const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({
chatType: 2, chatType: 2,

View File

@@ -12,7 +12,7 @@ export class NTQQMsgApi {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async clickInlineKeyboardButton(...params: Parameters<NodeIKernelMsgService['clickInlineKeyboardButton']>) { async clickInlineKeyboardButton(...params: Parameters<NodeIKernelMsgService['clickInlineKeyboardButton']>) {
return this.context.session.getMsgService().clickInlineKeyboardButton(...params); return this.context.session.getMsgService().clickInlineKeyboardButton(...params);
} }

View File

@@ -234,5 +234,13 @@
"3.2.16-33800": { "3.2.16-33800": {
"appid": 537274009, "appid": 537274009,
"qua": "V1_LNX_NQ_3.2.16_33800_GW_B" "qua": "V1_LNX_NQ_3.2.16_33800_GW_B"
},
"9.9.19-34231": {
"appid": 537279209,
"qua": "V1_WIN_NQ_9.9.19_34231_GW_B"
},
"3.2.17-34231": {
"appid": 537279245,
"qua": "V1_LNX_NQ_3.2.17_34231_GW_B"
} }
} }

View File

@@ -314,5 +314,17 @@
"3.2.16-33800-arm64": { "3.2.16-33800-arm64": {
"send": "7262BB0", "send": "7262BB0",
"recv": "72664E0" "recv": "72664E0"
},
"9.9.19-34231-x64": {
"send": "3BD73D0",
"recv": "3BDBBD0"
},
"3.2.17-34231-x64": {
"send": "AD787E0",
"recv": "AD7C200"
},
"3.2.17-34231-arm64": {
"send": "770CDC0",
"recv": "77106F0"
} }
} }

View File

@@ -1,22 +1,21 @@
import { ConfigBase } from '@/common/config-base'; import { ConfigBase } from '@/common/config-base';
import { NapCatCore } from '@/core'; import { NapCatCore } from '@/core';
import { Type, Static } from '@sinclair/typebox'; import { z } from 'zod';
import { AnySchema } from 'ajv';
export const NapcatConfigSchema = Type.Object({ export const NapcatConfigSchema = z.object({
fileLog: Type.Boolean({ default: false }), fileLog: z.boolean().default(false),
consoleLog: Type.Boolean({ default: true }), consoleLog: z.boolean().default(true),
fileLogLevel: Type.String({ default: 'debug' }), fileLogLevel: z.string().default('debug'),
consoleLogLevel: Type.String({ default: 'info' }), consoleLogLevel: z.string().default('info'),
packetBackend: Type.String({ default: 'auto' }), packetBackend: z.string().default('auto'),
packetServer: Type.String({ default: '' }), packetServer: z.string().default(''),
o3HookMode: Type.Number({ default: 0 }), o3HookMode: z.number().default(0),
}); });
export type NapcatConfig = Static<typeof NapcatConfigSchema>; export type NapcatConfig = z.infer<typeof NapcatConfigSchema>;
export class NapCatConfigLoader extends ConfigBase<NapcatConfig> { export class NapCatConfigLoader extends ConfigBase<NapcatConfig> {
constructor(core: NapCatCore, configPath: string, schema: AnySchema) { constructor(core: NapCatCore, configPath: string, schema: z.ZodType<any>) {
super('napcat', core, configPath, schema); super('napcat', core, configPath, schema);
} }
} }

View File

@@ -6,6 +6,17 @@ interface ServerRkeyData {
private_rkey: string; private_rkey: string;
expired_time: number; expired_time: number;
} }
interface OneBotApiRet {
status: string,
retcode: number,
data: ServerRkeyData,
message: string,
wording: string,
}
interface UrlFailureInfo {
count: number;
lastTimestamp: number;
}
export class RkeyManager { export class RkeyManager {
serverUrl: string[] = []; serverUrl: string[] = [];
@@ -15,9 +26,8 @@ export class RkeyManager {
private_rkey: '', private_rkey: '',
expired_time: 0, expired_time: 0,
}; };
private failureCount: number = 0; private urlFailures: Map<string, UrlFailureInfo> = new Map();
private lastFailureTimestamp: number = 0; private readonly FAILURE_LIMIT: number = 4;
private readonly FAILURE_LIMIT: number = 8;
private readonly ONE_DAY: number = 24 * 60 * 60 * 1000; private readonly ONE_DAY: number = 24 * 60 * 60 * 1000;
constructor(serverUrl: string[], logger: LogWrapper) { constructor(serverUrl: string[], logger: LogWrapper) {
@@ -26,50 +36,92 @@ export class RkeyManager {
} }
async getRkey() { async getRkey() {
const now = new Date().getTime(); const availableUrls = this.getAvailableUrls();
if (now - this.lastFailureTimestamp > this.ONE_DAY) { if (availableUrls.length === 0) {
this.failureCount = 0; // 重置失败计数器 this.logger.logError('[Rkey] 所有服务均已禁用, 图片使用FallBack机制');
} throw new Error('获取rkey失败所有服务URL均已被禁用');
if (this.failureCount >= this.FAILURE_LIMIT) {
this.logger.logError('[Rkey] 服务存在异常, 图片使用FallBack机制');
throw new Error('获取rkey失败次数过多请稍后再试');
} }
if (this.isExpired()) { if (this.isExpired()) {
try { try {
await this.refreshRkey(); await this.refreshRkey();
} catch (e) { } catch (e) {
throw new Error(`${e}`);//外抛 throw new Error(`${e}`);
} }
} }
return this.rkeyData; return this.rkeyData;
} }
private getAvailableUrls(): string[] {
return this.serverUrl.filter(url => !this.isUrlDisabled(url));
}
private isUrlDisabled(url: string): boolean {
const failureInfo = this.urlFailures.get(url);
if (!failureInfo) return false;
const now = new Date().getTime();
// 如果已经过了一天,重置失败计数
if (now - failureInfo.lastTimestamp > this.ONE_DAY) {
failureInfo.count = 0;
this.urlFailures.set(url, failureInfo);
return false;
}
return failureInfo.count >= this.FAILURE_LIMIT;
}
private updateUrlFailure(url: string) {
const now = new Date().getTime();
const failureInfo = this.urlFailures.get(url) || { count: 0, lastTimestamp: 0 };
// 如果已经过了一天,重置失败计数
if (now - failureInfo.lastTimestamp > this.ONE_DAY) {
failureInfo.count = 1;
} else {
failureInfo.count++;
}
failureInfo.lastTimestamp = now;
this.urlFailures.set(url, failureInfo);
if (failureInfo.count >= this.FAILURE_LIMIT) {
this.logger.logError(`[Rkey] URL ${url} 已被禁用,失败次数达到 ${this.FAILURE_LIMIT}`);
}
}
isExpired(): boolean { isExpired(): boolean {
const now = new Date().getTime() / 1000; const now = new Date().getTime() / 1000;
return now > this.rkeyData.expired_time; return now > this.rkeyData.expired_time;
} }
async refreshRkey() { async refreshRkey() {
//刷新rkey const availableUrls = this.getAvailableUrls();
for (const url of this.serverUrl) {
if (availableUrls.length === 0) {
this.logger.logError('[Rkey] 所有服务均已禁用');
throw new Error('获取rkey失败所有服务URL均已被禁用');
}
for (const url of availableUrls) {
try { try {
const temp = await RequestUtil.HttpGetJson<ServerRkeyData>(url, 'GET'); let temp = await RequestUtil.HttpGetJson<ServerRkeyData>(url, 'GET');
if ('retcode' in temp) {
// 支持Onebot Ret风格
temp = (temp as unknown as OneBotApiRet).data;
}
this.rkeyData = { this.rkeyData = {
group_rkey: temp.group_rkey.slice(6), group_rkey: temp.group_rkey.slice(6),
private_rkey: temp.private_rkey.slice(6), private_rkey: temp.private_rkey.slice(6),
expired_time: temp.expired_time expired_time: temp.expired_time
}; };
this.failureCount = 0;
return; return;
} catch (e) { } catch (e) {
this.logger.logError(`[Rkey] 异常服务 ${url} 异常 / `, e); this.logger.logError(`[Rkey] 异常服务 ${url} 异常 / `, e);
this.failureCount++; this.updateUrlFailure(url);
this.lastFailureTimestamp = new Date().getTime();
//是否为最后一个url if (url === availableUrls[availableUrls.length - 1]) {
if (url === this.serverUrl[this.serverUrl.length - 1]) { throw new Error(`获取rkey失败: ${e}`);
throw new Error(`获取rkey失败: ${e}`);//外抛
} }
} }
} }

View File

@@ -68,8 +68,8 @@ export class PacketOperationContext {
} }
} }
async SetGroupSpecialTitle(groupUin: number, uid: string, tittle: string) { async SetGroupSpecialTitle(groupUin: number, uid: string, title: string) {
const req = trans.SetSpecialTitle.build(groupUin, uid, tittle); const req = trans.SetSpecialTitle.build(groupUin, uid, title);
await this.context.client.sendOidbPacket(req); await this.context.client.sendOidbPacket(req);
} }
@@ -154,6 +154,20 @@ export class PacketOperationContext {
return res.result.resId; return res.result.resId;
} }
async MoveGroupFile(groupUin: number, fileUUID: string, currentParentDirectory: string, targetParentDirectory: string) {
const req = trans.MoveGroupFile.build(groupUin, fileUUID, currentParentDirectory, targetParentDirectory);
const resp = await this.context.client.sendOidbPacket(req, true);
const res = trans.MoveGroupFile.parse(resp);
return res.move.retCode;
}
async RenameGroupFile(groupUin: number, fileUUID: string, currentParentDirectory: string, newName: string) {
const req = trans.RenameGroupFile.build(groupUin, fileUUID, currentParentDirectory, newName);
const resp = await this.context.client.sendOidbPacket(req, true);
const res = trans.RenameGroupFile.parse(resp);
return res.rename.retCode;
}
async GetGroupFileUrl(groupUin: number, fileUUID: string) { async GetGroupFileUrl(groupUin: number, fileUUID: string) {
const req = trans.DownloadGroupFile.build(groupUin, fileUUID); const req = trans.DownloadGroupFile.build(groupUin, fileUUID);
const resp = await this.context.client.sendOidbPacket(req, true); const resp = await this.context.client.sendOidbPacket(req, true);

View File

@@ -0,0 +1,35 @@
import * as proto from '@/core/packet/transformer/proto';
import { NapProtoMsg } from '@napneko/nap-proto-core';
import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class MoveGroupFile extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0x6D6Response> {
constructor() {
super();
}
build(groupUin: number, fileUUID: string, currentParentDirectory: string, targetParentDirectory: string): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0x6D6).encode({
move: {
groupUin: groupUin,
appId: 5,
busId: 102,
fileId: fileUUID,
parentDirectory: currentParentDirectory,
targetDirectory: targetParentDirectory,
}
});
return OidbBase.build(0x6D6, 5, body, true, false);
}
parse(data: Buffer) {
const oidbBody = OidbBase.parse(data).body;
const res = new NapProtoMsg(proto.OidbSvcTrpcTcp0x6D6Response).decode(oidbBody);
if (res.move.retCode !== 0) {
throw new Error(`sendGroupFileMoveReq error: ${res.move.clientWording} (code=${res.move.retCode})`);
}
return res;
}
}
export default new MoveGroupFile();

View File

@@ -0,0 +1,34 @@
import * as proto from '@/core/packet/transformer/proto';
import { NapProtoMsg } from '@napneko/nap-proto-core';
import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class RenameGroupFile extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0x6D6Response> {
constructor() {
super();
}
build(groupUin: number, fileUUID: string, currentParentDirectory: string, newName: string): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0x6D6).encode({
rename: {
groupUin: groupUin,
busId: 102,
fileId: fileUUID,
parentFolder: currentParentDirectory,
newFileName: newName,
}
});
return OidbBase.build(0x6D6, 4, body, true, false);
}
parse(data: Buffer) {
const oidbBody = OidbBase.parse(data).body;
const res = new NapProtoMsg(proto.OidbSvcTrpcTcp0x6D6Response).decode(oidbBody);
if (res.rename.retCode !== 0) {
throw new Error(`sendGroupFileRenameReq error: ${res.rename.clientWording} (code=${res.rename.retCode})`);
}
return res;
}
}
export default new RenameGroupFile();

View File

@@ -8,14 +8,14 @@ class SetSpecialTitle extends PacketTransformer<typeof proto.OidbSvcTrpcTcpBase>
super(); super();
} }
build(groupCode: number, uid: string, tittle: string): OidbPacket { build(groupCode: number, uid: string, title: string): OidbPacket {
const oidb_0x8FC_2 = new NapProtoMsg(proto.OidbSvcTrpcTcp0X8FC_2).encode({ const oidb_0x8FC_2 = new NapProtoMsg(proto.OidbSvcTrpcTcp0X8FC_2).encode({
groupUin: +groupCode, groupUin: +groupCode,
body: { body: {
targetUid: uid, targetUid: uid,
specialTitle: tittle, specialTitle: title,
expiredTime: -1, expiredTime: -1,
uinName: tittle uinName: title
} }
}); });
return OidbBase.build(0x8FC, 2, oidb_0x8FC_2, false, false); return OidbBase.build(0x8FC, 2, oidb_0x8FC_2, false, false);

View File

@@ -6,3 +6,5 @@ export { default as GetStrangerInfo } from './GetStrangerInfo';
export { default as SendPoke } from './SendPoke'; export { default as SendPoke } from './SendPoke';
export { default as SetSpecialTitle } from './SetSpecialTitle'; export { default as SetSpecialTitle } from './SetSpecialTitle';
export { default as ImageOCR } from './ImageOCR'; export { default as ImageOCR } from './ImageOCR';
export { default as MoveGroupFile } from './MoveGroupFile';
export { default as RenameGroupFile } from './RenameGroupFile';

View File

@@ -1,5 +1,5 @@
import { AnyCnameRecord } from 'node:dns'; import { AnyCnameRecord } from 'node:dns';
import { BizKey, ModifyProfileParams, NodeIKernelProfileListener, ProfileBizType, SimpleInfo, UserDetailInfoByUin, UserDetailSource } from '@/core'; import { BizKey, ModifyProfileParams, NodeIKernelProfileListener, ProfileBizType, SimpleInfo, UserDetailInfoByUin, UserDetailInfoListenerArg, UserDetailSource } from '@/core';
import { GeneralCallResult } from '@/core/services/common'; import { GeneralCallResult } from '@/core/services/common';
export interface NodeIKernelProfileService { export interface NodeIKernelProfileService {
@@ -15,7 +15,13 @@ export interface NodeIKernelProfileService {
getCoreAndBaseInfo(callfrom: string, uids: string[]): Promise<Map<string, SimpleInfo>>; getCoreAndBaseInfo(callfrom: string, uids: string[]): Promise<Map<string, SimpleInfo>>;
fetchUserDetailInfo(trace: string, uids: string[], source: UserDetailSource, bizType: ProfileBizType[]): Promise<GeneralCallResult>; fetchUserDetailInfo(trace: string, uids: string[], source: UserDetailSource, bizType: ProfileBizType[]): Promise<GeneralCallResult &
{
source: UserDetailSource,
// uid -> detail
detail: Map<string, UserDetailInfoListenerArg>,
}
>;
addKernelProfileListener(listener: NodeIKernelProfileListener): number; addKernelProfileListener(listener: NodeIKernelProfileListener): number;

View File

@@ -198,9 +198,29 @@ export interface NodeIKernelRichMediaService {
renameGroupFile(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown; renameGroupFile(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown;
moveGroupFile(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown; moveGroupFile(groupCode: string, busId: Array<number>, fileList: Array<string>, currentParentDirectory: string, targetParentDirectory: string): Promise<GeneralCallResult & {
moveGroupFileResult: {
result: {
retCode: number,
retMsg: symbol,
clientWording: string
},
successFileIdList: Array<string>,
failFileIdList: Array<string>
}
}>;
transGroupFile(arg1: unknown, arg2: unknown): unknown; transGroupFile(groupCode: string, fileId: string): Promise<GeneralCallResult & {
transGroupFileResult: {
result: {
retCode: number
retMsg: string
clientWording: string
}
saveBusId: number
saveFilePath: string
}
}>;
searchGroupFile( searchGroupFile(
keywords: Array<string>, keywords: Array<string>,

View File

@@ -115,7 +115,7 @@ export interface GroupEssenceMsg {
add_digest_uin: string; add_digest_uin: string;
add_digest_nick: string; add_digest_nick: string;
add_digest_time: number; add_digest_time: number;
msg_content: unknown[]; msg_content: { msg_type: number, text?: string, image_url?: string }[];
can_be_removed: true; can_be_removed: true;
} }

View File

@@ -1,8 +1,8 @@
import { ActionName, BaseCheckResult } from './router'; import { ActionName, BaseCheckResult } from './router';
import Ajv, { ErrorObject, ValidateFunction } from 'ajv';
import { NapCatCore } from '@/core'; import { NapCatCore } from '@/core';
import { NapCatOneBot11Adapter, OB11Return } from '@/onebot'; import { NapCatOneBot11Adapter, OB11Return } from '@/onebot';
import { NetworkAdapterConfig } from '../config/config'; import { NetworkAdapterConfig } from '../config/config';
import { z } from 'zod';
export class OB11Response { export class OB11Response {
private static createResponse<T>(data: T, status: string, retcode: number, message: string = '', echo: unknown = null): OB11Return<T> { private static createResponse<T>(data: T, status: string, retcode: number, message: string = '', echo: unknown = null): OB11Return<T> {
@@ -32,8 +32,7 @@ export class OB11Response {
export abstract class OneBotAction<PayloadType, ReturnDataType> { export abstract class OneBotAction<PayloadType, ReturnDataType> {
actionName: typeof ActionName[keyof typeof ActionName] = ActionName.Unknown; actionName: typeof ActionName[keyof typeof ActionName] = ActionName.Unknown;
core: NapCatCore; core: NapCatCore;
private validate?: ValidateFunction<unknown> = undefined; payloadSchema?: z.ZodType<unknown> = undefined;
payloadSchema?: unknown = undefined;
obContext: NapCatOneBot11Adapter; obContext: NapCatOneBot11Adapter;
constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore) { constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore) {
@@ -41,19 +40,30 @@ export abstract class OneBotAction<PayloadType, ReturnDataType> {
this.core = core; this.core = core;
} }
protected async check(payload: PayloadType): Promise<BaseCheckResult> { protected async check(payload: unknown): Promise<BaseCheckResult> {
if (this.payloadSchema) { if (!this.payloadSchema) {
this.validate = new Ajv({ allowUnionTypes: true, useDefaults: true }).compile(this.payloadSchema); return { valid: true };
} }
if (this.validate && !this.validate(payload)) {
const errors = this.validate.errors as ErrorObject[]; try {
const errorMessages = errors.map(e => `Key: ${e.instancePath.split('/').slice(1).join('.')}, Message: ${e.message}`); // 使用 zod 验证并转换数据
this.payloadSchema.parse(payload);
return { valid: true };
} catch (error) {
if (error instanceof z.ZodError) {
const errorMessages = error.errors.map(e =>
`Key: ${e.path.join('.')}, Message: ${e.message}`
);
return {
valid: false,
message: errorMessages.join('\n') || '未知错误',
};
}
return { return {
valid: false, valid: false,
message: errorMessages.join('\n') ?? '未知错误', message: '验证过程中发生未知错误'
}; };
} }
return { valid: true };
} }
public async handle(payload: PayloadType, adaptername: string, config: NetworkAdapterConfig): Promise<OB11Return<ReturnDataType | null>> { public async handle(payload: PayloadType, adaptername: string, config: NetworkAdapterConfig): Promise<OB11Return<ReturnDataType | null>> {
@@ -85,4 +95,4 @@ export abstract class OneBotAction<PayloadType, ReturnDataType> {
} }
abstract _handle(payload: PayloadType, adaptername: string, config: NetworkAdapterConfig): Promise<ReturnDataType>; abstract _handle(payload: PayloadType, adaptername: string, config: NetworkAdapterConfig): Promise<ReturnDataType>;
} }

View File

@@ -1,16 +1,15 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { OneBotAction } from '../OneBotAction'; import { OneBotAction } from '../OneBotAction';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.string(),
bot_appid: Type.String(), bot_appid: z.string(),
button_id: Type.String({ default: '' }), button_id: z.string().default(''),
callback_data: Type.String({ default: '' }), callback_data: z.string().default(''),
msg_seq: Type.String({ default: '10086' }), msg_seq: z.string().default('10086'),
}); });
type Payload = z.infer<typeof SchemaData>;
type Payload = Static<typeof SchemaData>;
export class ClickInlineKeyboardButton extends OneBotAction<Payload, unknown> { export class ClickInlineKeyboardButton extends OneBotAction<Payload, unknown> {
override actionName = ActionName.ClickInlineKeyboardButton; override actionName = ActionName.ClickInlineKeyboardButton;
@@ -25,6 +24,6 @@ export class ClickInlineKeyboardButton extends OneBotAction<Payload, unknown> {
callback_data: payload.callback_data, callback_data: payload.callback_data,
dmFlag: 0, dmFlag: 0,
chatType: 2 chatType: 2
}) });
} }
} }

View File

@@ -1,13 +1,13 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Type, Static } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
rawData: Type.String(), rawData: z.string(),
brief: Type.String(), brief: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class CreateCollection extends OneBotAction<Payload, unknown> { export class CreateCollection extends OneBotAction<Payload, unknown> {
override actionName = ActionName.CreateCollection; override actionName = ActionName.CreateCollection;

View File

@@ -1,12 +1,12 @@
import { Type, Static } from '@sinclair/typebox'; import { z } from 'zod';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
const SchemaData = Type.Object({ const SchemaData = z.object({
count: Type.Union([Type.Number(), Type.String()], { default: 48 }), count: z.number().default(48),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class FetchCustomFace extends OneBotAction<Payload, string[]> { export class FetchCustomFace extends OneBotAction<Payload, string[]> {
override actionName = ActionName.FetchCustomFace; override actionName = ActionName.FetchCustomFace;

View File

@@ -1,17 +1,17 @@
import { Type, Static } from '@sinclair/typebox'; import { z } from 'zod';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { MessageUnique } from '@/common/message-unique'; import { MessageUnique } from '@/common/message-unique';
import { type NTQQMsgApi } from '@/core/apis'; import { type NTQQMsgApi } from '@/core/apis';
const SchemaData = Type.Object({ const SchemaData = z.object({
message_id: Type.Union([Type.Number(), Type.String()]), message_id: z.string(),
emojiId: Type.Union([Type.Number(), Type.String()]), emojiId: z.string(),
emojiType: Type.Union([Type.Number(), Type.String()]), emojiType: z.string(),
count: Type.Union([Type.Number(), Type.String()], { default: 20 }), count: z.number().default(20),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class FetchEmojiLike extends OneBotAction<Payload, Awaited<ReturnType<NTQQMsgApi['getMsgEmojiLikesList']>>> { export class FetchEmojiLike extends OneBotAction<Payload, Awaited<ReturnType<NTQQMsgApi['getMsgEmojiLikesList']>>> {
override actionName = ActionName.FetchEmojiLike; override actionName = ActionName.FetchEmojiLike;
@@ -23,7 +23,7 @@ export class FetchEmojiLike extends OneBotAction<Payload, Awaited<ReturnType<NTQ
const msg = (await this.core.apis.MsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0]; const msg = (await this.core.apis.MsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0];
if (!msg) throw new Error('消息不存在'); if (!msg) throw new Error('消息不存在');
return await this.core.apis.MsgApi.getMsgEmojiLikesList( return await this.core.apis.MsgApi.getMsgEmojiLikesList(
msgIdPeer.Peer, msg.msgSeq, payload.emojiId.toString(), payload.emojiType.toString(), +payload.count msgIdPeer.Peer, msg.msgSeq, payload.emojiId, payload.emojiType, +payload.count
); );
} }
} }

View File

@@ -1,14 +1,14 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { AIVoiceChatType } from '@/core/packet/entities/aiChat'; import { AIVoiceChatType } from '@/core/packet/entities/aiChat';
import { Type, Static } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.string(),
chat_type: Type.Union([Type.Union([Type.Number(), Type.String()])], { default: 1 }), chat_type: z.number().default(1),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
interface GetAiCharactersResponse { interface GetAiCharactersResponse {
type: string; type: string;

View File

@@ -1,14 +1,14 @@
import { type NTQQCollectionApi } from '@/core/apis/collection'; import { type NTQQCollectionApi } from '@/core/apis/collection';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Type, Static } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
category: Type.Union([Type.Number(), Type.String()]), category: z.number(),
count: Type.Union([Type.Union([Type.Number(), Type.String()])], { default: 1 }), count: z.number().default(1),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetCollectionList extends OneBotAction<Payload, Awaited<ReturnType<NTQQCollectionApi['getAllCollection']>>> { export class GetCollectionList extends OneBotAction<Payload, Awaited<ReturnType<NTQQCollectionApi['getAllCollection']>>> {
override actionName = ActionName.GetCollectionList; override actionName = ActionName.GetCollectionList;

View File

@@ -1,17 +1,17 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Type, Static } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetGroupInfoEx extends OneBotAction<Payload, unknown> { export class GetGroupInfoEx extends OneBotAction<Payload, unknown> {
override actionName = ActionName.GetGroupInfoEx; override actionName = ActionName.GetGroupInfoEx;
override payloadSchema = SchemaData; override payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
return (await this.core.apis.GroupApi.getGroupExtFE0Info([payload.group_id.toString()])).result.groupExtInfos.get(payload.group_id.toString()); return (await this.core.apis.GroupApi.getGroupExtFE0Info([payload.group_id])).result.groupExtInfos.get(payload.group_id);
} }
} }

View File

@@ -2,38 +2,38 @@ import { ActionName } from '@/onebot/action/router';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { MiniAppInfo, MiniAppInfoHelper } from '@/core/packet/utils/helper/miniAppHelper'; import { MiniAppInfo, MiniAppInfoHelper } from '@/core/packet/utils/helper/miniAppHelper';
import { MiniAppData, MiniAppRawData, MiniAppReqCustomParams, MiniAppReqParams } from '@/core/packet/entities/miniApp'; import { MiniAppData, MiniAppRawData, MiniAppReqCustomParams, MiniAppReqParams } from '@/core/packet/entities/miniApp';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Union([ const SchemaData = z.union([
Type.Object({ z.object({
type: Type.Union([Type.Literal('bili'), Type.Literal('weibo')]), type: z.union([z.literal('bili'), z.literal('weibo')]),
title: Type.String(), title: z.string(),
desc: Type.String(), desc: z.string(),
picUrl: Type.String(), picUrl: z.string(),
jumpUrl: Type.String(), jumpUrl: z.string(),
webUrl: Type.Optional(Type.String()), webUrl: z.string().optional(),
rawArkData: Type.Optional(Type.Union([Type.String()])) rawArkData: z.string().optional()
}), }),
Type.Object({ z.object({
title: Type.String(), title: z.string(),
desc: Type.String(), desc: z.string(),
picUrl: Type.String(), picUrl: z.string(),
jumpUrl: Type.String(), jumpUrl: z.string(),
iconUrl: Type.String(), iconUrl: z.string(),
webUrl: Type.Optional(Type.String()), webUrl: z.string().optional(),
appId: Type.String(), appId: z.string(),
scene: Type.Union([Type.Number(), Type.String()]), scene: z.union([z.number(), z.string()]),
templateType: Type.Union([Type.Number(), Type.String()]), templateType: z.union([z.number(), z.string()]),
businessType: Type.Union([Type.Number(), Type.String()]), businessType: z.union([z.number(), z.string()]),
verType: Type.Union([Type.Number(), Type.String()]), verType: z.union([z.number(), z.string()]),
shareType: Type.Union([Type.Number(), Type.String()]), shareType: z.union([z.number(), z.string()]),
versionId: Type.String(), versionId: z.string(),
sdkId: Type.String(), sdkId: z.string(),
withShareTicket: Type.Union([Type.Number(), Type.String()]), withShareTicket: z.union([z.number(), z.string()]),
rawArkData: Type.Optional(Type.Union([Type.String()])) rawArkData: z.string().optional()
}) })
]); ]);
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetMiniAppArk extends GetPacketStatusDepends<Payload, { export class GetMiniAppArk extends GetPacketStatusDepends<Payload, {
data: MiniAppData | MiniAppRawData data: MiniAppData | MiniAppRawData

View File

@@ -1,15 +1,15 @@
import { NTVoteInfo } from '@/core'; import { NTVoteInfo } from '@/core';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Type, Static } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
user_id: Type.Optional(Type.Union([Type.Number(), Type.String()])), user_id: z.string().optional(),
start: Type.Union([Type.Number(), Type.String()], { default: 0 }), start: z.number().default(0),
count: Type.Union([Type.Number(), Type.String()], { default: 10 }) count: z.number().default(10),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetProfileLike extends OneBotAction<Payload, { export class GetProfileLike extends OneBotAction<Payload, {
uid: string; uid: string;

View File

@@ -36,7 +36,7 @@ export class GetUnidirectionalFriendList extends OneBotAction<void, Friend[]> {
uint64_uin: self_id, uint64_uin: self_id,
uint64_top: 0, uint64_top: 0,
uint32_req_num: 99, uint32_req_num: 99,
bytes_cookies: "" bytes_cookies: ''
}; };
const packed_data = await this.pack_data(JSON.stringify(req_json)); const packed_data = await this.pack_data(JSON.stringify(req_json));
const data = Buffer.from(packed_data).toString('hex'); const data = Buffer.from(packed_data).toString('hex');

View File

@@ -1,18 +1,18 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.number(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetUserStatus extends GetPacketStatusDepends<Payload, { status: number; ext_status: number; } | undefined> { export class GetUserStatus extends GetPacketStatusDepends<Payload, { status: number; ext_status: number; } | undefined> {
override actionName = ActionName.GetUserStatus; override actionName = ActionName.GetUserStatus;
override payloadSchema = SchemaData; override payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
return await this.core.apis.PacketApi.pkt.operation.GetStrangerStatus(+payload.user_id); return await this.core.apis.PacketApi.pkt.operation.GetStrangerStatus(payload.user_id);
} }
} }

View File

@@ -0,0 +1,33 @@
import { ActionName } from '@/onebot/action/router';
import { FileNapCatOneBotUUID } from '@/common/file-uuid';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { z } from 'zod';
const SchemaData = z.object({
group_id: z.union([z.number(), z.string()]),
file_id: z.string(),
current_parent_directory: z.string(),
target_parent_directory: z.string(),
});
type Payload = z.infer<typeof SchemaData>;
interface MoveGroupFileResponse {
ok: boolean;
}
export class MoveGroupFile extends GetPacketStatusDepends<Payload, MoveGroupFileResponse> {
override actionName = ActionName.MoveGroupFile;
override payloadSchema = SchemaData;
async _handle(payload: Payload) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id) || FileNapCatOneBotUUID.decodeModelId(payload.file_id);
if (contextMsgFile?.fileUUID) {
await this.core.apis.PacketApi.pkt.operation.MoveGroupFile(+payload.group_id, contextMsgFile.fileUUID, payload.current_parent_directory, payload.target_parent_directory);
return {
ok: true,
};
}
throw new Error('real fileUUID not found!');
}
}

View File

@@ -2,14 +2,14 @@ import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { checkFileExist, uriToLocalFile } from '@/common/file'; import { checkFileExist, uriToLocalFile } from '@/common/file';
import fs from 'fs'; import fs from 'fs';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
import { GeneralCallResultStatus } from '@/core'; import { GeneralCallResultStatus } from '@/core';
const SchemaData = Type.Object({ const SchemaData = z.object({
image: Type.String(), image: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
class OCRImageBase extends OneBotAction<Payload, GeneralCallResultStatus> { class OCRImageBase extends OneBotAction<Payload, GeneralCallResultStatus> {
override payloadSchema = SchemaData; override payloadSchema = SchemaData;

View File

@@ -0,0 +1,33 @@
import { ActionName } from '@/onebot/action/router';
import { FileNapCatOneBotUUID } from '@/common/file-uuid';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { z } from 'zod';
const SchemaData = z.object({
group_id: z.union([z.number(), z.string()]),
file_id: z.string(),
current_parent_directory: z.string(),
new_name: z.string(),
});
type Payload = z.infer<typeof SchemaData>;
interface RenameGroupFileResponse {
ok: boolean;
}
export class RenameGroupFile extends GetPacketStatusDepends<Payload, RenameGroupFileResponse> {
override actionName = ActionName.RenameGroupFile;
override payloadSchema = SchemaData;
async _handle(payload: Payload) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id) || FileNapCatOneBotUUID.decodeModelId(payload.file_id);
if (contextMsgFile?.fileUUID) {
await this.core.apis.PacketApi.pkt.operation.RenameGroupFile(+payload.group_id, contextMsgFile.fileUUID, payload.current_parent_directory, payload.new_name);
return {
ok: true,
};
}
throw new Error('real fileUUID not found!');
}
}

View File

@@ -1,22 +1,21 @@
import { PacketHexStr } from '@/core/packet/transformer/base'; import { PacketHexStr } from '@/core/packet/transformer/base';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
cmd: Type.String(), cmd: z.string(),
data: Type.String(), data: z.string(),
rsp: Type.Union([Type.String(), Type.Boolean()], { default: true }), rsp: z.boolean().default(true),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SendPacket extends GetPacketStatusDepends<Payload, string | undefined> { export class SendPacket extends GetPacketStatusDepends<Payload, string | undefined> {
override payloadSchema = SchemaData; override payloadSchema = SchemaData;
override actionName = ActionName.SendPacket; override actionName = ActionName.SendPacket;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const rsp = typeof payload.rsp === 'boolean' ? payload.rsp : payload.rsp === 'true'; const data = await this.core.apis.PacketApi.pkt.operation.sendPacket({ cmd: payload.cmd, data: payload.data as PacketHexStr }, payload.rsp);
const data = await this.core.apis.PacketApi.pkt.operation.sendPacket({ cmd: payload.cmd, data: payload.data as PacketHexStr }, rsp);
return typeof data === 'object' ? data.toString('hex') : undefined; return typeof data === 'object' ? data.toString('hex') : undefined;
} }
} }

View File

@@ -1,14 +1,14 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
face_id: Type.Union([Type.Number(), Type.String()]),// 参考 face_config.json 的 QSid face_id: z.union([z.number(), z.string()]),// 参考 face_config.json 的 QSid
face_type: Type.Union([Type.Number(), Type.String()], { default: '1' }), face_type: z.union([z.number(), z.string()]).default('1'),
wording: Type.String({ default: ' ' }), wording: z.string().default(' '),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SetDiyOnlineStatus extends OneBotAction<Payload, string> { export class SetDiyOnlineStatus extends OneBotAction<Payload, string> {
override actionName = ActionName.SetDiyOnlineStatus; override actionName = ActionName.SetDiyOnlineStatus;

View File

@@ -1,13 +1,13 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.String(), group_id: z.string(),
remark: Type.String(), remark: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupRemark extends OneBotAction<Payload, null> { export default class SetGroupRemark extends OneBotAction<Payload, null> {
override actionName = ActionName.SetGroupRemark; override actionName = ActionName.SetGroupRemark;

View File

@@ -1,12 +1,12 @@
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
class SetGroupSignBase extends GetPacketStatusDepends<Payload, void> { class SetGroupSignBase extends GetPacketStatusDepends<Payload, void> {
override payloadSchema = SchemaData; override payloadSchema = SchemaData;

View File

@@ -1,14 +1,14 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { ChatType } from '@/core'; import { ChatType } from '@/core';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
event_type: Type.Number(), event_type: z.number(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SetInputStatus extends OneBotAction<Payload, unknown> { export class SetInputStatus extends OneBotAction<Payload, unknown> {
override actionName = ActionName.SetInputStatus; override actionName = ActionName.SetInputStatus;

View File

@@ -1,12 +1,12 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
longNick: Type.String(), longNick: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SetLongNick extends OneBotAction<Payload, unknown> { export class SetLongNick extends OneBotAction<Payload, unknown> {
override actionName = ActionName.SetLongNick; override actionName = ActionName.SetLongNick;

View File

@@ -1,14 +1,14 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
status: Type.Union([Type.Number(), Type.String()]), status: z.union([z.number(), z.string()]),
ext_status: Type.Union([Type.Number(), Type.String()]), ext_status: z.union([z.number(), z.string()]),
battery_status: Type.Union([Type.Number(), Type.String()]), battery_status: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SetOnlineStatus extends OneBotAction<Payload, null> { export class SetOnlineStatus extends OneBotAction<Payload, null> {
override actionName = ActionName.SetOnlineStatus; override actionName = ActionName.SetOnlineStatus;

View File

@@ -2,13 +2,13 @@ import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import fs from 'node:fs/promises'; import fs from 'node:fs/promises';
import { checkFileExist, uriToLocalFile } from '@/common/file'; import { checkFileExist, uriToLocalFile } from '@/common/file';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
file: Type.String(), file: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetAvatar extends OneBotAction<Payload, null> { export default class SetAvatar extends OneBotAction<Payload, null> {
override actionName = ActionName.SetQQAvatar; override actionName = ActionName.SetQQAvatar;

View File

@@ -1,17 +1,17 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
special_title: Type.String({ default: '' }), special_title: z.string().default(''),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SetSpecialTittle extends GetPacketStatusDepends<Payload, void> { export class SetSpecialTitle extends GetPacketStatusDepends<Payload, void> {
override actionName = ActionName.SetSpecialTittle; override actionName = ActionName.SetSpecialTitle;
override payloadSchema = SchemaData; override payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {

View File

@@ -1,15 +1,15 @@
import { GeneralCallResult } from '@/core'; import { GeneralCallResult } from '@/core';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
user_id: Type.Optional(Type.Union([Type.Number(), Type.String()])), user_id: z.union([z.number(), z.string()]).optional(),
group_id: Type.Optional(Type.Union([Type.Number(), Type.String()])), group_id: z.union([z.number(), z.string()]).optional(),
phoneNumber: Type.String({ default: '' }), phoneNumber: z.string().default(''),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SharePeer extends OneBotAction<Payload, GeneralCallResult & { export class SharePeer extends OneBotAction<Payload, GeneralCallResult & {
arkMsg?: string; arkMsg?: string;
@@ -28,11 +28,11 @@ export class SharePeer extends OneBotAction<Payload, GeneralCallResult & {
} }
} }
const SchemaDataGroupEx = Type.Object({ const SchemaDataGroupEx = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
}); });
type PayloadGroupEx = Static<typeof SchemaDataGroupEx>; type PayloadGroupEx = z.infer<typeof SchemaDataGroupEx>;
export class ShareGroupEx extends OneBotAction<PayloadGroupEx, string> { export class ShareGroupEx extends OneBotAction<PayloadGroupEx, string> {
override actionName = ActionName.ShareGroupEx; override actionName = ActionName.ShareGroupEx;

View File

@@ -0,0 +1,34 @@
import { ActionName } from '@/onebot/action/router';
import { FileNapCatOneBotUUID } from '@/common/file-uuid';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { z } from 'zod';
const SchemaData = z.object({
group_id: z.union([z.number(), z.string()]),
file_id: z.string(),
});
type Payload = z.infer<typeof SchemaData>;
interface TransGroupFileResponse {
ok: boolean;
}
export class TransGroupFile extends GetPacketStatusDepends<Payload, TransGroupFileResponse> {
override actionName = ActionName.TransGroupFile;
override payloadSchema = SchemaData;
async _handle(payload: Payload) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id) || FileNapCatOneBotUUID.decodeModelId(payload.file_id);
if (contextMsgFile?.fileUUID) {
const result = await this.core.apis.GroupApi.transGroupFile(payload.group_id.toString(), contextMsgFile.fileUUID);
if (result.transGroupFileResult.result.retCode === 0) {
return {
ok: true
};
}
throw new Error(result.transGroupFileResult.result.retMsg);
}
throw new Error('real fileUUID not found!');
}
}

View File

@@ -1,12 +1,12 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
words: Type.Array(Type.String()), words: z.array(z.string()),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class TranslateEnWordToZn extends OneBotAction<Payload, Array<unknown> | null> { export class TranslateEnWordToZn extends OneBotAction<Payload, Array<unknown> | null> {
override actionName = ActionName.TranslateEnWordToZn; override actionName = ActionName.TranslateEnWordToZn;

View File

@@ -3,7 +3,7 @@ import fs from 'fs/promises';
import { FileNapCatOneBotUUID } from '@/common/file-uuid'; import { FileNapCatOneBotUUID } from '@/common/file-uuid';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { OB11MessageImage, OB11MessageVideo } from '@/onebot/types'; import { OB11MessageImage, OB11MessageVideo } from '@/onebot/types';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
export interface GetFileResponse { export interface GetFileResponse {
file?: string; // path file?: string; // path
@@ -13,13 +13,13 @@ export interface GetFileResponse {
base64?: string; base64?: string;
} }
const GetFileBase_PayloadSchema = Type.Object({ const GetFileBase_PayloadSchema = z.object({
file: Type.Optional(Type.String()), file: z.string().optional(),
file_id: Type.Optional(Type.String()) file_id: z.string().optional(),
}); });
export type GetFilePayload = Static<typeof GetFileBase_PayloadSchema>; export type GetFilePayload = z.infer<typeof GetFileBase_PayloadSchema>;
export class GetFileBase extends OneBotAction<GetFilePayload, GetFileResponse> { export class GetFileBase extends OneBotAction<GetFilePayload, GetFileResponse> {
override payloadSchema = GetFileBase_PayloadSchema; override payloadSchema = GetFileBase_PayloadSchema;

View File

@@ -1,14 +1,14 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { FileNapCatOneBotUUID } from '@/common/file-uuid'; import { FileNapCatOneBotUUID } from '@/common/file-uuid';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
file_id: Type.String(), file_id: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
interface GetGroupFileUrlResponse { interface GetGroupFileUrlResponse {
url?: string; url?: string;

View File

@@ -1,13 +1,13 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { FileNapCatOneBotUUID } from '@/common/file-uuid'; import { FileNapCatOneBotUUID } from '@/common/file-uuid';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
file_id: Type.String(), file_id: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
interface GetPrivateFileUrlResponse { interface GetPrivateFileUrlResponse {
url?: string; url?: string;

View File

@@ -1,13 +1,13 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
folder_name: Type.String(), folder_name: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
interface ResponseType{ interface ResponseType{
result:unknown; result:unknown;
groupItem:unknown; groupItem:unknown;

View File

@@ -2,15 +2,15 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { FileNapCatOneBotUUID } from '@/common/file-uuid'; import { FileNapCatOneBotUUID } from '@/common/file-uuid';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
import { NTQQGroupApi } from '@/core/apis'; import { NTQQGroupApi } from '@/core/apis';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
file_id: Type.String(), file_id: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class DeleteGroupFile extends OneBotAction<Payload, Awaited<ReturnType<NTQQGroupApi['delGroupFile']>>> { export class DeleteGroupFile extends OneBotAction<Payload, Awaited<ReturnType<NTQQGroupApi['delGroupFile']>>> {
override actionName = ActionName.GOCQHTTP_DeleteGroupFile; override actionName = ActionName.GOCQHTTP_DeleteGroupFile;

View File

@@ -1,15 +1,15 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
import { NTQQGroupApi } from '@/core/apis'; import { NTQQGroupApi } from '@/core/apis';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
folder_id: Type.Optional(Type.String()), folder_id: z.string().optional(),
folder: Type.Optional(Type.String()), folder: z.string().optional(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class DeleteGroupFileFolder extends OneBotAction<Payload, Awaited<ReturnType<NTQQGroupApi['delGroupFileFolder']>>['groupFileCommonResult']> { export class DeleteGroupFileFolder extends OneBotAction<Payload, Awaited<ReturnType<NTQQGroupApi['delGroupFileFolder']>>['groupFileCommonResult']> {
override actionName = ActionName.GoCQHTTP_DeleteGroupFileFolder; override actionName = ActionName.GoCQHTTP_DeleteGroupFileFolder;

View File

@@ -4,20 +4,20 @@ import fs from 'fs';
import { join as joinPath } from 'node:path'; import { join as joinPath } from 'node:path';
import { calculateFileMD5, uriToLocalFile } from '@/common/file'; import { calculateFileMD5, uriToLocalFile } from '@/common/file';
import { randomUUID } from 'crypto'; import { randomUUID } from 'crypto';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
interface FileResponse { interface FileResponse {
file: string; file: string;
} }
const SchemaData = Type.Object({ const SchemaData = z.object({
url: Type.Optional(Type.String()), url: z.string().optional(),
base64: Type.Optional(Type.String()), base64: z.string().optional(),
name: Type.Optional(Type.String()), name: z.string().optional(),
headers: Type.Optional(Type.Union([Type.String(), Type.Array(Type.String())])), headers: z.union([z.string(), z.array(z.string())]).optional(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class GoCQHTTPDownloadFile extends OneBotAction<Payload, FileResponse> { export default class GoCQHTTPDownloadFile extends OneBotAction<Payload, FileResponse> {
override actionName = ActionName.GoCQHTTP_DownloadFile; override actionName = ActionName.GoCQHTTP_DownloadFile;

View File

@@ -2,15 +2,15 @@ import { OneBotAction } from '@/onebot/action/OneBotAction';
import { OB11Message, OB11MessageData, OB11MessageDataType, OB11MessageForward, OB11MessageNodePlain as OB11MessageNode } from '@/onebot'; import { OB11Message, OB11MessageData, OB11MessageDataType, OB11MessageForward, OB11MessageNodePlain as OB11MessageNode } from '@/onebot';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { MessageUnique } from '@/common/message-unique'; import { MessageUnique } from '@/common/message-unique';
import { Static, Type } from '@sinclair/typebox';
import { ChatType, ElementType, MsgSourceType, NTMsgType, RawMessage } from '@/core'; import { ChatType, ElementType, MsgSourceType, NTMsgType, RawMessage } from '@/core';
import { z } from 'zod';
import { isNumeric } from '@/common/helper';
const SchemaData = Type.Object({ const SchemaData = z.object({
message_id: Type.Optional(Type.Union([Type.Number(), Type.String()])), message_id: z.string().optional(),
id: Type.Optional(Type.Union([Type.Number(), Type.String()])), id: z.string().optional(),
}); });
type Payload = z.infer<typeof SchemaData>;
type Payload = Static<typeof SchemaData>;
export class GoCQHTTPGetForwardMsgAction extends OneBotAction<Payload, { export class GoCQHTTPGetForwardMsgAction extends OneBotAction<Payload, {
messages: OB11Message[] | undefined; messages: OB11Message[] | undefined;
@@ -53,19 +53,21 @@ export class GoCQHTTPGetForwardMsgAction extends OneBotAction<Payload, {
} }
async _handle(payload: Payload) { async _handle(payload: Payload) {
// 1. 检查消息ID是否存在
const msgId = payload.message_id || payload.id; const msgId = payload.message_id || payload.id;
if (!msgId) { if (!msgId) {
throw new Error('message_id is required'); throw new Error('message_id is required');
} }
const fakeForwardMsg = (res_id: string) => { // 2. 定义辅助函数 - 创建伪转发消息对象
const createFakeForwardMsg = (resId: string): RawMessage => {
return { return {
chatType: ChatType.KCHATTYPEGROUP, chatType: ChatType.KCHATTYPEGROUP,
elements: [{ elements: [{
elementType: ElementType.MULTIFORWARD, elementType: ElementType.MULTIFORWARD,
elementId: '', elementId: '',
multiForwardMsgElement: { multiForwardMsgElement: {
resId: res_id, resId: resId,
fileName: '', fileName: '',
xmlContent: '', xmlContent: '',
} }
@@ -96,8 +98,9 @@ export class GoCQHTTPGetForwardMsgAction extends OneBotAction<Payload, {
} as RawMessage; } as RawMessage;
}; };
const protocolFallbackLogic = async (res_id: string) => { // 3. 定义协议回退逻辑函数
const ob = (await this.obContext.apis.MsgApi.parseMessageV2(fakeForwardMsg(res_id)))?.arrayMsg; const protocolFallbackLogic = async (resId: string) => {
const ob = (await this.obContext.apis.MsgApi.parseMessageV2(createFakeForwardMsg(resId)))?.arrayMsg;
if (ob) { if (ob) {
return { return {
messages: (ob?.message?.[0] as OB11MessageForward)?.data?.content messages: (ob?.message?.[0] as OB11MessageForward)?.data?.content
@@ -105,31 +108,37 @@ export class GoCQHTTPGetForwardMsgAction extends OneBotAction<Payload, {
} }
throw new Error('protocolFallbackLogic: 找不到相关的聊天记录'); throw new Error('protocolFallbackLogic: 找不到相关的聊天记录');
}; };
// 4. 尝试通过正常渠道获取消息
// 如果是数字ID优先使用getMsgsByMsgId获取
if (!isNumeric(msgId)) {
let ret = await protocolFallbackLogic(msgId);
if (ret.messages) {
return ret;
}
throw new Error('ResId无效: 找不到相关的聊天记录');
}
const rootMsgId = MessageUnique.getShortIdByMsgId(msgId.toString()); const rootMsgId = MessageUnique.getShortIdByMsgId(msgId.toString());
const rootMsg = MessageUnique.getMsgIdAndPeerByShortId(rootMsgId ?? +msgId); const rootMsg = MessageUnique.getMsgIdAndPeerByShortId(rootMsgId ?? +msgId);
if (!rootMsg) {
return await protocolFallbackLogic(msgId.toString());
}
const data = await this.core.apis.MsgApi.getMsgsByMsgId(rootMsg.Peer, [rootMsg.MsgId]);
if (!data || data.result !== 0) { if (rootMsg) {
return await protocolFallbackLogic(msgId.toString()); // 5. 获取消息内容
} const data = await this.core.apis.MsgApi.getMsgsByMsgId(rootMsg.Peer, [rootMsg.MsgId]);
const singleMsg = data.msgList[0]; if (data && data.result === 0 && data.msgList.length > 0) {
if (!singleMsg) { const singleMsg = data.msgList[0];
return await protocolFallbackLogic(msgId.toString()); if (!singleMsg) {
} throw new Error('消息不存在或已过期');
const resMsg = (await this.obContext.apis.MsgApi.parseMessageV2(singleMsg))?.arrayMsg;//强制array 以便处理 }
if (!(resMsg?.message?.[0] as OB11MessageForward)?.data?.content) { // 6. 解析消息内容
return await protocolFallbackLogic(msgId.toString()); const resMsg = (await this.obContext.apis.MsgApi.parseMessageV2(singleMsg))?.arrayMsg;
}
return {
messages: (resMsg?.message?.[0] as OB11MessageForward)?.data?.content
};
//}
// return { message: resMsg }; const forwardContent = (resMsg?.message?.[0] as OB11MessageForward)?.data?.content;
if (forwardContent) {
return { messages: forwardContent };
}
}
}
// 说明消息已过期或者为内层消息 NapCat 一次返回不处理内层消息
throw new Error('消息已过期或者为内层消息,无法获取转发消息');
} }
} }

View File

@@ -3,22 +3,21 @@ import { OB11Message } from '@/onebot';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { ChatType } from '@/core/types'; import { ChatType } from '@/core/types';
import { MessageUnique } from '@/common/message-unique'; import { MessageUnique } from '@/common/message-unique';
import { z } from 'zod';
import { Static, Type } from '@sinclair/typebox';
import { NetworkAdapterConfig } from '@/onebot/config/config'; import { NetworkAdapterConfig } from '@/onebot/config/config';
interface Response { interface Response {
messages: OB11Message[]; messages: OB11Message[];
} }
const SchemaData = Type.Object({ const SchemaData = z.object({
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
message_seq: Type.Optional(Type.Union([Type.Number(), Type.String()])), message_seq: z.union([z.number(), z.string()]).optional(),
count: Type.Union([Type.Number(), Type.String()], { default: 20 }), count: z.union([z.number(), z.string()]).default(20),
reverseOrder: Type.Optional(Type.Union([Type.Boolean(), Type.String()])) reverseOrder: z.boolean().default(false)
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class GetFriendMsgHistory extends OneBotAction<Payload, Response> { export default class GetFriendMsgHistory extends OneBotAction<Payload, Response> {
override actionName = ActionName.GetFriendMsgHistory; override actionName = ActionName.GetFriendMsgHistory;
@@ -27,18 +26,14 @@ export default class GetFriendMsgHistory extends OneBotAction<Payload, Response>
async _handle(payload: Payload, _adapter: string, config: NetworkAdapterConfig): Promise<Response> { async _handle(payload: Payload, _adapter: string, config: NetworkAdapterConfig): Promise<Response> {
//处理参数 //处理参数
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString()); const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
const isReverseOrder = typeof payload.reverseOrder === 'string' ? payload.reverseOrder === 'true' : !!payload.reverseOrder;
if (!uid) throw new Error(`记录${payload.user_id}不存在`); if (!uid) throw new Error(`记录${payload.user_id}不存在`);
const friend = await this.core.apis.FriendApi.isBuddy(uid); const friend = await this.core.apis.FriendApi.isBuddy(uid);
const peer = { chatType: friend ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid: uid }; const peer = { chatType: friend ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid: uid };
const hasMessageSeq = !payload.message_seq ? !!payload.message_seq : !(payload.message_seq?.toString() === '' || payload.message_seq?.toString() === '0'); const hasMessageSeq = !payload.message_seq ? !!payload.message_seq : !(payload.message_seq?.toString() === '' || payload.message_seq?.toString() === '0');
const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0'; const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0';
const msgList = hasMessageSeq ? const msgList = hasMessageSeq ?
(await this.core.apis.MsgApi.getMsgHistory(peer, startMsgId, +payload.count)).msgList : (await this.core.apis.MsgApi.getAioFirstViewLatestMsgs(peer, +payload.count)).msgList; (await this.core.apis.MsgApi.getMsgHistory(peer, startMsgId, +payload.count, payload.reverseOrder)).msgList : (await this.core.apis.MsgApi.getAioFirstViewLatestMsgs(peer, +payload.count)).msgList;
if (msgList.length === 0) throw new Error(`消息${payload.message_seq}不存在`); if (msgList.length === 0) throw new Error(`消息${payload.message_seq}不存在`);
//翻转消息
if (isReverseOrder) msgList.reverse();
//转换序号 //转换序号
await Promise.all(msgList.map(async msg => { await Promise.all(msgList.map(async msg => {
msg.id = MessageUnique.createUniqueMsgId({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId); msg.id = MessageUnique.createUniqueMsgId({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);

View File

@@ -1,12 +1,12 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]) group_id: z.union([z.number(), z.string()])
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
interface ResponseType { interface ResponseType {
can_at_all: boolean; can_at_all: boolean;
remain_at_all_count_for_group: number; remain_at_all_count_for_group: number;

View File

@@ -1,12 +1,12 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]) group_id: z.union([z.number(), z.string()])
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetGroupFileSystemInfo extends OneBotAction<Payload, { export class GetGroupFileSystemInfo extends OneBotAction<Payload, {
file_count: number, file_count: number,

View File

@@ -2,16 +2,16 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { OB11Construct } from '@/onebot/helper/data'; import { OB11Construct } from '@/onebot/helper/data';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
folder_id: Type.Optional(Type.String()), folder_id: z.string().optional(),
folder: Type.Optional(Type.String()), folder: z.string().optional(),
file_count: Type.Union([Type.Number(), Type.String()], { default: 50 }), file_count: z.union([z.number(), z.string()]).default(50),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetGroupFilesByFolder extends OneBotAction<Payload, { export class GetGroupFilesByFolder extends OneBotAction<Payload, {
files: ReturnType<typeof OB11Construct.file>[], files: ReturnType<typeof OB11Construct.file>[],

View File

@@ -1,16 +1,16 @@
import { WebHonorType } from '@/core';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { WebHonorType } from '@/core/types'; import { z } from 'zod';
import { Static, Type } from '@sinclair/typebox';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
type: Type.Optional(Type.Enum(WebHonorType)) type: z.nativeEnum(WebHonorType).optional()
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetGroupHonorInfo extends OneBotAction<Payload, Array<unknown>> { export class GetGroupHonorInfo extends OneBotAction<Payload, unknown> {
override actionName = ActionName.GetGroupHonorInfo; override actionName = ActionName.GetGroupHonorInfo;
override payloadSchema = SchemaData; override payloadSchema = SchemaData;

View File

@@ -3,22 +3,22 @@ import { OB11Message } from '@/onebot';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { ChatType, Peer } from '@/core/types'; import { ChatType, Peer } from '@/core/types';
import { MessageUnique } from '@/common/message-unique'; import { MessageUnique } from '@/common/message-unique';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
import { NetworkAdapterConfig } from '@/onebot/config/config'; import { NetworkAdapterConfig } from '@/onebot/config/config';
interface Response { interface Response {
messages: OB11Message[]; messages: OB11Message[];
} }
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
message_seq: Type.Optional(Type.Union([Type.Number(), Type.String()])), message_seq: z.union([z.number(), z.string()]).optional(),
count: Type.Union([Type.Number(), Type.String()], { default: 20 }), count: z.union([z.number(), z.string()]).default(20),
reverseOrder: Type.Optional(Type.Union([Type.Boolean(), Type.String()])) reverseOrder: z.boolean().default(false)
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class GoCQHTTPGetGroupMsgHistory extends OneBotAction<Payload, Response> { export default class GoCQHTTPGetGroupMsgHistory extends OneBotAction<Payload, Response> {
@@ -26,17 +26,13 @@ export default class GoCQHTTPGetGroupMsgHistory extends OneBotAction<Payload, Re
override payloadSchema = SchemaData; override payloadSchema = SchemaData;
async _handle(payload: Payload, _adapter: string, config: NetworkAdapterConfig): Promise<Response> { async _handle(payload: Payload, _adapter: string, config: NetworkAdapterConfig): Promise<Response> {
//处理参数
const isReverseOrder = typeof payload.reverseOrder === 'string' ? payload.reverseOrder === 'true' : !!payload.reverseOrder;
const peer: Peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: payload.group_id.toString() }; const peer: Peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: payload.group_id.toString() };
const hasMessageSeq = !payload.message_seq ? !!payload.message_seq : !(payload.message_seq?.toString() === '' || payload.message_seq?.toString() === '0'); const hasMessageSeq = !payload.message_seq ? !!payload.message_seq : !(payload.message_seq?.toString() === '' || payload.message_seq?.toString() === '0');
//拉取消息 //拉取消息
const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0'; const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0';
const msgList = hasMessageSeq ? const msgList = hasMessageSeq ?
(await this.core.apis.MsgApi.getMsgHistory(peer, startMsgId, +payload.count)).msgList : (await this.core.apis.MsgApi.getAioFirstViewLatestMsgs(peer, +payload.count)).msgList; (await this.core.apis.MsgApi.getMsgHistory(peer, startMsgId, +payload.count, payload.reverseOrder)).msgList : (await this.core.apis.MsgApi.getAioFirstViewLatestMsgs(peer, +payload.count)).msgList;
if (msgList.length === 0) throw new Error(`消息${payload.message_seq}不存在`); if (msgList.length === 0) throw new Error(`消息${payload.message_seq}不存在`);
//翻转消息
if (isReverseOrder) msgList.reverse();
//转换序号 //转换序号
await Promise.all(msgList.map(async msg => { await Promise.all(msgList.map(async msg => {
msg.id = MessageUnique.createUniqueMsgId({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId); msg.id = MessageUnique.createUniqueMsgId({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);

View File

@@ -3,14 +3,14 @@ import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { OB11GroupFile, OB11GroupFileFolder } from '@/onebot'; import { OB11GroupFile, OB11GroupFileFolder } from '@/onebot';
import { OB11Construct } from '@/onebot/helper/data'; import { OB11Construct } from '@/onebot/helper/data';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
file_count: Type.Union([Type.Number(), Type.String()], { default: 50 }), file_count: z.union([z.number(), z.string()]).default(50),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetGroupRootFiles extends OneBotAction<Payload, { export class GetGroupRootFiles extends OneBotAction<Payload, {
files: OB11GroupFile[], files: OB11GroupFile[],

View File

@@ -3,14 +3,14 @@ import { OB11User, OB11UserSex } from '@/onebot';
import { OB11Construct } from '@/onebot/helper/data'; import { OB11Construct } from '@/onebot/helper/data';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { calcQQLevel } from '@/common/helper'; import { calcQQLevel } from '@/common/helper';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
no_cache: Type.Union([Type.Boolean(), Type.String()], { default: false }), no_cache: z.boolean().default(false),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class GoCQHTTPGetStrangerInfo extends OneBotAction<Payload, OB11User & { uid: string }> { export default class GoCQHTTPGetStrangerInfo extends OneBotAction<Payload, OB11User & { uid: string }> {
override actionName = ActionName.GoCQHTTP_GetStrangerInfo; override actionName = ActionName.GoCQHTTP_GetStrangerInfo;

View File

@@ -1,12 +1,12 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
url: Type.String(), url: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GoCQHTTPCheckUrlSafely extends OneBotAction<Payload, { level: number }> { export class GoCQHTTPCheckUrlSafely extends OneBotAction<Payload, { level: number }> {
override actionName = ActionName.GoCQHTTP_CheckUrlSafely; override actionName = ActionName.GoCQHTTP_CheckUrlSafely;

View File

@@ -1,15 +1,15 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
friend_id: Type.Optional(Type.Union([Type.String(), Type.Number()])), friend_id: z.union([z.string(), z.number()]).optional(),
user_id: Type.Optional(Type.Union([Type.String(), Type.Number()])), user_id: z.union([z.string(), z.number()]).optional(),
temp_block: Type.Optional(Type.Boolean()), temp_block: z.boolean().optional(),
temp_both_del: Type.Optional(Type.Boolean()), temp_both_del: z.boolean().optional(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GoCQHTTPDeleteFriend extends OneBotAction<Payload, unknown> { export class GoCQHTTPDeleteFriend extends OneBotAction<Payload, unknown> {
override actionName = ActionName.GoCQHTTP_DeleteFriend; override actionName = ActionName.GoCQHTTP_DeleteFriend;

View File

@@ -1,12 +1,12 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
model: Type.String(), model: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GoCQHTTPGetModelShow extends OneBotAction<Payload, Array<{ export class GoCQHTTPGetModelShow extends OneBotAction<Payload, Array<{
variants: { variants: {

View File

@@ -2,20 +2,20 @@ import { checkFileExist, uriToLocalFile } from '@/common/file';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { unlink } from 'node:fs/promises'; import { unlink } from 'node:fs/promises';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
content: Type.String(), content: z.string(),
image: Type.Optional(Type.String()), image: z.string().optional(),
pinned: Type.Union([Type.Number(), Type.String()], { default: 0 }), pinned: z.union([z.number(), z.string()]).default(0),
type: Type.Union([Type.Number(), Type.String()], { default: 1 }), type: z.union([z.number(), z.string()]).default(1),
confirm_required: Type.Union([Type.Number(), Type.String()], { default: 1 }), confirm_required: z.union([z.number(), z.string()]).default(1),
is_show_edit_card: Type.Union([Type.Number(), Type.String()], { default: 0 }), is_show_edit_card: z.union([z.number(), z.string()]).default(0),
tip_window_type: Type.Union([Type.Number(), Type.String()], { default: 0 }) tip_window_type: z.union([z.number(), z.string()]).default(0),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SendGroupNotice extends OneBotAction<Payload, null> { export class SendGroupNotice extends OneBotAction<Payload, null> {
override actionName = ActionName.GoCQHTTP_SendGroupNotice; override actionName = ActionName.GoCQHTTP_SendGroupNotice;

View File

@@ -1,15 +1,15 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { checkFileExistV2, uriToLocalFile } from '@/common/file'; import { checkFileExistV2, uriToLocalFile } from '@/common/file';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
import fs from 'node:fs/promises'; import fs from 'node:fs/promises';
import { GeneralCallResult } from '@/core'; import { GeneralCallResult } from '@/core';
const SchemaData = Type.Object({ const SchemaData = z.object({
file: Type.String(), file: z.string(),
group_id: Type.Union([Type.Number(), Type.String()]) group_id: z.union([z.number(), z.string()])
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupPortrait extends OneBotAction<Payload, GeneralCallResult> { export default class SetGroupPortrait extends OneBotAction<Payload, GeneralCallResult> {
override actionName = ActionName.SetGroupPortrait; override actionName = ActionName.SetGroupPortrait;

View File

@@ -1,15 +1,15 @@
import { NTQQUserApi } from '@/core/apis'; import { NTQQUserApi } from '@/core/apis';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
nickname: Type.String(), nickname: z.string(),
personal_note: Type.Optional(Type.String()), personal_note: z.string().optional(),
sex: Type.Optional(Type.Union([Type.Number(), Type.String()])), // 传Sex值建议传0 sex: z.union([z.number(), z.string()]).optional(), // 传Sex值建议传0
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SetQQProfile extends OneBotAction<Payload, Awaited<ReturnType<NTQQUserApi['modifySelfProfile']>> | null> { export class SetQQProfile extends OneBotAction<Payload, Awaited<ReturnType<NTQQUserApi['modifySelfProfile']>> | null> {
override actionName = ActionName.SetQQProfile; override actionName = ActionName.SetQQProfile;
override payloadSchema = SchemaData; override payloadSchema = SchemaData;

View File

@@ -4,17 +4,17 @@ import { ChatType, Peer } from '@/core/types';
import fs from 'fs'; import fs from 'fs';
import { uriToLocalFile } from '@/common/file'; import { uriToLocalFile } from '@/common/file';
import { SendMessageContext } from '@/onebot/api'; import { SendMessageContext } from '@/onebot/api';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
file: Type.String(), file: z.string(),
name: Type.String(), name: z.string(),
folder: Type.Optional(Type.String()), folder: z.string().optional(),
folder_id: Type.Optional(Type.String()),//临时扩展 folder_id: z.string().optional(),//临时扩展
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class GoCQHTTPUploadGroupFile extends OneBotAction<Payload, null> { export default class GoCQHTTPUploadGroupFile extends OneBotAction<Payload, null> {
override actionName = ActionName.GoCQHTTP_UploadGroupFile; override actionName = ActionName.GoCQHTTP_UploadGroupFile;

View File

@@ -5,15 +5,15 @@ import fs from 'fs';
import { uriToLocalFile } from '@/common/file'; import { uriToLocalFile } from '@/common/file';
import { SendMessageContext } from '@/onebot/api'; import { SendMessageContext } from '@/onebot/api';
import { ContextMode, createContext } from '@/onebot/action/msg/SendMsg'; import { ContextMode, createContext } from '@/onebot/action/msg/SendMsg';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
file: Type.String(), file: z.string(),
name: Type.String(), name: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class GoCQHTTPUploadPrivateFile extends OneBotAction<Payload, null> { export default class GoCQHTTPUploadPrivateFile extends OneBotAction<Payload, null> {
override actionName = ActionName.GOCQHTTP_UploadPrivateFile; override actionName = ActionName.GOCQHTTP_UploadPrivateFile;

View File

@@ -1,13 +1,13 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { MessageUnique } from '@/common/message-unique'; import { MessageUnique } from '@/common/message-unique';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
message_id: Type.Union([Type.Number(), Type.String()]), message_id: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class DelEssenceMsg extends OneBotAction<Payload, unknown> { export default class DelEssenceMsg extends OneBotAction<Payload, unknown> {
override actionName = ActionName.DelEssenceMsg; override actionName = ActionName.DelEssenceMsg;
override payloadSchema = SchemaData; override payloadSchema = SchemaData;

View File

@@ -1,13 +1,13 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
notice_id: Type.String() notice_id: z.string()
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class DelGroupNotice extends OneBotAction<Payload, void> { export class DelGroupNotice extends OneBotAction<Payload, void> {
override actionName = ActionName.DelGroupNotice; override actionName = ActionName.DelGroupNotice;

View File

@@ -1,15 +1,15 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { AIVoiceChatType } from '@/core/packet/entities/aiChat'; import { AIVoiceChatType } from '@/core/packet/entities/aiChat';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
character: Type.String(), character: z.string(),
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
text: Type.String(), text: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetAiRecord extends GetPacketStatusDepends<Payload, string> { export class GetAiRecord extends GetPacketStatusDepends<Payload, string> {
override actionName = ActionName.GetAiRecord; override actionName = ActionName.GetAiRecord;

View File

@@ -3,14 +3,14 @@ import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { MessageUnique } from '@/common/message-unique'; import { MessageUnique } from '@/common/message-unique';
import crypto from 'crypto'; import crypto from 'crypto';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
import { NetworkAdapterConfig } from '@/onebot/config/config'; import { NetworkAdapterConfig } from '@/onebot/config/config';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetGroupEssence extends OneBotAction<Payload, unknown> { export class GetGroupEssence extends OneBotAction<Payload, unknown> {
override actionName = ActionName.GoCQHTTP_GetEssenceMsg; override actionName = ActionName.GoCQHTTP_GetEssenceMsg;

View File

@@ -2,13 +2,13 @@ import { OB11Group } from '@/onebot';
import { OB11Construct } from '@/onebot/helper/data'; import { OB11Construct } from '@/onebot/helper/data';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
class GetGroupInfo extends OneBotAction<Payload, OB11Group> { class GetGroupInfo extends OneBotAction<Payload, OB11Group> {
override actionName = ActionName.GetGroupInfo; override actionName = ActionName.GetGroupInfo;
@@ -20,6 +20,7 @@ class GetGroupInfo extends OneBotAction<Payload, OB11Group> {
const data = await this.core.apis.GroupApi.fetchGroupDetail(payload.group_id.toString()); const data = await this.core.apis.GroupApi.fetchGroupDetail(payload.group_id.toString());
return { return {
...data, ...data,
group_all_shut: data.shutUpAllTimestamp > 0 ? -1 : 0,
group_remark: '', group_remark: '',
group_id: +payload.group_id, group_id: +payload.group_id,
group_name: data.groupName, group_name: data.groupName,

View File

@@ -2,13 +2,13 @@ import { OB11Group } from '@/onebot';
import { OB11Construct } from '@/onebot/helper/data'; import { OB11Construct } from '@/onebot/helper/data';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
no_cache: Type.Optional(Type.Union([Type.Boolean(), Type.String()])), no_cache: z.boolean().default(false),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
class GetGroupList extends OneBotAction<Payload, OB11Group[]> { class GetGroupList extends OneBotAction<Payload, OB11Group[]> {
override actionName = ActionName.GetGroupList; override actionName = ActionName.GetGroupList;

View File

@@ -2,15 +2,15 @@ import { OB11GroupMember } from '@/onebot';
import { OB11Construct } from '@/onebot/helper/data'; import { OB11Construct } from '@/onebot/helper/data';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
no_cache: Type.Optional(Type.Union([Type.Boolean(), Type.String()])), no_cache: z.boolean().default(false),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
class GetGroupMemberInfo extends OneBotAction<Payload, OB11GroupMember> { class GetGroupMemberInfo extends OneBotAction<Payload, OB11GroupMember> {
override actionName = ActionName.GetGroupMemberInfo; override actionName = ActionName.GetGroupMemberInfo;

View File

@@ -2,15 +2,15 @@ import { OB11GroupMember } from '@/onebot';
import { OB11Construct } from '@/onebot/helper/data'; import { OB11Construct } from '@/onebot/helper/data';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
import { GroupMember } from '@/core'; import { GroupMember } from '@/core';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
no_cache: Type.Optional(Type.Union([Type.Boolean(), Type.String()])) no_cache: z.boolean().default(false)
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetGroupMemberList extends OneBotAction<Payload, OB11GroupMember[]> { export class GetGroupMemberList extends OneBotAction<Payload, OB11GroupMember[]> {
override actionName = ActionName.GetGroupMemberList; override actionName = ActionName.GetGroupMemberList;

View File

@@ -1,7 +1,7 @@
import { WebApiGroupNoticeFeed } from '@/core'; import { WebApiGroupNoticeFeed } from '@/core';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
interface GroupNotice { interface GroupNotice {
sender_id: number; sender_id: number;
publish_time: number; publish_time: number;
@@ -16,11 +16,11 @@ interface GroupNotice {
}; };
} }
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
type ApiGroupNotice = GroupNotice & WebApiGroupNoticeFeed; type ApiGroupNotice = GroupNotice & WebApiGroupNoticeFeed;

View File

@@ -1,13 +1,13 @@
import { ShutUpGroupMember } from '@/core'; import { ShutUpGroupMember } from '@/core';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GetGroupShutList extends OneBotAction<Payload, ShutUpGroupMember[]> { export class GetGroupShutList extends OneBotAction<Payload, ShutUpGroupMember[]> {
override actionName = ActionName.GetGroupShutList; override actionName = ActionName.GetGroupShutList;

View File

@@ -1,13 +1,13 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class GroupPoke extends GetPacketStatusDepends<Payload, void> { export class GroupPoke extends GetPacketStatusDepends<Payload, void> {
override actionName = ActionName.GroupPoke; override actionName = ActionName.GroupPoke;

View File

@@ -1,15 +1,15 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
import { AIVoiceChatType } from '@/core/packet/entities/aiChat'; import { AIVoiceChatType } from '@/core/packet/entities/aiChat';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
character: Type.String(), character: z.string(),
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
text: Type.String(), text: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export class SendGroupAiRecord extends GetPacketStatusDepends<Payload, { export class SendGroupAiRecord extends GetPacketStatusDepends<Payload, {

View File

@@ -1,13 +1,13 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { MessageUnique } from '@/common/message-unique'; import { MessageUnique } from '@/common/message-unique';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
message_id: Type.Union([Type.Number(), Type.String()]), message_id: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetEssenceMsg extends OneBotAction<Payload, unknown> { export default class SetEssenceMsg extends OneBotAction<Payload, unknown> {
override actionName = ActionName.SetEssenceMsg; override actionName = ActionName.SetEssenceMsg;

View File

@@ -1,15 +1,15 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { NTGroupRequestOperateTypes } from '@/core/types'; import { NTGroupRequestOperateTypes } from '@/core/types';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
flag: Type.Union([Type.String(), Type.Number()]), flag: z.union([z.string(), z.number()]),
approve: Type.Optional(Type.Union([Type.Boolean(), Type.String()])), approve: z.boolean().default(true),
reason: Type.Optional(Type.Union([Type.String({ default: ' ' }), Type.Null()])), reason: z.union([z.string(), z.null()]).default(' '),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupAddRequest extends OneBotAction<Payload, null> { export default class SetGroupAddRequest extends OneBotAction<Payload, null> {
override actionName = ActionName.SetGroupAddRequest; override actionName = ActionName.SetGroupAddRequest;

View File

@@ -1,15 +1,15 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { NTGroupMemberRole } from '@/core/types'; import { NTGroupMemberRole } from '@/core/types';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
enable: Type.Optional(Type.Union([Type.Boolean(), Type.String()])), enable: z.boolean().default(false),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupAdmin extends OneBotAction<Payload, null> { export default class SetGroupAdmin extends OneBotAction<Payload, null> {
override actionName = ActionName.SetGroupAdmin; override actionName = ActionName.SetGroupAdmin;

View File

@@ -1,14 +1,14 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
duration: Type.Union([Type.Number(), Type.String()], { default: 0 }), duration: z.union([z.number(), z.string()]).default(0),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupBan extends OneBotAction<Payload, null> { export default class SetGroupBan extends OneBotAction<Payload, null> {
override actionName = ActionName.SetGroupBan; override actionName = ActionName.SetGroupBan;

View File

@@ -1,14 +1,14 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
card: Type.Optional(Type.String()) card: z.string().optional(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupCard extends OneBotAction<Payload, null> { export default class SetGroupCard extends OneBotAction<Payload, null> {
override actionName = ActionName.SetGroupCard; override actionName = ActionName.SetGroupCard;

View File

@@ -1,14 +1,14 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
user_id: Type.Union([Type.Number(), Type.String()]), user_id: z.union([z.number(), z.string()]),
reject_add_request: Type.Optional(Type.Union([Type.Boolean(), Type.String()])), reject_add_request: z.union([z.boolean(), z.string()]).optional(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupKick extends OneBotAction<Payload, null> { export default class SetGroupKick extends OneBotAction<Payload, null> {
override actionName = ActionName.SetGroupKick; override actionName = ActionName.SetGroupKick;

View File

@@ -1,13 +1,13 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
is_dismiss: Type.Optional(Type.Union([Type.Boolean(), Type.String()])), is_dismiss: z.boolean().optional(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupLeave extends OneBotAction<Payload, void> { export default class SetGroupLeave extends OneBotAction<Payload, void> {
override actionName = ActionName.SetGroupLeave; override actionName = ActionName.SetGroupLeave;

View File

@@ -1,14 +1,14 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
group_name: Type.String(), group_name: z.string(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupName extends OneBotAction<Payload, null> { export default class SetGroupName extends OneBotAction<Payload, null> {
override actionName = ActionName.SetGroupName; override actionName = ActionName.SetGroupName;

View File

@@ -1,13 +1,13 @@
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
group_id: Type.Union([Type.Number(), Type.String()]), group_id: z.union([z.number(), z.string()]),
enable: Type.Optional(Type.Union([Type.Boolean(), Type.String()])), enable: z.union([z.boolean(), z.string()]).optional(),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
export default class SetGroupWholeBan extends OneBotAction<Payload, null> { export default class SetGroupWholeBan extends OneBotAction<Payload, null> {
override actionName = ActionName.SetGroupWholeBan; override actionName = ActionName.SetGroupWholeBan;

View File

@@ -81,7 +81,7 @@ import { GetGroupSystemMsg } from './system/GetSystemMsg';
import { GroupPoke } from './group/GroupPoke'; import { GroupPoke } from './group/GroupPoke';
import { GetUserStatus } from './extends/GetUserStatus'; import { GetUserStatus } from './extends/GetUserStatus';
import { GetRkey } from './extends/GetRkey'; import { GetRkey } from './extends/GetRkey';
import { SetSpecialTittle } from './extends/SetSpecialTittle'; import { SetSpecialTitle } from './extends/SetSpecialTitle';
import { GetGroupShutList } from './group/GetGroupShutList'; import { GetGroupShutList } from './group/GetGroupShutList';
import { GetGroupMemberList } from './group/GetGroupMemberList'; import { GetGroupMemberList } from './group/GetGroupMemberList';
import { GetGroupFileUrl } from '@/onebot/action/file/GetGroupFileUrl'; import { GetGroupFileUrl } from '@/onebot/action/file/GetGroupFileUrl';
@@ -109,10 +109,17 @@ import { ClickInlineKeyboardButton } from './extends/ClickInlineKeyboardButton';
import { GetPrivateFileUrl } from './file/GetPrivateFileUrl'; import { GetPrivateFileUrl } from './file/GetPrivateFileUrl';
import { GetUnidirectionalFriendList } from './extends/GetUnidirectionalFriendList'; import { GetUnidirectionalFriendList } from './extends/GetUnidirectionalFriendList';
import SetGroupRemark from './extends/SetGroupRemark'; import SetGroupRemark from './extends/SetGroupRemark';
import { MoveGroupFile } from './extends/MoveGroupFile';
import { TransGroupFile } from './extends/TransGroupFile';
import { RenameGroupFile } from './extends/RenameGroupFile';
import { GetRkeyServer } from './packet/GetRkeyServer';
import { GetRkeyEx } from './packet/GetRkeyEx';
export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore) { export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore) {
const actionHandlers = [ const actionHandlers = [
new GetRkeyEx(obContext, core),
new GetRkeyServer(obContext, core),
new SetGroupRemark(obContext, core), new SetGroupRemark(obContext, core),
new GetGroupInfoEx(obContext, core), new GetGroupInfoEx(obContext, core),
new FetchEmojiLike(obContext, core), new FetchEmojiLike(obContext, core),
@@ -132,6 +139,9 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo
new SetGroupSign(obContext, core), new SetGroupSign(obContext, core),
new SendGroupSign(obContext, core), new SendGroupSign(obContext, core),
new GetClientkey(obContext, core), new GetClientkey(obContext, core),
new MoveGroupFile(obContext, core),
new RenameGroupFile(obContext, core),
new TransGroupFile(obContext, core),
// onebot11 // onebot11
new SendLike(obContext, core), new SendLike(obContext, core),
new GetMsg(obContext, core), new GetMsg(obContext, core),
@@ -215,7 +225,7 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo
new FriendPoke(obContext, core), new FriendPoke(obContext, core),
new GetUserStatus(obContext, core), new GetUserStatus(obContext, core),
new GetRkey(obContext, core), new GetRkey(obContext, core),
new SetSpecialTittle(obContext, core), new SetSpecialTitle(obContext, core),
new SetDiyOnlineStatus(obContext, core), new SetDiyOnlineStatus(obContext, core),
// new UploadForwardMsg(obContext, core), // new UploadForwardMsg(obContext, core),
new GetGroupShutList(obContext, core), new GetGroupShutList(obContext, core),

View File

@@ -1,13 +1,13 @@
import { ActionName } from '@/onebot/action/router'; import { ActionName } from '@/onebot/action/router';
import { OneBotAction } from '@/onebot/action/OneBotAction'; import { OneBotAction } from '@/onebot/action/OneBotAction';
import { MessageUnique } from '@/common/message-unique'; import { MessageUnique } from '@/common/message-unique';
import { Static, Type } from '@sinclair/typebox'; import { z } from 'zod';
const SchemaData = Type.Object({ const SchemaData = z.object({
message_id: Type.Union([Type.Number(), Type.String()]), message_id: z.union([z.number(), z.string()]),
}); });
type Payload = Static<typeof SchemaData>; type Payload = z.infer<typeof SchemaData>;
class DeleteMsg extends OneBotAction<Payload, void> { class DeleteMsg extends OneBotAction<Payload, void> {
override actionName = ActionName.DeleteMsg; override actionName = ActionName.DeleteMsg;

Some files were not shown because too many files have changed in this diff Show More