Add actionSummary and improve action metadata

Introduces the actionSummary property to OneBotAction and updates all action classes to provide concise summaries and improved descriptions. Refactors example imports for better modularity, adds new example files for guild and packet actions, and updates the OpenAPI schema generator to use the new summary and improved descriptions. This enhances API documentation clarity and consistency.
This commit is contained in:
手瓜一十雪 2026-01-25 18:06:24 +08:00
parent 7784dd9d7b
commit e6687750eb
24 changed files with 116 additions and 37 deletions

View File

@ -43,6 +43,7 @@ export abstract class OneBotAction<PayloadType, ReturnDataType> {
returnSchema?: TSchema = undefined;
payloadExample?: unknown = undefined;
returnExample?: unknown = undefined;
actionSummary: string = '';
actionDescription: string = '';
actionTags: string[] = [];
obContext: NapCatOneBot11Adapter;

View File

@ -32,7 +32,8 @@ export class GetAiCharacters extends GetPacketStatusDepends<PayloadType, ReturnT
override actionName = ActionName.GetAiCharacters;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取AI角色列表';
override actionSummary = '获取 AI 角色列表';
override actionDescription = '获取群聊中的 AI 角色列表';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.GetAiCharacters.payload;
override returnExample = ActionExamples.GetAiCharacters.return;

View File

@ -14,7 +14,8 @@ export class GetClientkey extends OneBotAction<void, ReturnType> {
override actionName = ActionName.GetClientkey;
override payloadSchema = Type.Void();
override returnSchema = ReturnSchema;
override actionDescription = '获取 ClientKey';
override actionSummary = '获取 ClientKey';
override actionDescription = '获取当前登录帐号的 ClientKey';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.GetClientkey.payload;
override returnExample = ActionExamples.GetClientkey.return;

View File

@ -19,7 +19,8 @@ type ReturnType = Static<typeof ReturnSchema>;
class OCRImageBase extends OneBotAction<PayloadType, ReturnType> {
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '图片 OCR 识别';
override actionSummary = '图片 OCR 识别';
override actionDescription = '识别图片中的文字内容';
override actionTags = ['扩展接口'];
override payloadExample = ExtendsActionsExamples.OCRImage.payload;
@ -46,8 +47,10 @@ class OCRImageBase extends OneBotAction<PayloadType, ReturnType> {
export class OCRImage extends OCRImageBase {
override actionName = ActionName.OCRImage;
override actionSummary = '图片 OCR 识别';
}
export class IOCRImage extends OCRImageBase {
override actionName = ActionName.IOCRImage;
override actionSummary = '图片 OCR 识别 (内部)';
}

View File

@ -1,6 +1,7 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ExtendsActionsExamples } from './examples';
const PayloadSchema = Type.Object({
longNick: Type.String({ description: '签名内容' }),

View File

@ -37,7 +37,8 @@ export default class GoCQHTTPGetStrangerInfo extends OneBotAction<PayloadType, R
override actionName = ActionName.GoCQHTTP_GetStrangerInfo;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取陌生人信息';
override actionSummary = '获取陌生人信息';
override actionDescription = '获取指定非好友用户的信息';
override actionTags = ['Go-CQHTTP'];
override payloadExample = GoCQHTTPActionsExamples.GetStrangerInfo.payload;

View File

@ -19,7 +19,8 @@ export class DelGroupNotice extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.DelGroupNotice;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '删除群公告';
override actionSummary = '删除群公告';
override actionDescription = '删除群聊中的公告';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.DelGroupNotice.payload;

View File

@ -20,7 +20,8 @@ class GetGroupInfo extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupInfo;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群信息';
override actionSummary = '获取群信息';
override actionDescription = '获取群聊的基本信息';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.GetGroupInfo.payload;

View File

@ -20,7 +20,8 @@ class GetGroupList extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群列表';
override actionSummary = '获取群列表';
override actionDescription = '获取当前帐号的群聊列表';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.GetGroupList.payload;
override returnExample = ActionExamples.GetGroupList.return;

View File

@ -4,7 +4,7 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { OB11GroupMemberSchema } from '../schemas';
import { ActionExamples } from '../examples';
import { GroupActionsExamples } from './examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
@ -22,10 +22,11 @@ class GetGroupMemberInfo extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupMemberInfo;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群成员信息';
override actionSummary = '获取群成员信息';
override actionDescription = '获取群聊中指定成员的信息';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.GetGroupMemberInfo.payload;
override returnExample = ActionExamples.GetGroupMemberInfo.return;
override payloadExample = GroupActionsExamples.GetGroupMemberInfo.payload;
override returnExample = GroupActionsExamples.GetGroupMemberInfo.response;
private parseBoolean (value: boolean | string): boolean {
return typeof value === 'string' ? value === 'true' : value;

View File

@ -20,7 +20,8 @@ export class GetGroupMemberList extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupMemberList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群成员列表';
override actionSummary = '获取群成员列表';
override actionDescription = '获取群聊中的所有成员列表';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.GetGroupMemberList.payload;
override returnExample = GroupActionsExamples.GetGroupMemberList.response;

View File

@ -1,14 +1,16 @@
import { ContextMode, ReturnDataType, SendMsgBase, SendMsgPayload } from '@/napcat-onebot/action/msg/SendMsg';
import { ActionName, BaseCheckResult } from '@/napcat-onebot/action/router';
import { ActionExamples } from '../examples';
import { GroupActionsExamples } from './examples';
// 未检测参数
class SendGroupMsg extends SendMsgBase {
override actionName = ActionName.SendGroupMsg;
override actionSummary = '发送群消息';
override actionDescription = '发送群消息';
override payloadExample = ActionExamples.SendGroupMsg.payload;
override returnExample = ActionExamples.SendGroupMsg.return;
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SendGroupMsg.payload;
override returnExample = GroupActionsExamples.SendGroupMsg.response;
protected override async check (payload: SendMsgPayload): Promise<BaseCheckResult> {
delete payload.user_id;

View File

@ -2,6 +2,7 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Type } from '@sinclair/typebox';
import { GuildActionsExamples } from './examples';
export class GetGuildList extends OneBotAction<void, void> {
override actionName = ActionName.GetGuildList;
@ -9,6 +10,8 @@ export class GetGuildList extends OneBotAction<void, void> {
override returnSchema = Type.Null();
override actionDescription = '获取频道列表';
override actionTags = ['频道接口'];
override payloadExample = GuildActionsExamples.GetGuildList.payload;
override returnExample = GuildActionsExamples.GetGuildList.response;
async _handle (): Promise<void> {

View File

@ -2,6 +2,7 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Type } from '@sinclair/typebox';
import { GuildActionsExamples } from './examples';
export class GetGuildProfile extends OneBotAction<void, void> {
override actionName = ActionName.GetGuildProfile;
@ -9,6 +10,8 @@ export class GetGuildProfile extends OneBotAction<void, void> {
override returnSchema = Type.Null();
override actionDescription = '获取频道个人信息';
override actionTags = ['频道接口'];
override payloadExample = GuildActionsExamples.GetGuildProfile.payload;
override returnExample = GuildActionsExamples.GetGuildProfile.response;
async _handle (): Promise<void> {

View File

@ -0,0 +1,10 @@
export const GuildActionsExamples = {
GetGuildList: {
payload: {},
response: [{ guild_id: '123456', guild_name: '测试频道' }],
},
GetGuildProfile: {
payload: { guild_id: '123456' },
response: { guild_id: '123456', guild_name: '测试频道', guild_display_id: '123' },
},
};

View File

@ -19,7 +19,8 @@ class DeleteMsg extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.DeleteMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '撤回消息';
override actionSummary = '撤回消息';
override actionDescription = '撤回已发送的消息';
override actionTags = ['消息接口'];
override payloadExample = ActionExamples.DeleteMsg.payload;

View File

@ -4,7 +4,7 @@ import { MessageUnique } from 'napcat-common/src/message-unique';
import { Static, Type } from '@sinclair/typebox';
import { NetworkAdapterConfig } from '@/napcat-onebot/config/config';
import { ActionExamples } from '../examples';
import { MsgActionsExamples } from './examples';
const PayloadSchema = Type.Object({
message_id: Type.Union([Type.Number(), Type.String()], { description: '消息ID' }),
@ -33,10 +33,11 @@ class GetMsg extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取消息';
override actionSummary = '获取消息';
override actionDescription = '根据消息 ID 获取消息详细信息';
override actionTags = ['消息接口'];
override payloadExample = ActionExamples.GetMsg.payload;
override returnExample = ActionExamples.GetMsg.return;
override payloadExample = MsgActionsExamples.GetMsg.payload;
override returnExample = MsgActionsExamples.GetMsg.response;
async _handle (payload: PayloadType, _adapter: string, config: NetworkAdapterConfig) {
if (!payload.message_id) {

View File

@ -19,7 +19,8 @@ const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
class MarkMsgAsRead extends OneBotAction<PayloadType, ReturnType> {
override actionDescription = '标记消息已读';
override actionSummary = '标记消息已读';
override actionDescription = '标记指定渠道的消息为已读';
override actionTags = ['消息接口'];
override payloadExample = ActionExamples.MarkMsgAsRead.payload;
@ -62,18 +63,21 @@ export class MarkPrivateMsgAsRead extends MarkMsgAsRead {
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionName = ActionName.MarkPrivateMsgAsRead;
override actionSummary = '标记私聊已读';
}
export class MarkGroupMsgAsRead extends MarkMsgAsRead {
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionName = ActionName.MarkGroupMsgAsRead;
override actionSummary = '标记群聊已读';
}
export class GoCQHTTPMarkMsgAsRead extends MarkMsgAsRead {
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionName = ActionName.GoCQHTTP_MarkMsgAsRead;
override actionSummary = '标记消息已读 (Go-CQHTTP)';
}
export class MarkAllMsgAsRead extends OneBotAction<void, null> {

View File

@ -445,7 +445,9 @@ export class SendMsgBase extends OneBotAction<SendMsgPayload, ReturnDataType> {
}
export default class SendMsg extends SendMsgBase {
override actionName = ActionName.SendMsg;
override actionDescription = '发送消息';
override actionSummary = '发送消息';
override actionDescription = '发送私聊或群聊消息';
override actionTags = ['消息接口'];
override payloadExample = ActionExamples.SendMsg.payload;
override returnExample = ActionExamples.SendMsg.return;
}

View File

@ -0,0 +1,14 @@
export const PacketActionsExamples = {
GetPacketStatus: {
payload: {},
response: { status: 'ok' },
},
SendPoke: {
payload: { user_id: '123456789' },
response: {},
},
SetGroupTodo: {
payload: { group_id: '123456', content: '待办内容' },
response: {},
},
};

View File

@ -11,7 +11,8 @@ class GetLoginInfo extends OneBotAction<void, OB11User> {
override actionName = ActionName.GetLoginInfo;
override payloadSchema = Type.Object({});
override returnSchema = OB11UserSchema;
override actionDescription = '获取登录号信息';
override actionSummary = '获取登录号信息';
override actionDescription = '获取当前登录帐号的信息';
override actionTags = ['系统接口'];
override payloadExample = ActionExamples.GetLoginInfo.payload;
override returnExample = ActionExamples.GetLoginInfo.return;

View File

@ -20,7 +20,8 @@ export default class GetFriendList extends OneBotAction<PayloadType, ReturnType>
override actionName = ActionName.GetFriendList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取好友列表';
override actionSummary = '获取好友列表';
override actionDescription = '获取当前帐号的好友列表';
override actionTags = ['用户接口'];
override payloadExample = ActionExamples.GetFriendList.payload;
override returnExample = ActionExamples.GetFriendList.return;

View File

@ -15,7 +15,8 @@ export default class SendLike extends OneBotAction<SendLikePayload, void> {
override actionName = ActionName.SendLike;
override payloadSchema = SendLikePayloadSchema;
override returnSchema = Type.Null();
override actionDescription = '点赞';
override actionSummary = '点赞';
override actionDescription = '给指定用户点赞';
override actionTags = ['用户接口'];
override payloadExample = ActionExamples.SendLike.payload;
override errorExamples = [

View File

@ -12,6 +12,7 @@ const __dirname = dirname(__filename);
interface ActionSchemaInfo {
payload?: TSchema;
return?: TSchema;
summary?: string;
description?: string;
tags?: string[];
payloadExample?: unknown;
@ -30,6 +31,7 @@ export function initSchemas () {
actionSchemas[handler.actionName] = {
payload: action.payloadSchema,
return: action.returnSchema,
summary: action.actionSummary,
description: action.actionDescription,
tags: action.actionTags,
payloadExample: action.payloadExample,
@ -45,6 +47,7 @@ export function initSchemas () {
actionSchemas[handler.actionName] = {
payload: action.payloadSchema,
return: action.returnSchema,
summary: action.actionSummary,
description: action.actionDescription,
tags: action.actionTags,
payloadExample: action.payloadExample,
@ -65,8 +68,8 @@ export function generateOpenAPI () {
const openapi: Record<string, unknown> = {
openapi: '3.1.0',
info: {
title: 'NapCat OneBot 11 API',
description: 'Auto-generated OpenAPI schema for NapCat OneBot 11 actions',
title: 'NapCat OneBot 11 接口文档',
description: 'NapCatOneBot11 旨在提供更先进、更统一、更美观的 OneBot 11 协议实现。',
version: '1.0.0'
},
paths: {} as Record<string, unknown>
@ -79,12 +82,27 @@ export function generateOpenAPI () {
const cleanPayload = JSON.parse(JSON.stringify(schemas.payload || { type: 'object', properties: {} }));
const cleanReturn = JSON.parse(JSON.stringify(schemas.return || { type: 'object', properties: {} }));
if (schemas.payloadExample) {
cleanPayload.example = schemas.payloadExample;
}
if (schemas.returnExample) {
cleanReturn.example = schemas.returnExample;
}
const wrappedPayload = {
type: 'object',
properties: {
action: { type: 'string', example: actionName },
params: cleanPayload,
echo: { type: 'string', example: `${actionName}:1234567890` }
}
};
const wrappedReturn = {
type: 'object',
properties: {
status: { type: 'string', example: 'ok' },
retcode: { type: 'number', example: 0 },
data: cleanReturn,
message: { type: 'string', example: '' },
wording: { type: 'string', example: '' },
echo: { type: 'string', example: `${actionName}:1234567890` }
},
required: ['status', 'retcode', 'data', 'message', 'wording']
};
const paths = openapi['paths'] as Record<string, any>;
const responses: Record<string, unknown> = {
@ -92,7 +110,7 @@ export function generateOpenAPI () {
description: '成功',
content: {
'application/json': {
schema: cleanReturn
schema: wrappedReturn
}
}
}
@ -121,13 +139,18 @@ export function generateOpenAPI () {
paths[path] = {
post: {
summary: actionName,
description: schemas.description || actionName,
summary: schemas.summary || actionName,
description: schemas.description || schemas.summary || actionName,
tags: schemas.tags || ['Default'],
requestBody: {
content: {
'application/json': {
schema: cleanPayload
schema: wrappedPayload,
example: {
action: actionName,
params: schemas.payloadExample || {},
echo: `${actionName}:1234567890`
}
}
}
},