@zhin.js/core 1.0.46 → 1.0.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/lib/adapter.d.ts +10 -0
- package/lib/adapter.d.ts.map +1 -1
- package/lib/adapter.js +15 -0
- package/lib/adapter.js.map +1 -1
- package/lib/bot.d.ts +8 -2
- package/lib/bot.d.ts.map +1 -1
- package/lib/built/message-filter.js +2 -2
- package/lib/built/message-filter.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/notice.d.ts +81 -0
- package/lib/notice.d.ts.map +1 -0
- package/lib/notice.js +11 -0
- package/lib/notice.js.map +1 -0
- package/lib/plugin.d.ts +6 -0
- package/lib/plugin.d.ts.map +1 -1
- package/lib/plugin.js.map +1 -1
- package/lib/request.d.ts +85 -0
- package/lib/request.d.ts.map +1 -0
- package/lib/request.js +11 -0
- package/lib/request.js.map +1 -0
- package/package.json +6 -6
- package/src/adapter.ts +25 -0
- package/src/bot.ts +8 -2
- package/src/built/message-filter.ts +2 -2
- package/src/index.ts +2 -0
- package/src/notice.ts +98 -0
- package/src/plugin.ts +8 -0
- package/src/request.ts +95 -0
- package/tests/message-filter.test.ts +566 -0
- package/tests/notice.test.ts +198 -0
- package/tests/request.test.ts +221 -0
package/lib/request.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAuFA,MAAM,KAAW,OAAO,CAOvB;AAPD,WAAiB,OAAO;IACtB;;OAEG;IACH,SAAgB,IAAI,CAAmB,KAAQ,EAAE,MAAmB;QAClE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAFe,YAAI,OAEnB,CAAA;AACH,CAAC,EAPgB,OAAO,KAAP,OAAO,QAOvB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.47",
|
|
4
4
|
"description": "Zhin机器人核心框架",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"segment-matcher": "^1.0.5",
|
|
38
38
|
"smol-toml": "^1.6.0",
|
|
39
39
|
"yaml": "^2.3.4",
|
|
40
|
-
"@zhin.js/
|
|
41
|
-
"@zhin.js/database": "1.0.
|
|
42
|
-
"@zhin.js/
|
|
43
|
-
"@zhin.js/logger": "0.1.
|
|
44
|
-
"@zhin.js/schema": "1.0.
|
|
40
|
+
"@zhin.js/ai": "1.0.8",
|
|
41
|
+
"@zhin.js/database": "1.0.34",
|
|
42
|
+
"@zhin.js/kernel": "0.0.8",
|
|
43
|
+
"@zhin.js/logger": "0.1.31",
|
|
44
|
+
"@zhin.js/schema": "1.0.31"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/node": "^24.3.0",
|
package/src/adapter.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { Bot } from "./bot.js";
|
|
|
2
2
|
import { Plugin } from "./plugin.js";
|
|
3
3
|
import { EventEmitter } from "events";
|
|
4
4
|
import { Message } from "./message.js";
|
|
5
|
+
import { Notice, NoticeType } from "./notice.js";
|
|
6
|
+
import { Request, RequestType } from "./request.js";
|
|
5
7
|
import { BeforeSendHandler, SendOptions, Tool, ToolContext, ToolScope } from "./types.js";
|
|
6
8
|
import { segment } from "./utils.js";
|
|
7
9
|
import { ZhinTool, isZhinTool, type ToolInput } from "./built/tool.js";
|
|
@@ -53,6 +55,21 @@ export abstract class Adapter<R extends Bot = Bot> extends EventEmitter<Adapter.
|
|
|
53
55
|
});
|
|
54
56
|
}
|
|
55
57
|
});
|
|
58
|
+
this.on('notice.receive', (notice) => {
|
|
59
|
+
this.logger.info(`${notice.$bot} notice ${notice.$type}${notice.$subType ? '.' + notice.$subType : ''} ${notice.$channel.type}(${notice.$channel.id})`);
|
|
60
|
+
const rootPlugin = this.plugin?.root || this.plugin;
|
|
61
|
+
rootPlugin?.dispatch('notice.receive', notice);
|
|
62
|
+
// 分发细粒度事件: notice.{type} 和 notice.{channelType}.{type}
|
|
63
|
+
rootPlugin?.dispatch(`notice.${notice.$type}` as 'notice.receive', notice);
|
|
64
|
+
rootPlugin?.dispatch(`notice.${notice.$channel.type}.${notice.$type}` as 'notice.receive', notice);
|
|
65
|
+
});
|
|
66
|
+
this.on('request.receive', (request) => {
|
|
67
|
+
this.logger.info(`${request.$bot} request ${request.$type}${request.$subType ? '.' + request.$subType : ''} from ${request.$sender.id}`);
|
|
68
|
+
const rootPlugin = this.plugin?.root || this.plugin;
|
|
69
|
+
rootPlugin?.dispatch('request.receive', request);
|
|
70
|
+
// 分发细粒度事件: request.{type}
|
|
71
|
+
rootPlugin?.dispatch(`request.${request.$type}` as 'request.receive', request);
|
|
72
|
+
});
|
|
56
73
|
}
|
|
57
74
|
abstract createBot(config: Adapter.BotConfig<R>): R;
|
|
58
75
|
get logger() {
|
|
@@ -322,6 +339,14 @@ export namespace Adapter {
|
|
|
322
339
|
'message.private.receive': [Message];
|
|
323
340
|
'message.group.receive': [Message];
|
|
324
341
|
'message.channel.receive': [Message];
|
|
342
|
+
'notice.receive': [Notice];
|
|
343
|
+
'notice.private.receive': [Notice];
|
|
344
|
+
'notice.group.receive': [Notice];
|
|
345
|
+
'notice.channel.receive': [Notice];
|
|
346
|
+
'request.receive': [Request];
|
|
347
|
+
'request.friend_add': [Request];
|
|
348
|
+
'request.group_add': [Request];
|
|
349
|
+
'request.group_invite': [Request];
|
|
325
350
|
'call.recallMessage': [string, string];
|
|
326
351
|
}
|
|
327
352
|
/**
|
package/src/bot.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { SendOptions } from "./types.js";
|
|
2
2
|
import { Message } from "./message.js";
|
|
3
|
+
import { Notice } from "./notice.js";
|
|
4
|
+
import { Request } from "./request.js";
|
|
3
5
|
import { Adapter, Adapters } from "./adapter.js";
|
|
4
6
|
/**
|
|
5
7
|
* Bot接口:所有平台机器人需实现的统一接口。
|
|
6
8
|
* 负责消息格式化、连接、断开、消息发送等。
|
|
7
|
-
* @template
|
|
8
|
-
* @template
|
|
9
|
+
* @template Config 配置类型
|
|
10
|
+
* @template Event 消息事件类型
|
|
9
11
|
*/
|
|
10
12
|
export interface Bot<Config extends object= {},Event extends object = {}> {
|
|
11
13
|
$id:string
|
|
@@ -15,6 +17,10 @@ export interface Bot<Config extends object= {},Event extends object = {}> {
|
|
|
15
17
|
$connected: boolean;
|
|
16
18
|
/** 格式化平台消息为标准Message结构 */
|
|
17
19
|
$formatMessage(event: Event): Message<Event>;
|
|
20
|
+
/** 格式化平台通知为标准Notice结构(适配器可选实现) */
|
|
21
|
+
$formatNotice?(event: any): Notice<any>;
|
|
22
|
+
/** 格式化平台请求为标准Request结构(适配器可选实现) */
|
|
23
|
+
$formatRequest?(event: any): Request<any>;
|
|
18
24
|
/** 连接机器人 */
|
|
19
25
|
$connect(): Promise<void>;
|
|
20
26
|
/** 断开机器人 */
|
|
@@ -370,10 +370,10 @@ export class MessageFilterFeature extends Feature<FilterRule> {
|
|
|
370
370
|
if (rule.bots?.length && !this.#matchAny(rule.bots, String(message.$bot))) {
|
|
371
371
|
return false;
|
|
372
372
|
}
|
|
373
|
-
if (rule.channels?.length && !this.#matchAny(rule.channels, message.$channel.id)) {
|
|
373
|
+
if (rule.channels?.length && !this.#matchAny(rule.channels, String(message.$channel.id))) {
|
|
374
374
|
return false;
|
|
375
375
|
}
|
|
376
|
-
if (rule.senders?.length && !this.#matchAny(rule.senders, message.$sender.id)) {
|
|
376
|
+
if (rule.senders?.length && !this.#matchAny(rule.senders, String(message.$sender.id))) {
|
|
377
377
|
return false;
|
|
378
378
|
}
|
|
379
379
|
return true;
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,8 @@ export * from './command.js'
|
|
|
6
6
|
export * from './component.js'
|
|
7
7
|
export * from './adapter.js'
|
|
8
8
|
export * from './message.js'
|
|
9
|
+
export * from './notice.js'
|
|
10
|
+
export * from './request.js'
|
|
9
11
|
export * from './prompt.js'
|
|
10
12
|
// Models
|
|
11
13
|
export * from './models/system-log.js'
|
package/src/notice.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Adapters } from './adapter.js';
|
|
2
|
+
import type { MessageSender } from './types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 通知类型枚举
|
|
6
|
+
*
|
|
7
|
+
* 常见 IM 通知事件分类:
|
|
8
|
+
* - group_member_increase: 群成员增加(入群)
|
|
9
|
+
* - group_member_decrease: 群成员减少(退群/被踢)
|
|
10
|
+
* - group_admin_change: 群管理员变动
|
|
11
|
+
* - group_ban: 群禁言
|
|
12
|
+
* - group_recall: 群消息撤回
|
|
13
|
+
* - friend_recall: 好友消息撤回
|
|
14
|
+
* - friend_add: 新增好友
|
|
15
|
+
* - group_poke: 群戳一戳
|
|
16
|
+
* - friend_poke: 好友戳一戳
|
|
17
|
+
* - group_transfer: 群转让
|
|
18
|
+
*
|
|
19
|
+
* 适配器可自行扩展更多子类型
|
|
20
|
+
*/
|
|
21
|
+
export type NoticeType =
|
|
22
|
+
| 'group_member_increase'
|
|
23
|
+
| 'group_member_decrease'
|
|
24
|
+
| 'group_admin_change'
|
|
25
|
+
| 'group_ban'
|
|
26
|
+
| 'group_recall'
|
|
27
|
+
| 'friend_recall'
|
|
28
|
+
| 'friend_add'
|
|
29
|
+
| 'group_poke'
|
|
30
|
+
| 'friend_poke'
|
|
31
|
+
| 'group_transfer'
|
|
32
|
+
| (string & {}); // 允许适配器扩展自定义类型
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 通知频道信息
|
|
36
|
+
*/
|
|
37
|
+
export interface NoticeChannel {
|
|
38
|
+
id: string;
|
|
39
|
+
type: 'group' | 'private' | 'channel';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 通知基础结构
|
|
44
|
+
*
|
|
45
|
+
* 与 MessageBase 同构设计,所有通知共享以下字段。
|
|
46
|
+
* 适配器通过 `Notice.from(raw, base)` 合并平台原始数据和标准字段。
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* // 适配器中格式化通知
|
|
51
|
+
* const notice = Notice.from(rawEvent, {
|
|
52
|
+
* $id: rawEvent.id,
|
|
53
|
+
* $adapter: 'icqq',
|
|
54
|
+
* $bot: botName,
|
|
55
|
+
* $type: 'group_member_decrease',
|
|
56
|
+
* $subType: 'kick',
|
|
57
|
+
* $channel: { id: groupId, type: 'group' },
|
|
58
|
+
* $operator: { id: operatorId, name: '管理员' },
|
|
59
|
+
* $target: { id: userId, name: '被踢者' },
|
|
60
|
+
* $timestamp: Date.now(),
|
|
61
|
+
* });
|
|
62
|
+
* this.adapter.emit('notice.receive', notice);
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export interface NoticeBase {
|
|
66
|
+
/** 通知唯一 ID(平台提供或自生成) */
|
|
67
|
+
$id: string;
|
|
68
|
+
/** 适配器名称 */
|
|
69
|
+
$adapter: keyof Adapters;
|
|
70
|
+
/** Bot 名称 */
|
|
71
|
+
$bot: string;
|
|
72
|
+
/** 通知类型 */
|
|
73
|
+
$type: NoticeType;
|
|
74
|
+
/** 通知子类型(如 leave/kick、set/unset) */
|
|
75
|
+
$subType?: string;
|
|
76
|
+
/** 通知发生的频道/群/会话 */
|
|
77
|
+
$channel: NoticeChannel;
|
|
78
|
+
/** 操作者信息(如管理员) */
|
|
79
|
+
$operator?: MessageSender;
|
|
80
|
+
/** 被操作目标信息(如被踢的成员) */
|
|
81
|
+
$target?: MessageSender;
|
|
82
|
+
/** 通知时间戳 */
|
|
83
|
+
$timestamp: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 完整通知类型,支持平台原始数据扩展
|
|
88
|
+
*/
|
|
89
|
+
export type Notice<T extends object = {}> = NoticeBase & T;
|
|
90
|
+
|
|
91
|
+
export namespace Notice {
|
|
92
|
+
/**
|
|
93
|
+
* 工具方法:合并自定义字段与基础通知结构
|
|
94
|
+
*/
|
|
95
|
+
export function from<T extends object>(input: T, format: NoticeBase): Notice<T> {
|
|
96
|
+
return Object.assign(input, format);
|
|
97
|
+
}
|
|
98
|
+
}
|
package/src/plugin.ts
CHANGED
|
@@ -18,6 +18,8 @@ import { MessageMiddleware, RegisteredAdapter, MaybePromise, ArrayItem, SendOpti
|
|
|
18
18
|
import type { ConfigFeature } from "./built/config.js";
|
|
19
19
|
import type { PermissionFeature } from "./built/permission.js";
|
|
20
20
|
import { Adapter, Adapters } from "./adapter.js";
|
|
21
|
+
import { Notice } from "./notice.js";
|
|
22
|
+
import { Request } from "./request.js";
|
|
21
23
|
import { Feature, FeatureJSON } from "./feature.js";
|
|
22
24
|
import { createHash } from "crypto";
|
|
23
25
|
const contextsKey = Symbol("contexts");
|
|
@@ -1024,6 +1026,12 @@ export namespace Plugin {
|
|
|
1024
1026
|
'before.sendMessage': [SendOptions];
|
|
1025
1027
|
"context.mounted": [keyof Plugin.Contexts];
|
|
1026
1028
|
"context.dispose": [keyof Plugin.Contexts];
|
|
1029
|
+
// Notice 事件
|
|
1030
|
+
'notice.receive': [Notice];
|
|
1031
|
+
[key: `notice.${string}`]: [Notice];
|
|
1032
|
+
// Request 事件
|
|
1033
|
+
'request.receive': [Request];
|
|
1034
|
+
[key: `request.${string}`]: [Request];
|
|
1027
1035
|
}
|
|
1028
1036
|
|
|
1029
1037
|
/**
|
package/src/request.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Adapters } from './adapter.js';
|
|
2
|
+
import type { MessageSender, MaybePromise } from './types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 请求类型枚举
|
|
6
|
+
*
|
|
7
|
+
* 常见 IM 请求事件分类:
|
|
8
|
+
* - friend_add: 好友添加请求
|
|
9
|
+
* - group_add: 主动申请入群
|
|
10
|
+
* - group_invite: 邀请入群请求
|
|
11
|
+
*
|
|
12
|
+
* 适配器可自行扩展更多子类型
|
|
13
|
+
*/
|
|
14
|
+
export type RequestType =
|
|
15
|
+
| 'friend_add'
|
|
16
|
+
| 'group_add'
|
|
17
|
+
| 'group_invite'
|
|
18
|
+
| (string & {}); // 允许适配器扩展自定义类型
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 请求频道信息
|
|
22
|
+
*/
|
|
23
|
+
export interface RequestChannel {
|
|
24
|
+
id: string;
|
|
25
|
+
type: 'group' | 'private' | 'channel';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 请求基础结构
|
|
30
|
+
*
|
|
31
|
+
* 与 MessageBase / NoticeBase 同构设计。
|
|
32
|
+
* 核心区别:Request 提供 `$approve()` 和 `$reject()` 方法,用于快速处理请求。
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // 适配器中格式化请求
|
|
37
|
+
* const request = Request.from(rawEvent, {
|
|
38
|
+
* $id: rawEvent.flag,
|
|
39
|
+
* $adapter: 'icqq',
|
|
40
|
+
* $bot: botName,
|
|
41
|
+
* $type: 'group_invite',
|
|
42
|
+
* $channel: { id: groupId, type: 'group' },
|
|
43
|
+
* $sender: { id: userId, name: '邀请者' },
|
|
44
|
+
* $comment: '请求加群消息',
|
|
45
|
+
* $timestamp: Date.now(),
|
|
46
|
+
* $approve: async (remark?) => { await api.approve(flag, remark); },
|
|
47
|
+
* $reject: async (reason?) => { await api.reject(flag, reason); },
|
|
48
|
+
* });
|
|
49
|
+
* this.adapter.emit('request.receive', request);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export interface RequestBase {
|
|
53
|
+
/** 请求唯一 ID / flag(平台提供的请求标识,用于后续处理) */
|
|
54
|
+
$id: string;
|
|
55
|
+
/** 适配器名称 */
|
|
56
|
+
$adapter: keyof Adapters;
|
|
57
|
+
/** Bot 名称 */
|
|
58
|
+
$bot: string;
|
|
59
|
+
/** 请求类型 */
|
|
60
|
+
$type: RequestType;
|
|
61
|
+
/** 请求子类型 */
|
|
62
|
+
$subType?: string;
|
|
63
|
+
/** 请求发生的频道/群/会话 */
|
|
64
|
+
$channel: RequestChannel;
|
|
65
|
+
/** 请求发送者 */
|
|
66
|
+
$sender: MessageSender;
|
|
67
|
+
/** 请求附言/验证消息 */
|
|
68
|
+
$comment?: string;
|
|
69
|
+
/** 请求时间戳 */
|
|
70
|
+
$timestamp: number;
|
|
71
|
+
/**
|
|
72
|
+
* 同意请求
|
|
73
|
+
* @param remark 备注信息(如好友备注)
|
|
74
|
+
*/
|
|
75
|
+
$approve(remark?: string): MaybePromise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* 拒绝请求
|
|
78
|
+
* @param reason 拒绝原因
|
|
79
|
+
*/
|
|
80
|
+
$reject(reason?: string): MaybePromise<void>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 完整请求类型,支持平台原始数据扩展
|
|
85
|
+
*/
|
|
86
|
+
export type Request<T extends object = {}> = RequestBase & T;
|
|
87
|
+
|
|
88
|
+
export namespace Request {
|
|
89
|
+
/**
|
|
90
|
+
* 工具方法:合并自定义字段与基础请求结构
|
|
91
|
+
*/
|
|
92
|
+
export function from<T extends object>(input: T, format: RequestBase): Request<T> {
|
|
93
|
+
return Object.assign(input, format);
|
|
94
|
+
}
|
|
95
|
+
}
|