mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-02-05 07:01:16 +00:00
Moved action example files into a new 'example' directory and updated all imports accordingly. Removed the monolithic 'examples.ts' and redefined ActionExamples in OneBotAction.ts to only include common error codes. This improves code organization and maintainability.
111 lines
4.8 KiB
TypeScript
111 lines
4.8 KiB
TypeScript
import { ActionName, BaseCheckResult } from './router';
|
|
import Ajv, { ErrorObject, ValidateFunction } from 'ajv';
|
|
import { NapCatCore } from 'napcat-core';
|
|
import { NapCatOneBot11Adapter, OB11Return } from '@/napcat-onebot/index';
|
|
import { NetworkAdapterConfig } from '../config/config';
|
|
import { TSchema } from '@sinclair/typebox';
|
|
import { StreamPacket, StreamPacketBasic, StreamStatus } from './stream/StreamBasic';
|
|
export const ActionExamples = {
|
|
Common: {
|
|
errors: [
|
|
{ code: 1400, description: '请求参数错误或业务逻辑执行失败' },
|
|
{ code: 1401, description: '权限不足' },
|
|
{ code: 1404, description: '资源不存在' }
|
|
]
|
|
}
|
|
};
|
|
|
|
export class OB11Response {
|
|
private static createResponse<T> (data: T, status: string, retcode: number, message: string = '', echo: unknown = null, useStream: boolean = false): OB11Return<T> {
|
|
return {
|
|
status,
|
|
retcode,
|
|
data,
|
|
message,
|
|
wording: message,
|
|
echo,
|
|
stream: useStream ? 'stream-action' : 'normal-action',
|
|
};
|
|
}
|
|
|
|
static res<T> (data: T, status: string, retcode: number, message: string = '', echo: unknown = null, useStream: boolean = false): OB11Return<T> {
|
|
return this.createResponse(data, status, retcode, message, echo, useStream);
|
|
}
|
|
|
|
static ok<T> (data: T, echo: unknown = null, useStream: boolean = false): OB11Return<T> {
|
|
return this.createResponse(data, 'ok', 0, '', echo, useStream);
|
|
}
|
|
|
|
static error (err: string, retcode: number, echo: unknown = null, useStream: boolean = false): OB11Return<null | StreamPacketBasic> {
|
|
return this.createResponse(useStream ? { type: StreamStatus.Error, data_type: 'error' } : null, 'failed', retcode, err, echo, useStream);
|
|
}
|
|
}
|
|
export abstract class OneBotRequestToolkit {
|
|
abstract send<T> (packet: StreamPacket<T>): Promise<void>;
|
|
}
|
|
export abstract class OneBotAction<PayloadType, ReturnDataType> {
|
|
actionName: typeof ActionName[keyof typeof ActionName] = ActionName.Unknown;
|
|
core: NapCatCore;
|
|
private validate?: ValidateFunction<unknown> = undefined;
|
|
payloadSchema?: TSchema = undefined;
|
|
returnSchema?: TSchema = undefined;
|
|
payloadExample?: unknown = undefined;
|
|
returnExample?: unknown = undefined;
|
|
actionSummary: string = '';
|
|
actionDescription: string = '';
|
|
actionTags: string[] = [];
|
|
obContext: NapCatOneBot11Adapter;
|
|
useStream: boolean = false;
|
|
errorExamples: Array<{ code: number, description: string; }> = ActionExamples.Common.errors;
|
|
|
|
constructor (obContext: NapCatOneBot11Adapter, core: NapCatCore) {
|
|
this.obContext = obContext;
|
|
this.core = core;
|
|
}
|
|
|
|
protected async check (payload: PayloadType): Promise<BaseCheckResult> {
|
|
if (this.payloadSchema) {
|
|
this.validate = new Ajv({ allowUnionTypes: true, useDefaults: true, coerceTypes: true }).compile(this.payloadSchema);
|
|
}
|
|
if (this.validate && !this.validate(payload)) {
|
|
const errors = this.validate.errors as ErrorObject[];
|
|
const errorMessages = errors.map(e => `Key: ${e.instancePath.split('/').slice(1).join('.')}, Message: ${e.message}`);
|
|
return {
|
|
valid: false,
|
|
message: errorMessages.join('\n') ?? '未知错误',
|
|
};
|
|
}
|
|
return { valid: true };
|
|
}
|
|
|
|
public async handle (payload: PayloadType, adaptername: string, config: NetworkAdapterConfig, req: OneBotRequestToolkit = { send: async () => { } }, echo?: string): Promise<OB11Return<ReturnDataType | StreamPacketBasic | null>> {
|
|
const result = await this.check(payload);
|
|
if (!result.valid) {
|
|
return OB11Response.error(result.message, 400);
|
|
}
|
|
try {
|
|
const resData = await this._handle(payload, adaptername, config, req);
|
|
return OB11Response.ok(resData, echo, this.useStream);
|
|
} catch (e: unknown) {
|
|
this.core.context.logger.logError('发生错误', e);
|
|
return OB11Response.error((e as Error).message.toString() || (e as Error)?.stack?.toString() || '未知错误,可能操作超时', 200, echo, this.useStream);
|
|
}
|
|
}
|
|
|
|
public async websocketHandle (payload: PayloadType, echo: unknown, adaptername: string, config: NetworkAdapterConfig, req: OneBotRequestToolkit = { send: async () => { } }): Promise<OB11Return<ReturnDataType | StreamPacketBasic | null>> {
|
|
const result = await this.check(payload);
|
|
if (!result.valid) {
|
|
return OB11Response.error(result.message, 1400, echo, this.useStream);
|
|
}
|
|
try {
|
|
const resData = await this._handle(payload, adaptername, config, req);
|
|
return OB11Response.ok(resData, echo, this.useStream);
|
|
} catch (e: unknown) {
|
|
this.core.context.logger.logError('发生错误', e);
|
|
return OB11Response.error(((e as Error).message.toString() || (e as Error).stack?.toString()) ?? 'Error', 1200, echo, this.useStream);
|
|
}
|
|
}
|
|
|
|
abstract _handle (payload: PayloadType, adaptername: string, config: NetworkAdapterConfig, req: OneBotRequestToolkit): Promise<ReturnDataType>;
|
|
}
|