Add action examples and enhance action metadata

Introduced a centralized examples.ts file providing payload and return examples for all actions. Updated numerous action classes to include actionDescription, actionTags, payloadExample, and returnExample fields, improving API documentation and discoverability.
This commit is contained in:
手瓜一十雪 2026-01-25 17:45:46 +08:00
parent 8f1dc3fdde
commit fd1808e36a
66 changed files with 779 additions and 22 deletions

View File

@ -5,6 +5,7 @@ import { NapCatOneBot11Adapter, OB11Return } from '@/napcat-onebot/index';
import { NetworkAdapterConfig } from '../config/config';
import { TSchema } from '@sinclair/typebox';
import { StreamPacket, StreamPacketBasic, StreamStatus } from './stream/StreamBasic';
import { ActionExamples } from './examples';
export class OB11Response {
private static createResponse<T> (data: T, status: string, retcode: number, message: string = '', echo: unknown = null, useStream: boolean = false): OB11Return<T> {
@ -40,8 +41,13 @@ export abstract class OneBotAction<PayloadType, ReturnDataType> {
private validate?: ValidateFunction<unknown> = undefined;
payloadSchema?: TSchema = undefined;
returnSchema?: TSchema = undefined;
payloadExample?: unknown = undefined;
returnExample?: unknown = undefined;
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;

View File

@ -0,0 +1,365 @@
export const ActionExamples = {
GetGroupInfo: {
payload: { group_id: '123456789' },
return: {
group_id: 123456789,
group_name: '测试群',
member_count: 10,
max_member_count: 500,
group_all_shut: 0,
group_remark: ''
}
},
GetGroupList: {
payload: {},
return: [
{
group_id: 123456789,
group_name: '测试群',
member_count: 10,
max_member_count: 500,
group_all_shut: 0,
group_remark: ''
}
]
},
GetGroupMemberList: {
payload: { group_id: '123456789' },
return: [
{
group_id: 123456789,
user_id: 987654321,
nickname: '测试成员',
card: '群名片',
role: 'member'
}
]
},
SendGroupMsg: {
payload: { group_id: '123456789', message: 'hello' },
return: { message_id: 123456 }
},
SendLike: {
payload: { user_id: '123456789', times: 1 },
return: null
},
GetFriendList: {
payload: {},
return: [
{
user_id: 123456789,
nickname: '测试好友',
remark: '备注'
}
]
},
GetStrangerInfo: {
payload: { user_id: '123456789' },
return: {
user_id: 123456789,
nickname: '陌生人',
sex: 'unknown',
age: 0
}
},
SetFriendRemark: {
payload: { user_id: '123456789', remark: '新备注' },
return: null
},
GetCookies: {
payload: { domain: 'qun.qq.com' },
return: { cookies: 'p_skey=xxxx; p_uin=xxxx', bkn: '123456' }
},
SendPrivateMsg: {
payload: { user_id: '123456789', message: 'hello' },
return: { message_id: 123456 }
},
OCRImage: {
payload: { image: 'https://example.com/test.jpg' },
return: [{ text: '识别文本', confidence: 0.99 }]
},
GetClientkey: {
payload: {},
return: { clientkey: 'abcdef123456' }
},
SetQQAvatar: {
payload: { file: 'base64://...' },
return: null
},
SetGroupKickMembers: {
payload: { group_id: '123456789', user_id: ['987654321'], reject_add_request: false },
return: null
},
GetLoginInfo: {
payload: {},
return: { user_id: 123456789, nickname: '机器人' }
},
GetVersionInfo: {
payload: {},
return: {
app_name: 'NapCatQQ',
app_version: '1.0.0',
protocol_version: 'v11'
}
},
GetStatus: {
payload: {},
return: { online: true, good: true }
},
DeleteMsg: {
payload: { message_id: 123456 },
return: null
},
SetGroupWholeBan: {
payload: { group_id: '123456789', enable: true },
return: null
},
SetGroupBan: {
payload: { group_id: '123456789', user_id: '987654321', duration: 1800 },
return: null
},
SetGroupKick: {
payload: { group_id: '123456789', user_id: '987654321', reject_add_request: false },
return: null
},
SetGroupAdmin: {
payload: { group_id: '123456789', user_id: '987654321', enable: true },
return: null
},
SetGroupName: {
payload: { group_id: '123456789', group_name: '新群名' },
return: null
},
SetGroupCard: {
payload: { group_id: '123456789', user_id: '987654321', card: '新名片' },
return: null
},
GetGroupMemberInfo: {
payload: { group_id: '123456789', user_id: '987654321' },
return: {
group_id: 123456789,
user_id: 987654321,
nickname: '成员昵称',
card: '名片',
role: 'member'
}
},
SendMsg: {
payload: { message_type: 'group', group_id: '123456789', message: 'hello' },
return: { message_id: 123456 }
},
GetMsg: {
payload: { message_id: 123456 },
return: {
time: 123456789,
message_type: 'group',
message_id: 123456,
real_id: 123456,
sender: { user_id: 987654321, nickname: '昵称' },
message: 'hello'
}
},
SetGroupLeave: {
payload: { group_id: '123456789', is_dismiss: false },
return: null
},
CanSendRecord: {
payload: {},
return: { yes: true }
},
CanSendImage: {
payload: {},
return: { yes: true }
},
SetFriendAddRequest: {
payload: { flag: '12345', approve: true, remark: '好友' },
return: null
},
SetGroupAddRequest: {
payload: { flag: '12345', sub_type: 'add', approve: true },
return: null
},
DelEssenceMsg: {
payload: { message_id: 12345 },
return: null
},
SetEssenceMsg: {
payload: { message_id: 12345 },
return: null
},
GetGroupEssence: {
payload: { group_id: '123456789' },
return: [
{
msg_seq: 12345,
msg_random: 67890,
sender_id: 987654321,
sender_nick: '发送者',
operator_id: 123456789,
operator_nick: '操作者',
message_id: 123456,
operator_time: 1234567890,
content: [{ type: 'text', data: { text: '精华消息内容' } }]
}
]
},
GetGroupShutList: {
payload: { group_id: '123456789' },
return: [
{
user_id: 987654321,
nickname: '禁言成员',
card: '名片',
shut_up_time: 1234567890
}
]
},
GetGroupDetailInfo: {
payload: { group_id: '123456789' },
return: {
group_id: 123456789,
group_name: '测试群',
member_count: 10,
max_member_count: 500,
group_all_shut: 0,
group_remark: ''
}
},
DelGroupNotice: {
payload: { group_id: '123456789', notice_id: 'abc-123' },
return: null
},
GetAiRecord: {
payload: { group_id: '123456789', character: 'ai' },
return: { msg: 'AI回复内容' }
},
GetGroupNotice: {
payload: { group_id: '123456789' },
return: [
{
notice_id: 'abc-123',
sender_id: 987654321,
publish_time: 1234567890,
message: { text: '公告内容', images: [] }
}
]
},
SendGroupAiRecord: {
payload: { group_id: '123456789', character: 'ai', text: '你好' },
return: { message_id: 123456 }
},
GetFile: {
payload: { file: 'abc-123' },
return: {
file: '/path/to/file',
url: 'http://example.com/file',
file_size: '1024',
file_name: 'test.txt'
}
},
GetImage: {
payload: { file: 'abc-123' },
return: {
file: '/path/to/image.jpg',
url: 'http://example.com/image.jpg',
file_size: '1024',
file_name: 'image.jpg'
}
},
GetRecord: {
payload: { file: 'abc-123', out_format: 'mp3' },
return: {
file: '/path/to/record.mp3',
url: 'http://example.com/record.mp3',
file_size: '1024',
file_name: 'record.mp3',
base64: '...'
}
},
GetGroupFileUrl: {
payload: { group_id: '123456789', file_id: 'abc-123' },
return: { url: 'http://example.com/group_file' }
},
GetPrivateFileUrl: {
payload: { file_id: 'abc-123' },
return: { url: 'http://example.com/private_file' }
},
GetAiCharacters: {
payload: { group_id: '123456789' },
return: [
{
type: '常用',
characters: [
{ character_id: 'ai-1', character_name: 'AI助手', preview_url: 'http://...' }
]
}
]
},
SetOnlineStatus: {
payload: { status: 11, ext_status: 0, battery_status: 100 },
return: null
},
SetGroupRemark: {
payload: { group_id: '123456789', remark: '群备注' },
return: null
},
GetCollectionList: {
payload: { category: '1', count: '10' },
return: []
},
SetSpecialTitle: {
payload: { group_id: '123456789', user_id: '987654321', special_title: '群头衔' },
return: null
},
MarkMsgAsRead: {
payload: { group_id: '123456789' },
return: null
},
ForwardSingleMsg: {
payload: { message_id: 12345, group_id: '123456789' },
return: null
},
SendPoke: {
payload: { group_id: '123456789', user_id: '987654321' },
return: null
},
SetGroupTodo: {
payload: { group_id: '123456789', message_id: '12345' },
return: null
},
GetCredentials: {
payload: { domain: 'qun.qq.com' },
return: { cookies: '...', token: 123456 }
},
GetGroupSystemMsg: {
payload: { count: 10 },
return: {
invited_requests: [],
InvitedRequest: [],
join_requests: []
}
},
GetRecentContact: {
payload: { count: 10 },
return: []
},
GetCSRF: {
payload: {},
return: { token: 123456789 }
},
SetMsgEmojiLike: {
payload: { message_id: 12345, emoji_id: '124' },
return: null
},
UploadGroupFile: {
payload: { group_id: '123456789', file: '/path/to/file', name: 'test.txt' },
return: null
},
Common: {
errors: [
{ code: 1400, description: '请求参数错误或业务逻辑执行失败' },
{ code: 1401, description: '权限不足' },
{ code: 1404, description: '资源不存在' }
]
}
};

View File

@ -2,6 +2,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
import { Type, Static } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
chat_type: Type.Union([Type.Number(), Type.String()], { default: 1, description: '聊天类型' }),
@ -30,6 +32,10 @@ export class GetAiCharacters extends GetPacketStatusDepends<PayloadType, ReturnT
override actionName = ActionName.GetAiCharacters;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取AI角色列表';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.GetAiCharacters.payload;
override returnExample = ActionExamples.GetAiCharacters.return;
async _handle (payload: PayloadType) {
const chatTypeNum = Number(payload.chat_type);

View File

@ -2,6 +2,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { OneBotAction } from '../OneBotAction';
import { Type, Static } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const ReturnSchema = Type.Object({
clientkey: Type.Optional(Type.String({ description: '客户端Key' })),
}, { description: '获取ClientKey结果' });
@ -12,6 +14,10 @@ export class GetClientkey extends OneBotAction<void, ReturnType> {
override actionName = ActionName.GetClientkey;
override payloadSchema = Type.Void();
override returnSchema = ReturnSchema;
override actionDescription = '获取 ClientKey';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.GetClientkey.payload;
override returnExample = ActionExamples.GetClientkey.return;
async _handle () {
return { clientkey: (await this.core.apis.UserApi.forceFetchClientKey()).clientKey };

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Type, Static } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
category: Type.String({ description: '分类ID' }),
count: Type.String({ default: '1', description: '获取数量' }),
@ -17,6 +19,10 @@ export class GetCollectionList extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetCollectionList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取收藏列表';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.GetCollectionList.payload;
override returnExample = ActionExamples.GetCollectionList.return;
async _handle (payload: PayloadType) {
return await this.core.apis.CollectionApi.getAllCollection(+payload.category, +payload.count);

View File

@ -4,6 +4,8 @@ import { checkFileExist, uriToLocalFile } from 'napcat-common/src/file';
import fs from 'fs';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
image: Type.String({ description: '图片路径、URL或Base64' }),
});
@ -17,6 +19,10 @@ type ReturnType = Static<typeof ReturnSchema>;
class OCRImageBase extends OneBotAction<PayloadType, ReturnType> {
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '图片 OCR 识别';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.OCRImage.payload;
override returnExample = ActionExamples.OCRImage.return;
async _handle (payload: PayloadType): Promise<ReturnType> {
const { path, success } = await uriToLocalFile(this.core.NapCatTempPath, payload.image);

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.Array(Type.String(), { description: 'QQ号列表' }),
@ -18,6 +20,9 @@ export default class SetGroupKickMembers extends OneBotAction<PayloadType, Retur
override actionName = ActionName.SetGroupKickMembers;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '批量踢出群成员';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.SetGroupKickMembers.payload;
async _handle (payload: PayloadType): Promise<ReturnType> {
const rejectReq = payload.reject_add_request?.toString() === 'true';

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
remark: Type.String({ description: '备注' }),
@ -17,6 +19,10 @@ export default class SetGroupRemark extends OneBotAction<PayloadType, ReturnType
override actionName = ActionName.SetGroupRemark;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '设置群备注';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.SetGroupRemark.payload;
async _handle (payload: PayloadType): Promise<ReturnType> {
const ret = await this.core.apis.GroupApi.setGroupRemark(payload.group_id, payload.remark);
if (ret.result !== 0) {

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
status: Type.Union([Type.Number(), Type.String()], { description: '在线状态' }),
ext_status: Type.Union([Type.Number(), Type.String()], { description: '扩展状态' }),
@ -18,6 +20,9 @@ export class SetOnlineStatus extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetOnlineStatus;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '设置在线状态';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.SetOnlineStatus.payload;
async _handle (payload: PayloadType) {
const ret = await this.core.apis.UserApi.setSelfOnlineStatus(

View File

@ -4,6 +4,8 @@ import fs from 'node:fs/promises';
import { checkFileExist, uriToLocalFile } from 'napcat-common/src/file';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
file: Type.String({ description: '图片路径、URL或Base64' }),
});
@ -18,6 +20,10 @@ export default class SetAvatar extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetQQAvatar;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '设置 QQ 头像';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.SetQQAvatar.payload;
async _handle (payload: PayloadType): Promise<ReturnType> {
const { path, success } = (await uriToLocalFile(this.core.NapCatTempPath, payload.file));
if (!success) {

View File

@ -2,6 +2,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: 'QQ号' }),
@ -18,6 +20,9 @@ export class SetSpecialTitle extends GetPacketStatusDepends<PayloadType, ReturnT
override actionName = ActionName.SetSpecialTitle;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '设置专属头衔';
override actionTags = ['扩展接口'];
override payloadExample = ActionExamples.SetSpecialTitle.payload;
async _handle (payload: PayloadType) {
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());

View File

@ -5,6 +5,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { OB11MessageImage, OB11MessageVideo } from '@/napcat-onebot/types';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
export const GetFilePayloadSchema = Type.Object({
file: Type.Optional(Type.String({ description: '文件路径、URL或Base64' })),
file_id: Type.Optional(Type.String({ description: '文件ID' })),
@ -25,6 +27,7 @@ export type GetFileResponse = Static<typeof GetFileReturnSchema>;
export class GetFileBase extends OneBotAction<GetFilePayload, GetFileResponse> {
override payloadSchema = GetFilePayloadSchema;
override returnSchema = GetFileReturnSchema;
override actionTags = ['文件接口'];
async _handle (payload: GetFilePayload): Promise<GetFileResponse> {
payload.file ||= payload.file_id || '';
@ -116,4 +119,7 @@ export class GetFileBase extends OneBotAction<GetFilePayload, GetFileResponse> {
export default class GetFile extends GetFileBase {
override actionName = ActionName.GetFile;
override actionDescription = '获取文件';
override payloadExample = ActionExamples.GetFile.payload;
override returnExample = ActionExamples.GetFile.return;
}

View File

@ -3,6 +3,8 @@ import { FileNapCatOneBotUUID } from 'napcat-common/src/file-uuid';
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
file_id: Type.String({ description: '文件ID' }),
@ -20,6 +22,10 @@ export class GetGroupFileUrl extends GetPacketStatusDepends<PayloadType, ReturnT
override actionName = ActionName.GOCQHTTP_GetGroupFileUrl;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群文件URL';
override actionTags = ['文件接口'];
override payloadExample = ActionExamples.GetGroupFileUrl.payload;
override returnExample = ActionExamples.GetGroupFileUrl.return;
async _handle (payload: PayloadType) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id) || FileNapCatOneBotUUID.decodeModelId(payload.file_id);

View File

@ -1,6 +1,11 @@
import { GetFileBase } from './GetFile';
import { ActionName } from '@/napcat-onebot/action/router';
import { ActionExamples } from '../examples';
export default class GetImage extends GetFileBase {
override actionName = ActionName.GetImage;
override actionDescription = '获取图片';
override payloadExample = ActionExamples.GetImage.payload;
override returnExample = ActionExamples.GetImage.return;
}

View File

@ -3,6 +3,8 @@ import { FileNapCatOneBotUUID } from 'napcat-common/src/file-uuid';
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
file_id: Type.String({ description: '文件ID' }),
});
@ -19,6 +21,10 @@ export class GetPrivateFileUrl extends GetPacketStatusDepends<PayloadType, Retur
override actionName = ActionName.NapCat_GetPrivateFileUrl;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取私聊文件URL';
override actionTags = ['文件接口'];
override payloadExample = ActionExamples.GetPrivateFileUrl.payload;
override returnExample = ActionExamples.GetPrivateFileUrl.return;
async _handle (payload: PayloadType) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id);

View File

@ -4,6 +4,8 @@ import { promises as fs } from 'fs';
import { FFmpegService } from '@/napcat-core/helper/ffmpeg/ffmpeg';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const out_format_list = ['mp3', 'amr', 'wma', 'm4a', 'spx', 'ogg', 'wav', 'flac'];
const PayloadSchema = Type.Object({
@ -17,6 +19,9 @@ type PayloadType = Static<typeof PayloadSchema>;
export default class GetRecord extends GetFileBase {
override actionName = ActionName.GetRecord;
override payloadSchema = PayloadSchema;
override actionDescription = '获取语音';
override payloadExample = ActionExamples.GetRecord.payload;
override returnExample = ActionExamples.GetRecord.return;
override async _handle (payload: PayloadType): Promise<GetFileResponse> {
const res = await super._handle(payload as GetFilePayload);

View File

@ -27,6 +27,8 @@ export class GoCQHTTPGetForwardMsgAction extends OneBotAction<PayloadType, Retur
override actionName = ActionName.GoCQHTTP_GetForwardMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取合并转发消息';
override actionTags = ['消息接口'];
private createTemplateNode (message: OB11Message): OB11MessageNode {
return {

View File

@ -20,6 +20,8 @@ export class GoCQHTTPGetGroupAtAllRemain extends OneBotAction<PayloadType, Retur
override actionName = ActionName.GoCQHTTP_GetGroupAtAllRemain;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群艾特全体剩余次数';
override actionTags = ['群组接口'];
async _handle (payload: PayloadType) {
const ret = await this.core.apis.GroupApi.getGroupRemainAtTimes(payload.group_id.toString());

View File

@ -26,6 +26,8 @@ export class GetGroupHonorInfo extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupHonorInfo;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群荣誉信息';
override actionTags = ['群组接口'];
async _handle (payload: PayloadType): Promise<ReturnType> {
if (!payload.type) {

View File

@ -5,6 +5,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { calcQQLevel } from 'napcat-common/src/helper';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
user_id: Type.String({ description: '用户QQ' }),
no_cache: Type.Union([Type.Boolean(), Type.String()], { default: false, description: '是否不使用缓存' }),
@ -36,6 +38,11 @@ export default class GoCQHTTPGetStrangerInfo extends OneBotAction<PayloadType, R
override actionName = ActionName.GoCQHTTP_GetStrangerInfo;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取陌生人信息';
override actionTags = ['用户接口'];
override payloadExample = ActionExamples.GetStrangerInfo.payload;
override returnExample = ActionExamples.GetStrangerInfo.return;
async _handle (payload: PayloadType): Promise<ReturnType> {
const user_id = payload.user_id.toString();
const isNocache = typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache;

View File

@ -13,6 +13,8 @@ export class GoCQHTTPSendForwardMsgBase extends SendMsgBase {
}
export class GoCQHTTPSendForwardMsg extends GoCQHTTPSendForwardMsgBase {
override actionName = ActionName.GoCQHTTP_SendForwardMsg;
override actionDescription = '发送合并转发消息';
override actionTags = ['消息接口'];
protected override async check (payload: GoCQHTTPSendForwardMsgPayload) {
if (payload.messages) payload.message = normalize(payload.messages);

View File

@ -3,6 +3,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { MessageUnique } from 'napcat-common/src/message-unique';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
message_id: Type.Optional(Type.Union([Type.Number(), Type.String()], { description: '消息ID' })),
msg_seq: Type.Optional(Type.String({ description: '消息序号' })),
@ -20,6 +22,9 @@ export default class DelEssenceMsg extends OneBotAction<PayloadType, ReturnType>
override actionName = ActionName.DelEssenceMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '移出精华消息';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.DelEssenceMsg.payload;
async _handle (payload: PayloadType): Promise<ReturnType> {
// 如果直接提供了 msg_seq, msg_random, group_id,优先使用

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
notice_id: Type.String({ description: '公告ID' }),
@ -17,6 +19,9 @@ export class DelGroupNotice extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.DelGroupNotice;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '删除群公告';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.DelGroupNotice.payload;
async _handle (payload: PayloadType) {
const group = payload.group_id.toString();

View File

@ -3,6 +3,8 @@ import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketS
import { AIVoiceChatType } from 'napcat-core/packet/entities/aiChat';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
character: Type.String({ description: '角色ID' }),
group_id: Type.String({ description: '群号' }),
@ -19,6 +21,9 @@ export class GetAiRecord extends GetPacketStatusDepends<PayloadType, ReturnType>
override actionName = ActionName.GetAiRecord;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取AI语音';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.GetAiRecord.payload;
async _handle (payload: PayloadType) {
const rawRsp = await this.core.apis.PacketApi.pkt.operation.GetAiVoice(+payload.group_id, payload.character, payload.text, AIVoiceChatType.Sound);

View File

@ -4,6 +4,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { OB11GroupSchema } from '../schemas';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
});
@ -18,6 +20,10 @@ class GetGroupInfo extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupInfo;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群信息';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.GetGroupInfo.payload;
override returnExample = ActionExamples.GetGroupInfo.return;
async _handle (payload: PayloadType) {
const group = (await this.core.apis.GroupApi.getGroups()).find(e => e.groupCode === payload.group_id.toString());

View File

@ -4,6 +4,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { OB11GroupSchema } from '../schemas';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
no_cache: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否不使用缓存' })),
});
@ -18,6 +20,10 @@ class GetGroupList extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群列表';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.GetGroupList.payload;
override returnExample = ActionExamples.GetGroupList.return;
async _handle (payload: PayloadType) {
return OB11Construct.groups(

View File

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

View File

@ -18,8 +18,17 @@ type ReturnType = Static<typeof ReturnSchema>;
export class GetGroupMemberList extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupMemberList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override returnSchema = ReturnSchema; override actionDescription = '获取群成员列表';
override payloadExample = { group_id: '123456789' };
override returnExample = [
{
group_id: 123456789,
user_id: 987654321,
nickname: '测试成员',
card: '群名片',
role: 'member'
}
];
async _handle (payload: PayloadType) {
const groupIdStr = payload.group_id.toString();
const noCache = this.parseBoolean(payload.no_cache ?? false);

View File

@ -2,6 +2,8 @@ import { WebApiGroupNoticeFeed } from 'napcat-core';
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
});
@ -29,6 +31,10 @@ export class GetGroupNotice extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GoCQHTTP_GetGroupNotice;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取群公告';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.GetGroupNotice.payload;
override returnExample = ActionExamples.GetGroupNotice.return;
async _handle (payload: PayloadType) {
const group = payload.group_id.toString();

View File

@ -3,6 +3,8 @@ import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketS
import { AIVoiceChatType } from 'napcat-core/packet/entities/aiChat';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
character: Type.String({ description: '角色ID' }),
group_id: Type.String({ description: '群号' }),
@ -21,6 +23,9 @@ export class SendGroupAiRecord extends GetPacketStatusDepends<PayloadType, Retur
override actionName = ActionName.SendGroupAiRecord;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '发送群AI语音';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SendGroupAiRecord.payload;
async _handle (payload: PayloadType) {
await this.core.apis.PacketApi.pkt.operation.GetAiVoice(+payload.group_id, payload.character, payload.text, AIVoiceChatType.Sound);

View File

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

View File

@ -3,6 +3,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { MessageUnique } from 'napcat-common/src/message-unique';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
message_id: Type.Union([Type.Number(), Type.String()], { description: '消息ID' }),
});
@ -17,6 +19,9 @@ export default class SetEssenceMsg extends OneBotAction<PayloadType, ReturnType>
override actionName = ActionName.SetEssenceMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '设置精华消息';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SetEssenceMsg.payload;
async _handle (payload: PayloadType) {
const msg = MessageUnique.getMsgIdAndPeerByShortId(+payload.message_id);

View File

@ -3,6 +3,8 @@ import { GroupNotify, NTGroupRequestOperateTypes } from 'napcat-core/types';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
flag: Type.String({ description: '请求flag' }),
approve: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否同意' })),
@ -20,6 +22,9 @@ export default class SetGroupAddRequest extends OneBotAction<PayloadType, Return
override actionName = ActionName.SetGroupAddRequest;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '处理加群请求';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SetGroupAddRequest.payload;
async _handle (payload: PayloadType): Promise<null> {
const flag = payload.flag.toString();

View File

@ -3,6 +3,8 @@ import { NTGroupMemberRole } from 'napcat-core/types';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: '用户QQ' }),
@ -19,6 +21,9 @@ export default class SetGroupAdmin extends OneBotAction<PayloadType, ReturnType>
override actionName = ActionName.SetGroupAdmin;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '设置群管理员';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SetGroupAdmin.payload;
async _handle (payload: PayloadType): Promise<null> {
const enable = typeof payload.enable === 'string' ? payload.enable === 'true' : !!payload.enable;

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: '用户QQ' }),
@ -18,6 +20,10 @@ export default class SetGroupBan extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupBan;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '群组禁言';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SetGroupBan.payload;
async _handle (payload: PayloadType): Promise<null> {
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('uid error');

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: '用户QQ' }),
@ -18,6 +20,9 @@ export default class SetGroupCard extends OneBotAction<PayloadType, ReturnType>
override actionName = ActionName.SetGroupCard;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '设置群名片';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SetGroupCard.payload;
async _handle (payload: PayloadType): Promise<null> {
const member = await this.core.apis.GroupApi.getGroupMember(payload.group_id.toString(), payload.user_id.toString());

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: '用户QQ' }),
@ -18,6 +20,9 @@ export default class SetGroupKick extends OneBotAction<PayloadType, ReturnType>
override actionName = ActionName.SetGroupKick;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '群组踢人';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SetGroupKick.payload;
async _handle (payload: PayloadType): Promise<null> {
const rejectReq = payload.reject_add_request?.toString() === 'true';

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
is_dismiss: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否解散' })),
@ -17,6 +19,9 @@ export default class SetGroupLeave extends OneBotAction<PayloadType, ReturnType>
override actionName = ActionName.SetGroupLeave;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '退出群组';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SetGroupLeave.payload;
async _handle (payload: PayloadType): Promise<null> {
await this.core.apis.GroupApi.quitGroup(payload.group_id.toString());

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
group_name: Type.String({ description: '群名称' }),
@ -17,6 +19,9 @@ export default class SetGroupName extends OneBotAction<PayloadType, ReturnType>
override actionName = ActionName.SetGroupName;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '设置群名称';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SetGroupName.payload;
async _handle (payload: PayloadType): Promise<null> {
const ret = await this.core.apis.GroupApi.setGroupName(payload.group_id.toString(), payload.group_name);

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
enable: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否开启全员禁言' })),
@ -17,6 +19,9 @@ export default class SetGroupWholeBan extends OneBotAction<PayloadType, ReturnTy
override actionName = ActionName.SetGroupWholeBan;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '全员禁言';
override actionTags = ['群组接口'];
override payloadExample = ActionExamples.SetGroupWholeBan.payload;
async _handle (payload: PayloadType): Promise<null> {
const enable = payload.enable?.toString() !== 'false';

View File

@ -7,6 +7,8 @@ export class GetGuildList extends OneBotAction<void, void> {
override actionName = ActionName.GetGuildList;
override payloadSchema = Type.Object({});
override returnSchema = Type.Null();
override actionDescription = '获取频道列表';
override actionTags = ['频道接口'];
async _handle (): Promise<void> {

View File

@ -7,6 +7,8 @@ export class GetGuildProfile extends OneBotAction<void, void> {
override actionName = ActionName.GetGuildProfile;
override payloadSchema = Type.Object({});
override returnSchema = Type.Null();
override actionDescription = '获取频道个人信息';
override actionTags = ['频道接口'];
async _handle (): Promise<void> {

View File

@ -3,6 +3,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { MessageUnique } from 'napcat-common/src/message-unique';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
message_id: Type.Union([Type.Number(), Type.String()], { description: '消息ID' }),
});
@ -17,6 +19,9 @@ class DeleteMsg extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.DeleteMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '撤回消息';
override actionTags = ['消息接口'];
override payloadExample = ActionExamples.DeleteMsg.payload;
async _handle (payload: PayloadType) {
const msg = MessageUnique.getMsgIdAndPeerByShortId(Number(payload.message_id));

View File

@ -4,6 +4,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { MessageUnique } from 'napcat-common/src/message-unique';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
message_id: Type.Union([Type.Number(), Type.String()], { description: '消息ID' }),
group_id: Type.Optional(Type.String({ description: '目标群号' })),
@ -17,6 +19,10 @@ const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
class ForwardSingleMsg extends OneBotAction<PayloadType, ReturnType> {
override actionDescription = '转发单条消息';
override actionTags = ['消息接口'];
override payloadExample = ActionExamples.ForwardSingleMsg.payload;
protected async getTargetPeer (payload: PayloadType): Promise<Peer> {
if (payload.user_id) {
const peerUid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());

View File

@ -4,6 +4,8 @@ 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';
const PayloadSchema = Type.Object({
message_id: Type.Union([Type.Number(), Type.String()], { description: '消息ID' }),
});
@ -31,6 +33,10 @@ class GetMsg extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取消息';
override actionTags = ['消息接口'];
override payloadExample = ActionExamples.GetMsg.payload;
override returnExample = ActionExamples.GetMsg.return;
async _handle (payload: PayloadType, _adapter: string, config: NetworkAdapterConfig) {
if (!payload.message_id) {

View File

@ -4,6 +4,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { MessageUnique } from 'napcat-common/src/message-unique';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
user_id: Type.Optional(Type.Union([Type.String(), Type.Number()], { description: '用户QQ' })),
group_id: Type.Optional(Type.Union([Type.String(), Type.Number()], { description: '群号' })),
@ -17,6 +19,10 @@ const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
class MarkMsgAsRead extends OneBotAction<PayloadType, ReturnType> {
override actionDescription = '标记消息已读';
override actionTags = ['消息接口'];
override payloadExample = ActionExamples.MarkMsgAsRead.payload;
async getPeer (payload: PayloadType): Promise<Peer> {
if (payload.message_id) {
const s_peer = MessageUnique.getMsgIdAndPeerByShortId(+payload.message_id)?.Peer;

View File

@ -16,6 +16,8 @@ import { PacketMsg } from 'napcat-core/packet/message/message';
import { rawMsgWithSendMsg } from 'napcat-core/packet/message/converter';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
export const SendMsgPayloadSchema = Type.Object({
message_type: Type.Optional(Type.Union([Type.Literal('private'), Type.Literal('group')], { description: '消息类型 (private/group)' })),
user_id: Type.Optional(Type.String({ description: '用户QQ' })),
@ -129,6 +131,7 @@ function isNode (msg: OB11MessageData): msg is OB11MessageNode {
export class SendMsgBase extends OneBotAction<SendMsgPayload, ReturnDataType> {
override payloadSchema = SendMsgPayloadSchema;
override returnSchema = SendMsgReturnSchema;
override actionTags = ['消息接口'];
protected override async check (payload: SendMsgPayload): Promise<BaseCheckResult> {
const messages = normalize(payload.message);
@ -442,4 +445,7 @@ export class SendMsgBase extends OneBotAction<SendMsgPayload, ReturnDataType> {
}
export default class SendMsg extends SendMsgBase {
override actionName = ActionName.SendMsg;
override actionDescription = '发送消息';
override payloadExample = ActionExamples.SendMsg.payload;
override returnExample = ActionExamples.SendMsg.return;
}

View File

@ -1,9 +1,15 @@
import { ContextMode, ReturnDataType, SendMsgBase, SendMsgPayload } from './SendMsg';
import { ActionName, BaseCheckResult } from '@/napcat-onebot/action/router';
import { ActionExamples } from '../examples';
// 未检测参数
class SendPrivateMsg extends SendMsgBase {
override actionName = ActionName.SendPrivateMsg;
override actionDescription = '发送私聊消息';
override actionTags = ['消息接口'];
override payloadExample = ActionExamples.SendPrivateMsg.payload;
override returnExample = ActionExamples.SendPrivateMsg.return;
protected override async check (payload: SendMsgPayload): Promise<BaseCheckResult> {
payload.message_type = 'private';

View File

@ -19,6 +19,8 @@ export class GetPacketStatus extends GetPacketStatusDepends<void, void> {
override actionName = ActionName.GetPacketStatus;
override payloadSchema = Type.Object({});
override returnSchema = Type.Null();
override actionDescription = '获取 Packet 状态';
override actionTags = ['系统接口'];
async _handle () {

View File

@ -2,6 +2,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
export const SendPokePayloadSchema = Type.Object({
group_id: Type.Optional(Type.Union([Type.String(), Type.Number()], { description: '群号' })),
user_id: Type.Optional(Type.Union([Type.String(), Type.Number()], { description: '用户QQ' })),
@ -12,6 +14,9 @@ export type SendPokePayload = Static<typeof SendPokePayloadSchema>;
export class SendPokeBase extends GetPacketStatusDepends<SendPokePayload, void> {
override payloadSchema = SendPokePayloadSchema;
override returnSchema = Type.Null();
override actionDescription = '发送戳一戳';
override actionTags = ['核心接口'];
override payloadExample = ActionExamples.SendPoke.payload;
async _handle (payload: SendPokePayload) {
// 这里的 !! 可以传入空字符串 忽略这些数据有利用接口统一接口

View File

@ -4,6 +4,8 @@ import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketS
import { Static, Type } from '@sinclair/typebox';
import { ActionName } from '../router';
import { ActionExamples } from '../examples';
export const SetGroupTodoPayloadSchema = Type.Object({
group_id: Type.Union([Type.String(), Type.Number()], { description: '群号' }),
message_id: Type.Optional(Type.String({ description: '消息ID' })),
@ -15,6 +17,10 @@ export class SetGroupTodo extends GetPacketStatusDepends<SetGroupTodoPayload, vo
override payloadSchema = SetGroupTodoPayloadSchema;
override returnSchema = Type.Null();
override actionName = ActionName.SetGroupTodo;
override actionDescription = '设置群待办';
override actionTags = ['核心接口'];
override payloadExample = ActionExamples.SetGroupTodo.payload;
async _handle (payload: SetGroupTodoPayload) {
if (payload.message_seq) {
return await this.core.apis.PacketApi.pkt.operation.SetGroupTodo(+payload.group_id, payload.message_seq.toString());

View File

@ -1,6 +1,10 @@
import { ActionName } from '@/napcat-onebot/action/router';
import { CanSend } from './CanSendRecord';
import { ActionExamples } from '../examples';
export default class CanSendImage extends CanSend {
override actionName = ActionName.CanSendImage;
override actionDescription = '检查是否可以发送图片';
override payloadExample = ActionExamples.CanSendImage.payload;
override returnExample = ActionExamples.CanSendImage.return;
}

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Type, Static } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
export const CanSendReturnSchema = Type.Object({
yes: Type.Boolean({ description: '是否可以发送' }),
});
@ -11,6 +13,7 @@ export type CanSendReturnType = Static<typeof CanSendReturnSchema>;
export class CanSend extends OneBotAction<void, CanSendReturnType> {
override payloadSchema = Type.Object({});
override returnSchema = CanSendReturnSchema;
override actionTags = ['系统接口'];
async _handle (): Promise<CanSendReturnType> {
return {
@ -21,4 +24,7 @@ export class CanSend extends OneBotAction<void, CanSendReturnType> {
export default class CanSendRecord extends CanSend {
override actionName = ActionName.CanSendRecord;
override actionDescription = '检查是否可以发送语音';
override payloadExample = ActionExamples.CanSendRecord.payload;
override returnExample = ActionExamples.CanSendRecord.return;
}

View File

@ -8,6 +8,8 @@ export class CleanCache extends OneBotAction<void, void> {
override actionName = ActionName.CleanCache;
override payloadSchema = Type.Object({});
override returnSchema = Type.Null();
override actionDescription = '清理缓存';
override actionTags = ['系统接口'];
async _handle () {
try {

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
export const GetCredentialsPayloadSchema = Type.Object({
domain: Type.String({ description: '需要获取 cookies 的域名' }),
});
@ -19,6 +21,10 @@ export class GetCredentials extends OneBotAction<GetCredentialsPayload, GetCrede
override actionName = ActionName.GetCredentials;
override payloadSchema = GetCredentialsPayloadSchema;
override returnSchema = GetCredentialsReturnSchema;
override actionDescription = '获取身份信息';
override actionTags = ['系统接口'];
override payloadExample = ActionExamples.GetCredentials.payload;
override returnExample = ActionExamples.GetCredentials.return;
async _handle (payload: GetCredentialsPayload) {
const cookiesObject = await this.core.apis.UserApi.getCookies(payload.domain);

View File

@ -5,10 +5,16 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { OB11UserSchema } from '../schemas';
import { Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
class GetLoginInfo extends OneBotAction<void, OB11User> {
override actionName = ActionName.GetLoginInfo;
override payloadSchema = Type.Object({});
override returnSchema = OB11UserSchema;
override actionDescription = '获取登录号信息';
override actionTags = ['系统接口'];
override payloadExample = ActionExamples.GetLoginInfo.payload;
override returnExample = ActionExamples.GetLoginInfo.return;
async _handle () {
return OB11Construct.selfInfo(this.core.selfInfo);

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Type, Static } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
export const GetStatusReturnSchema = Type.Object({
online: Type.Boolean({ description: '是否在线' }),
good: Type.Boolean({ description: '状态是否良好' }),
@ -14,6 +16,10 @@ export default class GetStatus extends OneBotAction<void, GetStatusReturnType> {
override actionName = ActionName.GetStatus;
override payloadSchema = Type.Object({});
override returnSchema = GetStatusReturnSchema;
override actionDescription = '获取运行状态';
override actionTags = ['系统接口'];
override payloadExample = ActionExamples.GetStatus.payload;
override returnExample = ActionExamples.GetStatus.return;
async _handle (): Promise<GetStatusReturnType> {
return {

View File

@ -4,6 +4,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { OB11NotifySchema } from '../schemas';
import { ActionExamples } from '../examples';
export const GetGroupSystemMsgPayloadSchema = Type.Object({
count: Type.Union([Type.Number(), Type.String()], { default: 50, description: '获取的消息数量' }),
});
@ -22,6 +24,10 @@ export class GetGroupSystemMsg extends OneBotAction<GetGroupSystemMsgPayload, Ge
override actionName = ActionName.GetGroupSystemMsg;
override payloadSchema = GetGroupSystemMsgPayloadSchema;
override returnSchema = GetGroupSystemMsgReturnSchema;
override actionDescription = '获取群系统消息';
override actionTags = ['系统接口'];
override payloadExample = ActionExamples.GetGroupSystemMsg.payload;
override returnExample = ActionExamples.GetGroupSystemMsg.return;
async _handle (params: GetGroupSystemMsgPayload): Promise<GetGroupSystemMsgReturn> {
const SingleScreenNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(false, +params.count);

View File

@ -11,9 +11,15 @@ const ReturnSchema = Type.Object({
type ReturnType = Static<typeof ReturnSchema>;
import { ActionExamples } from '../examples';
export default class GetVersionInfo extends OneBotAction<void, ReturnType> {
override actionName = ActionName.GetVersionInfo;
override returnSchema = ReturnSchema;
override actionDescription = '获取版本信息';
override actionTags = ['系统接口'];
override payloadExample = ActionExamples.GetVersionInfo.payload;
override returnExample = ActionExamples.GetVersionInfo.return;
async _handle (): Promise<ReturnType> {
return {

View File

@ -7,6 +7,8 @@ export class SetRestart extends OneBotAction<void, void> {
override actionName = ActionName.Reboot;
override payloadSchema = Type.Object({});
override returnSchema = Type.Null();
override actionDescription = '重启服务';
override actionTags = ['系统接口'];
async _handle () {
const result = await WebUiDataRuntime.requestRestartProcess();

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
export const GetCookiesPayloadSchema = Type.Object({
domain: Type.String({ description: '需要获取 cookies 的域名' }),
});
@ -19,6 +21,10 @@ export class GetCookies extends OneBotAction<GetCookiesPayload, GetCookiesRespon
override actionName = ActionName.GetCookies;
override payloadSchema = GetCookiesPayloadSchema;
override returnSchema = GetCookiesReturnSchema;
override actionDescription = '获取 Cookies';
override actionTags = ['用户接口'];
override payloadExample = ActionExamples.GetCookies.payload;
override returnExample = ActionExamples.GetCookies.return;
async _handle (payload: GetCookiesPayload) {
const cookiesObject = await this.core.apis.UserApi.getCookies(payload.domain);

View File

@ -4,6 +4,8 @@ import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { OB11UserSchema } from '../schemas';
import { ActionExamples } from '../examples';
const PayloadSchema = Type.Object({
no_cache: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否不使用缓存' })),
});
@ -18,6 +20,10 @@ export default class GetFriendList extends OneBotAction<PayloadType, ReturnType>
override actionName = ActionName.GetFriendList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionDescription = '获取好友列表';
override actionTags = ['用户接口'];
override payloadExample = ActionExamples.GetFriendList.payload;
override returnExample = ActionExamples.GetFriendList.return;
async _handle (_payload: PayloadType) {
const buddyMap = await this.core.apis.FriendApi.getBuddyV2SimpleInfoMap();

View File

@ -2,6 +2,8 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
export const SendLikePayloadSchema = Type.Object({
user_id: Type.String({ description: '对方 QQ 号' }),
times: Type.Union([Type.Number(), Type.String()], { default: 1, description: '点赞次数' }),
@ -13,6 +15,13 @@ export default class SendLike extends OneBotAction<SendLikePayload, void> {
override actionName = ActionName.SendLike;
override payloadSchema = SendLikePayloadSchema;
override returnSchema = Type.Null();
override actionDescription = '点赞';
override actionTags = ['用户接口'];
override payloadExample = ActionExamples.SendLike.payload;
override errorExamples = [
...ActionExamples.Common.errors,
{ code: 1400, description: '点赞失败(频率过快或用户不存在)' }
];
async _handle (payload: SendLikePayload): Promise<void> {
const qq = payload.user_id.toString();

View File

@ -10,10 +10,15 @@ export const SetFriendAddRequestPayloadSchema = Type.Object({
export type SetFriendAddRequestPayload = Static<typeof SetFriendAddRequestPayloadSchema>;
import { ActionExamples } from '../examples';
export default class SetFriendAddRequest extends OneBotAction<SetFriendAddRequestPayload, void> {
override actionName = ActionName.SetFriendAddRequest;
override payloadSchema = SetFriendAddRequestPayloadSchema;
override returnSchema = Type.Null();
override actionDescription = '处理加好友请求';
override actionTags = ['用户接口'];
override payloadExample = ActionExamples.SetFriendAddRequest.payload;
async _handle (payload: SetFriendAddRequestPayload): Promise<void> {
const approve = payload.approve?.toString() !== 'false';

View File

@ -2,9 +2,11 @@ import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { ActionExamples } from '../examples';
export const SetFriendRemarkPayloadSchema = Type.Object({
user_id: Type.String({ description: '好友 QQ 号' }),
remark: Type.String({ description: '备注' }),
user_id: Type.String({ description: '对方 QQ 号' }),
remark: Type.String({ description: '备注内容' }),
});
export type SetFriendRemarkPayload = Static<typeof SetFriendRemarkPayloadSchema>;
@ -13,6 +15,13 @@ export default class SetFriendRemark extends OneBotAction<SetFriendRemarkPayload
override actionName = ActionName.SetFriendRemark;
override payloadSchema = SetFriendRemarkPayloadSchema;
override returnSchema = Type.Null();
override actionDescription = '设置好友备注';
override actionTags = ['用户接口'];
override payloadExample = ActionExamples.SetFriendRemark.payload;
override errorExamples = [
...ActionExamples.Common.errors,
{ code: 1400, description: '备注设置失败(好友不存在或非法输入)' }
];
async _handle (payload: SetFriendRemarkPayload): Promise<void> {
const friendUid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());

View File

@ -4,28 +4,52 @@ import { writeFileSync } from 'node:fs';
import { resolve, dirname } from 'node:path';
import { TSchema } from '@sinclair/typebox';
import { fileURLToPath } from 'node:url';
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export const actionSchemas: Record<string, { payload?: TSchema, return?: TSchema; }> = {};
interface ActionSchemaInfo {
payload?: TSchema;
return?: TSchema;
description?: string;
tags?: string[];
payloadExample?: unknown;
returnExample?: unknown;
errorExamples?: Array<{ code: number, description: string }>;
}
export const actionSchemas: Record<string, ActionSchemaInfo> = {};
export function initSchemas () {
const handlers = getAllHandlers(null as any, null as any);
handlers.forEach(handler => {
if (handler.actionName && (handler.actionName as string) !== 'unknown') {
const action = handler as OneBotAction<unknown, unknown>;
actionSchemas[handler.actionName] = {
payload: handler.payloadSchema,
return: handler.returnSchema
payload: action.payloadSchema,
return: action.returnSchema,
description: action.actionDescription,
tags: action.actionTags,
payloadExample: action.payloadExample,
returnExample: action.returnExample,
errorExamples: action.errorExamples
};
}
});
AutoRegisterRouter.forEach((ActionClass) => {
const handler = new ActionClass(null as any, null as any);
if (handler.actionName && (handler.actionName as string) !== 'unknown') {
const action = handler as OneBotAction<unknown, unknown>;
actionSchemas[handler.actionName] = {
payload: handler.payloadSchema,
return: handler.returnSchema
payload: action.payloadSchema,
return: action.returnSchema,
description: action.actionDescription,
tags: action.actionTags,
payloadExample: action.payloadExample,
returnExample: action.returnExample,
errorExamples: action.errorExamples
};
}
});
@ -38,14 +62,14 @@ export function generateOpenAPI () {
console.warn('Init schemas partial failure (expected due to complex imports), proceeding with collected data...');
}
const openapi: any = {
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',
version: '1.0.0'
},
paths: {}
paths: {} as Record<string, unknown>
};
for (const [actionName, schemas] of Object.entries(actionSchemas)) {
@ -55,9 +79,51 @@ 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: {} }));
openapi.paths[path] = {
if (schemas.payloadExample) {
cleanPayload.example = schemas.payloadExample;
}
if (schemas.returnExample) {
cleanReturn.example = schemas.returnExample;
}
const paths = openapi['paths'] as Record<string, any>;
const responses: Record<string, unknown> = {
'200': {
description: '成功',
content: {
'application/json': {
schema: cleanReturn
}
}
}
};
if (schemas.errorExamples) {
schemas.errorExamples.forEach(error => {
responses[error.code.toString()] = {
description: error.description,
content: {
'application/json': {
schema: {
type: 'object',
properties: {
status: { type: 'string', example: 'failed' },
retcode: { type: 'number', example: error.code },
data: { type: 'null' },
message: { type: 'string', example: error.description }
}
}
}
}
};
});
}
paths[path] = {
post: {
summary: actionName,
description: schemas.description || actionName,
tags: schemas.tags || ['Default'],
requestBody: {
content: {
'application/json': {
@ -65,16 +131,7 @@ export function generateOpenAPI () {
}
}
},
responses: {
'200': {
description: '成功',
content: {
'application/json': {
schema: cleanReturn
}
}
}
}
responses: responses
}
};
}