NapCatQQ source snapshot
This commit is contained in:
commit
f954252a34
1111 files changed
+139867
No files matched your search
@@ -0,0 +1,18 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { QzonePublicAction, QzonePublicContentSchema, QzonePublicFeedExample, QzonePublicFeedSchema } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({ feed: QzonePublicFeedSchema, content: QzonePublicContentSchema });
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class CommentQzonePublicFeed extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.CommentQzonePublicFeed;
|
||||
override actionSummary = '评论空友爱看动态';
|
||||
override actionDescription = '对完整 feed 发表评论;content 接受非空文本或富文本对象数组,富文本字段原样保留';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, content: '很有意思' };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.addComment(payload.feed, payload.content);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { QzonePublicAction, QzonePublicCommentExample, QzonePublicCommentSchema, QzonePublicFeedExample, QzonePublicFeedSchema } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({ feed: QzonePublicFeedSchema, comment: QzonePublicCommentSchema });
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class DeleteQzonePublicComment extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.DeleteQzonePublicComment;
|
||||
override actionSummary = '删除空友爱看评论';
|
||||
override actionDescription = '传入完整 feed 及 comment 删除评论,操作权限由上游校验';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, comment: QzonePublicCommentExample };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.deleteComment(payload.feed, payload.comment);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import {
|
||||
QzonePublicAction,
|
||||
QzonePublicCommentExample,
|
||||
QzonePublicCommentSchema,
|
||||
QzonePublicFeedExample,
|
||||
QzonePublicFeedSchema,
|
||||
QzonePublicReplyExample,
|
||||
QzonePublicReplySchema,
|
||||
} from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({ feed: QzonePublicFeedSchema, comment: QzonePublicCommentSchema, reply: QzonePublicReplySchema });
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class DeleteQzonePublicReply extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.DeleteQzonePublicReply;
|
||||
override actionSummary = '删除空友爱看回复';
|
||||
override actionDescription = '传入完整 feed、父 comment 和目标 reply 删除回复,操作权限由上游校验';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, comment: QzonePublicCommentExample, reply: QzonePublicReplyExample };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.deleteReply(payload.feed, payload.comment, payload.reply);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { QzonePublicAction, QzonePublicFeedExample, QzonePublicFeedSchema } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({
|
||||
feed: QzonePublicFeedSchema,
|
||||
reason: Type.Optional(Type.String({ default: '', description: '转发附言,默认空字符串;数字或布尔值会转为文本' })),
|
||||
});
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class ForwardQzonePublicFeed extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.ForwardQzonePublicFeed;
|
||||
override actionSummary = '转发空友爱看动态';
|
||||
override actionDescription = '将完整 feed 转发到自己的空间,可通过 reason 添加转发附言';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, reason: '分享一条动态' };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.forwardFeed(payload.feed, payload.reason ?? '');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { QzonePublicAction } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({});
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class GetQzonePublicCapabilities extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.GetQzonePublicCapabilities;
|
||||
override actionSummary = '获取空友爱看接口能力';
|
||||
override actionDescription = '获取当前 QQ 版本和账号可用的空友爱看接口能力,不会执行写操作';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = {};
|
||||
|
||||
async _handle () {
|
||||
return this.core.apis.QzonePublicApi.getCapabilities();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { QzonePublicAction, QzonePublicFeedExample, QzonePublicFeedSchema } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({
|
||||
feed: QzonePublicFeedSchema,
|
||||
cursor: Type.String({ minLength: 1, description: '动态详情或上一评论页返回的非空 attach_info;数字或布尔值会转为文本' }),
|
||||
});
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class GetQzonePublicComments extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.GetQzonePublicComments;
|
||||
override actionSummary = '获取空友爱看评论';
|
||||
override actionDescription = '读取动态的后续评论;cursor 为必填非空字符串,使用动态详情或上一评论页的 attach_info,原始评论对象应完整保留';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, cursor: 'detail-attach-info' };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.getComments(payload.feed, payload.cursor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { QzonePublicAction, QzonePublicFeedExample, QzonePublicFeedSchema } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({ feed: QzonePublicFeedSchema });
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class GetQzonePublicFeedDetail extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.GetQzonePublicFeedDetail;
|
||||
override actionSummary = '获取空友爱看动态详情';
|
||||
override actionDescription = '传入列表中的完整 feed 对象获取详情;继续读取评论时,将详情返回的 attach_info 作为 cursor';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.getFeedDetail(payload.feed);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import type { QzonePublicFeedsPage } from '@/napcat-core/data/qzone-public';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { QzonePublicAction, QzonePublicFeedExample, QzonePublicObjectSchema } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({
|
||||
cursor: Type.Optional(Type.String({ minLength: 1, maxLength: 65536, description: '上一页返回的非空 next_cursor,首次请求可省略;数字或布尔值会转为文本' })),
|
||||
});
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
const ReturnSchema = Type.Object({
|
||||
feeds: Type.Array(QzonePublicObjectSchema, { description: '完整动态对象,可直接传给详情和互动接口' }),
|
||||
has_more: Type.Boolean({ description: '是否还有下一页' }),
|
||||
next_cursor: Type.Union([Type.String(), Type.Null()], { description: '下一页游标,没有下一页时为 null' }),
|
||||
}, { additionalProperties: true, description: '动态列表分页结果,保留上游返回的额外字段' });
|
||||
|
||||
export class GetQzonePublicFeeds extends QzonePublicAction<PayloadType, QzonePublicFeedsPage> {
|
||||
override actionName = ActionName.GetQzonePublicFeeds;
|
||||
override actionSummary = '获取空友爱看动态';
|
||||
override actionDescription = '获取空友爱看动态列表;后续操作应直接传入 feeds 中的完整对象,翻页使用 next_cursor';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override returnSchema = ReturnSchema;
|
||||
override payloadExample = {};
|
||||
override returnExample = { feeds: [QzonePublicFeedExample], has_more: false, next_cursor: null };
|
||||
|
||||
async _handle (payload: PayloadType): Promise<QzonePublicFeedsPage> {
|
||||
return this.core.apis.QzonePublicApi.getFeeds(payload.cursor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import {
|
||||
parseQzonePublicPageSize,
|
||||
QzonePublicAction,
|
||||
QzonePublicCommentExample,
|
||||
QzonePublicCommentSchema,
|
||||
QzonePublicFeedExample,
|
||||
QzonePublicFeedSchema,
|
||||
} from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({
|
||||
feed: QzonePublicFeedSchema,
|
||||
comment: QzonePublicCommentSchema,
|
||||
cursor: Type.Optional(Type.String({ default: '', description: '回复分页游标,默认为空字符串;空字符串时使用 comment.reply_attach_info;数字或布尔值会转为文本' })),
|
||||
page_size: Type.Optional(Type.Union([
|
||||
Type.Number({ minimum: 1 }), Type.String(),
|
||||
], { default: 20, description: '每页回复数量,默认 20;有限数字或非空数值字符串,向零截断后应大于等于 1' })),
|
||||
});
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class GetQzonePublicReplies extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.GetQzonePublicReplies;
|
||||
override actionSummary = '获取空友爱看评论回复';
|
||||
override actionDescription = '传入完整动态及父评论读取回复分页;省略 cursor 时使用父评论中的 reply_attach_info';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, comment: QzonePublicCommentExample, page_size: 20 };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.getReplies(payload.feed, payload.comment, payload.cursor ?? '', parseQzonePublicPageSize(payload.page_size));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import {
|
||||
QzonePublicAction,
|
||||
QzonePublicCommentExample,
|
||||
QzonePublicCommentSchema,
|
||||
QzonePublicContentSchema,
|
||||
QzonePublicFeedExample,
|
||||
QzonePublicFeedSchema,
|
||||
QzonePublicReplySchema,
|
||||
} from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({
|
||||
feed: QzonePublicFeedSchema,
|
||||
comment: QzonePublicCommentSchema,
|
||||
content: QzonePublicContentSchema,
|
||||
reply: Type.Optional(QzonePublicReplySchema),
|
||||
});
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class ReplyQzonePublicFeed extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.ReplyQzonePublicFeed;
|
||||
override actionSummary = '回复空友爱看评论';
|
||||
override actionDescription = '传入完整 feed、父 comment 及非空 content 发表回复;需要回复已有回复时一并传入完整 reply';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, comment: QzonePublicCommentExample, content: '谢谢分享' };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.addReply(payload.feed, payload.comment, payload.content, payload.reply);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import {
|
||||
parseQzonePublicEnable,
|
||||
QzonePublicAction,
|
||||
QzonePublicCommentExample,
|
||||
QzonePublicCommentSchema,
|
||||
QzonePublicEnableSchema,
|
||||
QzonePublicFeedExample,
|
||||
QzonePublicFeedSchema,
|
||||
QzonePublicReplySchema,
|
||||
} from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({
|
||||
feed: QzonePublicFeedSchema,
|
||||
comment: QzonePublicCommentSchema,
|
||||
reply: Type.Optional(QzonePublicReplySchema),
|
||||
enable: QzonePublicEnableSchema,
|
||||
});
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class SetQzonePublicCommentLike extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.SetQzonePublicCommentLike;
|
||||
override actionSummary = '设置空友爱看评论或回复赞';
|
||||
override actionDescription = '对完整 comment 点赞或取消点赞;传入完整 reply 时操作该回复,保留 comment/reply 的 like.id 等字段';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, comment: QzonePublicCommentExample, enable: true };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.setCommentLike(payload.feed, payload.comment, parseQzonePublicEnable(payload.enable), payload.reply);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { parseQzonePublicEnable, QzonePublicAction, QzonePublicEnableSchema, QzonePublicFeedExample, QzonePublicFeedSchema } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({ feed: QzonePublicFeedSchema, enable: QzonePublicEnableSchema });
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class SetQzonePublicFollow extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.SetQzonePublicFollow;
|
||||
override actionSummary = '蹲或取消蹲空友爱看作者';
|
||||
override actionDescription = '根据完整 feed 蹲或取消蹲动态作者;enable 默认 true,返回上游操作结果';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, enable: true };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.setFollow(payload.feed, parseQzonePublicEnable(payload.enable));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { parseQzonePublicEnable, QzonePublicAction, QzonePublicEnableSchema, QzonePublicFeedExample, QzonePublicFeedSchema } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({ feed: QzonePublicFeedSchema, enable: QzonePublicEnableSchema });
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class SetQzonePublicLike extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.SetQzonePublicLike;
|
||||
override actionSummary = '设置空友爱看普通赞';
|
||||
override actionDescription = '对完整 feed 设置或取消普通点赞(like);enable 默认 true,此操作与推分别处理';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, enable: true };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.setLike(payload.feed, parseQzonePublicEnable(payload.enable));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { parseQzonePublicEnable, QzonePublicAction, QzonePublicEnableSchema, QzonePublicFeedExample, QzonePublicFeedSchema } from './common';
|
||||
|
||||
const PayloadSchema = Type.Object({ feed: QzonePublicFeedSchema, enable: QzonePublicEnableSchema });
|
||||
type PayloadType = Static<typeof PayloadSchema>;
|
||||
|
||||
export class SetQzonePublicUpvote extends QzonePublicAction<PayloadType> {
|
||||
override actionName = ActionName.SetQzonePublicUpvote;
|
||||
override actionSummary = '推或取消推空友爱看动态';
|
||||
override actionDescription = '对完整 feed 设置推或取消推(upvote);enable 默认 true,此操作与普通点赞分别处理';
|
||||
override payloadSchema = PayloadSchema;
|
||||
override payloadExample = { feed: QzonePublicFeedExample, enable: true };
|
||||
|
||||
async _handle (payload: PayloadType) {
|
||||
return this.core.apis.QzonePublicApi.setUpvote(payload.feed, parseQzonePublicEnable(payload.enable));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
import { Type } from '@sinclair/typebox';
|
||||
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
|
||||
import type { BaseCheckResult } from '@/napcat-onebot/action/router';
|
||||
import type { QzonePublicObject } from '@/napcat-core/data/qzone-public';
|
||||
|
||||
export const QzonePublicObjectSchema = Type.Object({}, { additionalProperties: Type.Unknown() });
|
||||
export const QzonePublicFeedSchema = Type.Object({}, {
|
||||
additionalProperties: Type.Unknown(),
|
||||
description: 'get_qzone_public_feeds 返回的完整 feed 对象,请保留全部字段',
|
||||
});
|
||||
export const QzonePublicCommentSchema = Type.Object({}, {
|
||||
additionalProperties: Type.Unknown(),
|
||||
description: '详情或评论列表返回的完整 comment 对象,请保留 like.id 等全部字段',
|
||||
});
|
||||
export const QzonePublicReplySchema = Type.Object({}, {
|
||||
additionalProperties: Type.Unknown(),
|
||||
description: '回复列表返回的完整 reply 对象,请保留全部字段',
|
||||
});
|
||||
export const QzonePublicResultSchema = Type.Object({}, {
|
||||
additionalProperties: Type.Unknown(),
|
||||
description: '上游返回的原始 JSON 对象,字段随内容类型和服务端版本变化',
|
||||
});
|
||||
export const QzonePublicEnableSchema = Type.Optional(Type.Union([
|
||||
Type.Boolean(), Type.Number(), Type.String(),
|
||||
], { default: true, description: '是否启用,默认 true;数字非 0 为 true,文本支持 true/false、1/0、yes/no、on/off' }));
|
||||
export const QzonePublicContentSchema = Type.Union([
|
||||
Type.String({ minLength: 1 }),
|
||||
Type.Array(QzonePublicObjectSchema, { minItems: 1 }),
|
||||
], { description: '非空文本或非空富文本对象数组,保留每个对象的全部字段' });
|
||||
|
||||
// 示例仅说明对象传递方式;实际调用应直接使用上游返回的完整对象。
|
||||
export const QzonePublicFeedExample = {
|
||||
cell_common: {
|
||||
union_id: { uf_key: 'example-uf-key', ugc_id: 'example-ugc-id', feed_id: 'example-feed-id', ext_ids: [] },
|
||||
cur_like_key: 'example-like-key',
|
||||
domain_type: 3,
|
||||
},
|
||||
cell_user_info: { user: { uin: '10001' } },
|
||||
cell_feed_transfer: {},
|
||||
};
|
||||
export const QzonePublicCommentExample = { id: 'example-comment', like: { id: 'example-comment-like' }, reply_attach_info: '' };
|
||||
export const QzonePublicReplyExample = { id: 'example-reply', like: { id: 'example-reply-like' } };
|
||||
|
||||
export function parseQzonePublicEnable (value: boolean | number | string | undefined): boolean {
|
||||
if (value === undefined) return true;
|
||||
if (typeof value === 'boolean') return value;
|
||||
if (typeof value === 'number') return value !== 0;
|
||||
if (typeof value === 'string') {
|
||||
const text = value.trim().toLowerCase();
|
||||
if (['true', '1', 'yes', 'on'].includes(text)) return true;
|
||||
if (['false', '0', 'no', 'off'].includes(text)) return false;
|
||||
}
|
||||
throw new Error('enable 必须为布尔值、数字或 true/false、1/0、yes/no、on/off 文本');
|
||||
}
|
||||
|
||||
export function parseQzonePublicPageSize (value: number | string | undefined): number {
|
||||
if (value === undefined) return 20;
|
||||
if (typeof value !== 'number' && typeof value !== 'string') {
|
||||
throw new Error('page_size 必须为数字或数值字符串,截断后应大于等于 1');
|
||||
}
|
||||
if (typeof value === 'string' && !value.trim()) {
|
||||
throw new Error('page_size 必须为数字或数值字符串,截断后应大于等于 1');
|
||||
}
|
||||
const numericValue = Number(value);
|
||||
const pageSize = Math.trunc(numericValue);
|
||||
if (!Number.isFinite(numericValue) || pageSize < 1) {
|
||||
throw new Error('page_size 必须为数字或数值字符串,截断后应大于等于 1');
|
||||
}
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
function isObject (value: unknown): value is QzonePublicObject {
|
||||
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
||||
}
|
||||
|
||||
export abstract class QzonePublicAction<PayloadType, ReturnType = QzonePublicObject> extends OneBotAction<PayloadType, ReturnType> {
|
||||
override actionTags = ['QQ空间扩展'];
|
||||
override returnSchema = QzonePublicResultSchema;
|
||||
override returnExample = {};
|
||||
|
||||
protected override async check (payload: PayloadType): Promise<BaseCheckResult> {
|
||||
// OneBot 的通用解析会转换原始类型。先校验这些透传参数,避免数字被当作文本或对象。
|
||||
if (!isObject(payload)) return { valid: false, message: '请求参数必须为 JSON 对象' };
|
||||
const parameters: QzonePublicObject = payload;
|
||||
for (const key of ['feed', 'comment', 'reply']) {
|
||||
if (parameters[key] !== undefined && !isObject(parameters[key])) {
|
||||
return { valid: false, message: `${key} 必须为上游返回的完整 JSON 对象` };
|
||||
}
|
||||
}
|
||||
for (const key of ['cursor', 'reason']) {
|
||||
const value = parameters[key];
|
||||
if (value !== undefined) {
|
||||
if (!['string', 'number', 'boolean'].includes(typeof value)) {
|
||||
return { valid: false, message: `${key} 必须为字符串、数字或布尔值` };
|
||||
}
|
||||
parameters[key] = String(value);
|
||||
}
|
||||
}
|
||||
if ('content' in parameters) {
|
||||
let content = parameters['content'];
|
||||
if (typeof content === 'string') {
|
||||
const text = content.trim();
|
||||
if (text.startsWith('[') && text.endsWith(']')) {
|
||||
try {
|
||||
const decoded: unknown = JSON.parse(text);
|
||||
if (Array.isArray(decoded)) content = decoded;
|
||||
} catch {
|
||||
// 无效 JSON 仍按原始文本处理。
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof content === 'string' ? content.length === 0 : !Array.isArray(content) || content.length === 0 || !content.every(isObject)) {
|
||||
return { valid: false, message: 'content 必须为非空文本或非空富文本对象数组' };
|
||||
}
|
||||
parameters['content'] = content;
|
||||
}
|
||||
try {
|
||||
if ('enable' in parameters) parameters['enable'] = parseQzonePublicEnable(parameters['enable'] as boolean | number | string | undefined);
|
||||
if ('page_size' in parameters) parameters['page_size'] = parseQzonePublicPageSize(parameters['page_size'] as number | string | undefined);
|
||||
} catch (error) {
|
||||
return { valid: false, message: (error as Error).message };
|
||||
}
|
||||
return super.check(payload as PayloadType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/** Decode individual GET / form values before applying the public Qzone action contract. */
|
||||
export function decodeQzonePublicHttpParameters (parameters: unknown): Record<string, unknown> {
|
||||
if (parameters === null || typeof parameters !== 'object' || Array.isArray(parameters)) return {};
|
||||
return Object.fromEntries(Object.entries(parameters).map(([key, value]) => {
|
||||
if (typeof value !== 'string') return [key, value];
|
||||
try {
|
||||
return [key, JSON.parse(value) as unknown];
|
||||
} catch {
|
||||
return [key, value];
|
||||
}
|
||||
}));
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export { GetQzonePublicCapabilities } from './GetQzonePublicCapabilities';
|
||||
export { GetQzonePublicFeeds } from './GetQzonePublicFeeds';
|
||||
export { GetQzonePublicFeedDetail } from './GetQzonePublicFeedDetail';
|
||||
export { GetQzonePublicComments } from './GetQzonePublicComments';
|
||||
export { GetQzonePublicReplies } from './GetQzonePublicReplies';
|
||||
export { SetQzonePublicUpvote } from './SetQzonePublicUpvote';
|
||||
export { SetQzonePublicLike } from './SetQzonePublicLike';
|
||||
export { SetQzonePublicFollow } from './SetQzonePublicFollow';
|
||||
export { SetQzonePublicCommentLike } from './SetQzonePublicCommentLike';
|
||||
export { CommentQzonePublicFeed } from './CommentQzonePublicFeed';
|
||||
export { ReplyQzonePublicFeed } from './ReplyQzonePublicFeed';
|
||||
export { DeleteQzonePublicComment } from './DeleteQzonePublicComment';
|
||||
export { DeleteQzonePublicReply } from './DeleteQzonePublicReply';
|
||||
export { ForwardQzonePublicFeed } from './ForwardQzonePublicFeed';
|
||||
Reference in new issue
Block a user