NapCatQQ/packages/napcat-satori/action/message/MessageCreate.ts
手瓜一十雪 b0d88d3705 Refactor Satori actions with schema validation and router
Refactored all Satori action classes to use TypeBox schemas for payload validation and unified action naming via a new router. Added schema-based parameter checking to the SatoriAction base class. Introduced new actions for guild and member approval, and login retrieval. Centralized action name constants and types in a new router module. Enhanced event and message APIs with more structured event types and parsing logic. Added helper utilities for XML parsing. Updated exports and registration logic to support the new structure.
2026-01-14 17:52:38 +08:00

75 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Static, Type } from '@sinclair/typebox';
import { SatoriAction } from '../SatoriAction';
import { SatoriActionName } from '../router';
import { SatoriMessage, SatoriChannelType } from '../../types';
import { ChatType, SendMessageElement } from 'napcat-core';
const SchemaData = Type.Object({
channel_id: Type.String(),
content: Type.String(),
});
type Payload = Static<typeof SchemaData>;
export class MessageCreateAction extends SatoriAction<Payload, SatoriMessage[]> {
actionName = SatoriActionName.MessageCreate;
override payloadSchema = SchemaData;
protected async _handle (payload: Payload): Promise<SatoriMessage[]> {
const { channel_id, content } = payload;
// 解析 channel_id格式: private:{user_id} 或 group:{group_id}
const parts = channel_id.split(':');
const type = parts[0];
const id = parts[1];
if (!type || !id) {
throw new Error(`无效的频道ID格式: ${channel_id}`);
}
let chatType: ChatType;
let peerUid: string;
if (type === 'private') {
chatType = ChatType.KCHATTYPEC2C;
peerUid = await this.core.apis.UserApi.getUidByUinV2(id);
} else if (type === 'group') {
chatType = ChatType.KCHATTYPEGROUP;
peerUid = id;
} else {
throw new Error(`不支持的频道类型: ${type}`);
}
// 解析 Satori 消息内容为 NapCat 消息元素
const elements = await this.satoriAdapter.apis.MsgApi.parseContent(content);
// 发送消息
const result = await this.core.apis.MsgApi.sendMsg(
{ chatType, peerUid, guildId: '' },
elements as SendMessageElement[],
30000
);
if (!result) {
throw new Error('消息发送失败: 未知错误');
}
// 构造返回结果
const message: SatoriMessage = {
id: result.msgId,
content,
channel: {
id: channel_id,
type: type === 'private' ? SatoriChannelType.DIRECT : SatoriChannelType.TEXT,
},
user: {
id: this.selfInfo.uin,
name: this.selfInfo.nick,
},
created_at: Date.now(),
};
return [message];
}
}