NapCatQQ source snapshot
This commit is contained in:
commit
f954252a34
1111 files changed
+139867
No files matched your search
@@ -0,0 +1,40 @@
|
||||
import { MessageUnique } from 'napcat-common/src/message-unique';
|
||||
import { ChatType, Peer } from 'napcat-core';
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
|
||||
|
||||
export const GroupTodoPayloadSchema = Type.Object({
|
||||
group_id: Type.Union([Type.String(), Type.Number()], { description: '群号' }),
|
||||
message_id: Type.Optional(Type.String({ description: '消息ID' })),
|
||||
message_seq: Type.Optional(Type.String({ description: '消息Seq (可选)' })),
|
||||
});
|
||||
|
||||
export type GroupTodoPayload = Static<typeof GroupTodoPayloadSchema>;
|
||||
|
||||
export abstract class BaseGroupTodoAction extends GetPacketStatusDepends<GroupTodoPayload, void> {
|
||||
override payloadSchema = GroupTodoPayloadSchema;
|
||||
override returnSchema = Type.Null();
|
||||
override actionTags = ['核心接口'];
|
||||
|
||||
protected abstract handleGroupTodo (groupId: number, msgSeq: string): Promise<void>;
|
||||
|
||||
async _handle (payload: GroupTodoPayload) {
|
||||
const groupId = +payload.group_id;
|
||||
if (payload.message_seq) {
|
||||
return await this.handleGroupTodo(groupId, payload.message_seq.toString());
|
||||
}
|
||||
if (!payload.message_id) {
|
||||
throw new Error('缺少参数 message_id 或 message_seq');
|
||||
}
|
||||
const peer: Peer = {
|
||||
chatType: ChatType.KCHATTYPEGROUP,
|
||||
peerUid: payload.group_id.toString(),
|
||||
};
|
||||
const { MsgId, Peer } = MessageUnique.getMsgIdAndPeerByShortId(+payload.message_id) ?? { Peer: peer, MsgId: payload.message_id.toString() };
|
||||
const msg = (await this.core.apis.MsgApi.getMsgsByMsgId(Peer, [MsgId])).msgList[0];
|
||||
if (!msg) {
|
||||
throw new Error('消息不存在');
|
||||
}
|
||||
await this.handleGroupTodo(groupId, msg.msgSeq);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ActionName } from '../router';
|
||||
import { PacketActionsExamples } from '../example/PacketActionsExamples';
|
||||
import { BaseGroupTodoAction } from './BaseGroupTodoAction';
|
||||
|
||||
export class CancelGroupTodo extends BaseGroupTodoAction {
|
||||
override actionName = ActionName.CancelGroupTodo;
|
||||
override actionSummary = '取消群待办';
|
||||
override actionDescription = '将指定消息对应的群待办取消';
|
||||
override payloadExample = PacketActionsExamples.CancelGroupTodo.payload;
|
||||
override returnExample = PacketActionsExamples.CancelGroupTodo.response;
|
||||
|
||||
protected override async handleGroupTodo (groupId: number, msgSeq: string) {
|
||||
await this.core.apis.PacketApi.pkt.operation.CancelGroupTodo(groupId, msgSeq);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ActionName } from '../router';
|
||||
import { PacketActionsExamples } from '../example/PacketActionsExamples';
|
||||
import { BaseGroupTodoAction } from './BaseGroupTodoAction';
|
||||
|
||||
export class CompleteGroupTodo extends BaseGroupTodoAction {
|
||||
override actionName = ActionName.CompleteGroupTodo;
|
||||
override actionSummary = '完成群待办';
|
||||
override actionDescription = '将指定消息对应的群待办标记为已完成';
|
||||
override payloadExample = PacketActionsExamples.CompleteGroupTodo.payload;
|
||||
override returnExample = PacketActionsExamples.CompleteGroupTodo.response;
|
||||
|
||||
protected override async handleGroupTodo (groupId: number, msgSeq: string) {
|
||||
await this.core.apis.PacketApi.pkt.operation.CompleteGroupTodo(groupId, msgSeq);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
|
||||
import { ActionName, BaseCheckResult } from '@/napcat-onebot/action/router';
|
||||
import { Type } from '@sinclair/typebox';
|
||||
|
||||
export abstract class GetPacketStatusDepends<PT, RT> extends OneBotAction<PT, RT> {
|
||||
protected override async check (payload: PT): Promise<BaseCheckResult> {
|
||||
const schemaResult = await super.check(payload);
|
||||
if (!schemaResult.valid) return schemaResult;
|
||||
if (!this.core.apis.PacketApi.packetStatus) {
|
||||
return {
|
||||
valid: false,
|
||||
message: 'packetBackend不可用,请参照文档 https://napneko.github.io/config/advanced 和启动日志检查packetBackend状态或进行配置!' +
|
||||
'错误堆栈信息:' + this.core.apis.PacketApi.clientLogStack,
|
||||
};
|
||||
}
|
||||
return { valid: true };
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class PacketSendAvailableDepends<PT, RT> extends OneBotAction<PT, RT> {
|
||||
protected override async check (payload: PT): Promise<BaseCheckResult> {
|
||||
const schemaResult = await super.check(payload);
|
||||
if (!schemaResult.valid) return schemaResult;
|
||||
if (!this.core.apis.PacketApi.available) {
|
||||
return {
|
||||
valid: false,
|
||||
message: 'packetBackend发包能力不可用,请参照文档 https://napneko.github.io/config/advanced 和启动日志检查packetBackend状态或进行配置!' +
|
||||
'错误堆栈信息:' + this.core.apis.PacketApi.clientLogStack,
|
||||
};
|
||||
}
|
||||
return { valid: true };
|
||||
}
|
||||
}
|
||||
|
||||
export class GetPacketStatus extends GetPacketStatusDepends<void, void> {
|
||||
override actionName = ActionName.GetPacketStatus;
|
||||
override payloadSchema = Type.Object({});
|
||||
override returnSchema = Type.Null();
|
||||
override actionSummary = '获取Packet状态';
|
||||
override actionDescription = '获取底层Packet服务的运行状态';
|
||||
override actionTags = ['系统接口'];
|
||||
override payloadExample = {};
|
||||
override returnExample = null;
|
||||
|
||||
async _handle () {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
|
||||
import { Type, Static } from '@sinclair/typebox';
|
||||
|
||||
export const GetRkeyExReturnSchema = Type.Array(Type.Object({
|
||||
type: Type.String({ description: '类型 (private/group)' }),
|
||||
rkey: Type.String({ description: 'RKey' }),
|
||||
created_at: Type.Number({ description: '创建时间' }),
|
||||
ttl: Type.Number({ description: '有效期' }),
|
||||
}), { description: 'RKey 列表' });
|
||||
|
||||
export type GetRkeyExReturn = Static<typeof GetRkeyExReturnSchema>;
|
||||
|
||||
export class GetRkeyEx extends GetPacketStatusDepends<void, GetRkeyExReturn> {
|
||||
override actionName = ActionName.GetRkeyEx;
|
||||
override payloadSchema = Type.Object({});
|
||||
override returnSchema = GetRkeyExReturnSchema;
|
||||
override actionSummary = '获取扩展 RKey';
|
||||
override actionTags = ['系统扩展'];
|
||||
override payloadExample = {};
|
||||
override returnExample = [
|
||||
{
|
||||
type: 'private',
|
||||
rkey: 'rkey_123',
|
||||
created_at: 1734567890,
|
||||
ttl: 3600,
|
||||
},
|
||||
];
|
||||
|
||||
async _handle () {
|
||||
const rkeys = await this.core.apis.PacketApi.pkt.operation.FetchRkey();
|
||||
return rkeys.map(rkey => {
|
||||
return {
|
||||
type: rkey.type === 10 ? 'private' : 'group',
|
||||
rkey: rkey.rkey,
|
||||
created_at: Number(rkey.time),
|
||||
ttl: Number(rkey.ttl),
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
|
||||
import { Type, Static } from '@sinclair/typebox';
|
||||
|
||||
export const GetRkeyServerReturnSchema = Type.Object({
|
||||
private_rkey: Type.Optional(Type.String({ description: '私聊 RKey' })),
|
||||
group_rkey: Type.Optional(Type.String({ description: '群聊 RKey' })),
|
||||
expired_time: Type.Optional(Type.Number({ description: '过期时间' })),
|
||||
name: Type.String({ description: '名称' }),
|
||||
});
|
||||
|
||||
export type GetRkeyServerReturn = Static<typeof GetRkeyServerReturnSchema>;
|
||||
|
||||
export class GetRkeyServer extends GetPacketStatusDepends<void, GetRkeyServerReturn> {
|
||||
override actionName = ActionName.GetRkeyServer;
|
||||
override actionSummary = '获取 RKey 服务器';
|
||||
override actionTags = ['系统扩展'];
|
||||
override payloadExample = {};
|
||||
override returnExample = {
|
||||
private_rkey: '&rkey=123456789',
|
||||
group_rkey: '&rkey=123456789',
|
||||
expired_time: 1694560000,
|
||||
name: 'NapCat 4',
|
||||
};
|
||||
|
||||
override payloadSchema = Type.Object({});
|
||||
override returnSchema = GetRkeyServerReturnSchema;
|
||||
|
||||
private rkeyCache: GetRkeyServerReturn | null = null;
|
||||
|
||||
private expiryTime: number | null = null;
|
||||
|
||||
async _handle () {
|
||||
// 检查缓存是否有效
|
||||
if (this.expiryTime && this.expiryTime > Math.floor(Date.now() / 1000) && this.rkeyCache) {
|
||||
return this.rkeyCache;
|
||||
}
|
||||
|
||||
// 获取新的 Rkey
|
||||
const rkeys = await this.core.apis.PacketApi.pkt.operation.FetchRkey();
|
||||
const privateRkeyItem = rkeys.filter(rkey => rkey.type === 10)[0];
|
||||
const groupRkeyItem = rkeys.filter(rkey => rkey.type === 20)[0];
|
||||
|
||||
this.expiryTime = Math.floor(Date.now() / 1000) + Math.min(+groupRkeyItem!.ttl.toString(), +privateRkeyItem!.ttl.toString());
|
||||
|
||||
// 更新缓存
|
||||
this.rkeyCache = {
|
||||
private_rkey: privateRkeyItem ? privateRkeyItem.rkey : undefined,
|
||||
group_rkey: groupRkeyItem ? groupRkeyItem.rkey : undefined,
|
||||
expired_time: this.expiryTime,
|
||||
name: 'NapCat 4',
|
||||
};
|
||||
|
||||
return this.rkeyCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { PacketSendAvailableDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
|
||||
import { PacketActionsExamples } from '../example/PacketActionsExamples';
|
||||
|
||||
export const SendPokePayloadSchema = Type.Object({
|
||||
group_id: Type.Optional(Type.String({ description: '群号' })),
|
||||
user_id: Type.String({ description: '用户QQ' }),
|
||||
target_id: Type.Optional(Type.String({ description: '目标QQ' })),
|
||||
});
|
||||
|
||||
export type SendPokePayload = Static<typeof SendPokePayloadSchema>;
|
||||
export class SendPokeBase extends PacketSendAvailableDepends<SendPokePayload, void> {
|
||||
override payloadSchema = SendPokePayloadSchema;
|
||||
override returnSchema = Type.Null();
|
||||
override actionSummary = '发送戳一戳';
|
||||
override actionDescription = '在群聊或私聊中发送戳一戳动作';
|
||||
override actionTags = ['核心接口'];
|
||||
override payloadExample = PacketActionsExamples.SendPoke.payload;
|
||||
override returnExample = PacketActionsExamples.SendPoke.response;
|
||||
|
||||
async _handle (payload: SendPokePayload) {
|
||||
// 这里的 !! 可以传入空字符串 忽略这些数据有利用接口统一接口
|
||||
const target_id = payload.target_id?.toString() || payload.user_id?.toString();
|
||||
const peer_id = payload.group_id?.toString() || payload.user_id?.toString();
|
||||
|
||||
const is_group = !!payload.group_id;
|
||||
if (!target_id || !peer_id) {
|
||||
throw new Error('请检查参数,缺少 user_id 或 group_id');
|
||||
}
|
||||
|
||||
await this.core.apis.PacketApi.pkt.operation.SendPoke(is_group, +peer_id, +target_id);
|
||||
}
|
||||
}
|
||||
|
||||
export class SendPoke extends SendPokeBase {
|
||||
override actionName = ActionName.SendPoke;
|
||||
}
|
||||
export class GroupPoke extends SendPokeBase {
|
||||
override actionName = ActionName.GroupPoke;
|
||||
}
|
||||
export class FriendPoke extends SendPokeBase {
|
||||
override actionName = ActionName.FriendPoke;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { ActionName } from '../router';
|
||||
import { PacketActionsExamples } from '../example/PacketActionsExamples';
|
||||
import { BaseGroupTodoAction } from './BaseGroupTodoAction';
|
||||
export class SetGroupTodo extends BaseGroupTodoAction {
|
||||
override actionName = ActionName.SetGroupTodo;
|
||||
override actionSummary = '设置群待办';
|
||||
override actionDescription = '将指定消息设置为群待办';
|
||||
override payloadExample = PacketActionsExamples.SetGroupTodo.payload;
|
||||
override returnExample = PacketActionsExamples.SetGroupTodo.response;
|
||||
|
||||
protected override async handleGroupTodo (groupId: number, msgSeq: string) {
|
||||
await this.core.apis.PacketApi.pkt.operation.SetGroupTodo(groupId, msgSeq);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user