@zhin.js/adapter-kook 7.0.14 → 8.0.1
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 +36 -0
- package/README.md +11 -2
- package/adapters/kook.js +1 -7
- package/adapters/kook.ts +1 -7
- package/agent/tools/blacklist.ts +6 -8
- package/agent/tools/create_role.ts +5 -7
- package/agent/tools/delete_role.ts +5 -7
- package/agent/tools/grant_role.ts +5 -7
- package/agent/tools/list_roles.ts +5 -7
- package/agent/tools/revoke_role.ts +5 -7
- package/lib/client.d.ts +11 -0
- package/lib/client.js +2 -0
- package/lib/endpoint.d.ts +11 -42
- package/lib/endpoint.js +47 -59
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/kook-endpoint-commands.d.ts +1 -1
- package/lib/protocol.d.ts +1 -1
- package/lib/protocol.js +1 -1
- package/lib/side-event-dispatch.d.ts +2 -2
- package/lib/side-event-dispatch.js +2 -4
- package/lib/webhook.d.ts +2 -3
- package/lib/webhook.js +2 -11
- package/package.json +15 -14
- package/src/client.ts +15 -0
- package/src/endpoint.ts +61 -84
- package/src/index.ts +1 -7
- package/src/protocol.ts +1 -1
- package/src/side-event-dispatch.ts +3 -4
- package/src/webhook.ts +2 -10
- package/lib/kook-agent-deps.d.ts +0 -29
- package/lib/kook-agent-deps.js +0 -30
- package/src/kook-agent-deps.ts +0 -55
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @zhin.js/adapter-kook
|
|
2
2
|
|
|
3
|
+
## 8.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1fc78bc: Unify native platform Client access behind the literal `adapter` discriminant. Handlers infer both native events and Clients, while command, inbound/outbound middleware, and both Agent tool authoring surfaces expose the exact operation-scoped Client through a lazy `$client` getter. Definitions without `adapter` keep `$client` typed as `unknown`, and runtime dispatch rejects adapter mismatches before resolving the Client. Bundled platform tools now use this single path instead of model-provided endpoint ids and adapter-specific dependency wrappers. Every adapter registers one Client/EventMap contract, and protocol adapters including NapCat, Milky, OneBot and Satori now produce transport-independent Client objects rather than letting Endpoint instances impersonate Clients.
|
|
8
|
+
- Updated dependencies [e9c6a73]
|
|
9
|
+
- Updated dependencies [4e8117c]
|
|
10
|
+
- Updated dependencies [902fa35]
|
|
11
|
+
- Updated dependencies [54bfd6b]
|
|
12
|
+
- Updated dependencies [12025ee]
|
|
13
|
+
- Updated dependencies [09b14d6]
|
|
14
|
+
- Updated dependencies [1fc78bc]
|
|
15
|
+
- @zhin.js/agent@1.1.16
|
|
16
|
+
- @zhin.js/adapter@1.2.1
|
|
17
|
+
- @zhin.js/core@1.5.14
|
|
18
|
+
- @zhin.js/host-http@1.0.13
|
|
19
|
+
- @zhin.js/command@1.0.16
|
|
20
|
+
- @zhin.js/logger@1.0.77
|
|
21
|
+
- zhin.js@6.0.14
|
|
22
|
+
- @zhin.js/feature-kit@1.0.13
|
|
23
|
+
- @zhin.js/permission@1.0.4
|
|
24
|
+
|
|
25
|
+
## 8.0.0
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- f2c532f: Expose exact per-Endpoint message operations through one validated Adapter capability model, route Core control calls through declared active capabilities, and connect existing recall, edit, reaction, and typing implementations across platform adapters.
|
|
30
|
+
- Updated dependencies [b10d058]
|
|
31
|
+
- Updated dependencies [f2c532f]
|
|
32
|
+
- Updated dependencies [3dbf990]
|
|
33
|
+
- @zhin.js/host-http@1.0.12
|
|
34
|
+
- @zhin.js/adapter@1.2.0
|
|
35
|
+
- @zhin.js/core@1.5.13
|
|
36
|
+
- @zhin.js/agent@1.1.15
|
|
37
|
+
- zhin.js@6.0.13
|
|
38
|
+
|
|
3
39
|
## 7.0.14
|
|
4
40
|
|
|
5
41
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ pnpm add @zhin.js/adapter-kook
|
|
|
20
20
|
## Plugin Runtime
|
|
21
21
|
|
|
22
22
|
- `@zhin.js/adapter` — 约定式 `adapters/kook.ts`(`defineAdapter`)
|
|
23
|
-
- `@zhin.js/core` — `
|
|
23
|
+
- `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
|
|
24
24
|
- `@zhin.js/host-http` — Webhook 模式 POST 路由(WebSocket 不需要)
|
|
25
25
|
- `zhin.js` — `plugin.ts`(`definePlugin`)
|
|
26
26
|
- 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
|
|
@@ -97,7 +97,16 @@ platform permit checker 由 `plugin.ts` 的 generation 生命周期注册;Capa
|
|
|
97
97
|
|
|
98
98
|
## 迁移后出站能力变化
|
|
99
99
|
|
|
100
|
-
迁移到 Plugin Runtime 后,出站统一经 `
|
|
100
|
+
迁移到 Plugin Runtime 后,出站统一经 `outboundMessageToken` 渲染并由 endpoint 编码为 KMarkdown(`sendChannelMsg` / `sendPrivateMsg`)。canonical `markdown` 保留格式;图片、视频、音频和文件仅有远程 URL 时可表示为 KMarkdown 链接。卡片消息与附件上传仍未接入统一出站通道。
|
|
101
|
+
|
|
102
|
+
## 故障排查
|
|
103
|
+
|
|
104
|
+
| 现象 | 排查 |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| WebSocket 无法上线 | 检查 Bot Token、网络与机器人能力开关 |
|
|
107
|
+
| Webhook challenge 失败 | 检查公网路径、`verify_token` 与 HTTP Host |
|
|
108
|
+
| 频道消息未触发 | 检查应用订阅、频道权限与机器人是否已加入服务器 |
|
|
109
|
+
| 附件表现为链接 | 当前统一出站不上传附件;使用远程 URL 或按能力降级 |
|
|
101
110
|
|
|
102
111
|
## 许可证
|
|
103
112
|
|
package/adapters/kook.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* Implementation lives under `src/` (endpoint / webhook / ws / protocol).
|
|
5
5
|
*/
|
|
6
6
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
7
|
-
import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
|
|
8
7
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
9
8
|
import { KookWebhookEndpoint, KookWebsocketEndpoint, } from "../lib/endpoint.js";
|
|
10
9
|
import { resolveKookConfig, } from "../lib/protocol.js";
|
|
@@ -12,6 +11,7 @@ import { kookRuntimeStateToken } from "../lib/kook-runtime-state.js";
|
|
|
12
11
|
export { KookWebhookEndpoint, KookWebsocketEndpoint, } from "../lib/endpoint.js";
|
|
13
12
|
export default defineAdapter({
|
|
14
13
|
capabilities: ['inbound', 'outbound'],
|
|
14
|
+
operations: ['recall'],
|
|
15
15
|
// KOOK 图片消息消费远程 URL;KMarkdown 由 endpoint codec 原生消费;
|
|
16
16
|
// 无按钮交互面,交互段降级纯文本。
|
|
17
17
|
segments: {
|
|
@@ -21,8 +21,6 @@ export default defineAdapter({
|
|
|
21
21
|
},
|
|
22
22
|
create(context) {
|
|
23
23
|
const config = resolveKookConfig(context.config);
|
|
24
|
-
const gateway = context.use(messageGatewayToken);
|
|
25
|
-
const sideEvents = context.use(sideEventGatewayToken);
|
|
26
24
|
// 注册到插件运行时状态(kook.endpoint list 的"运行中"数据源)
|
|
27
25
|
context.use(kookRuntimeStateToken).endpoints.set(config.id, {
|
|
28
26
|
id: config.id,
|
|
@@ -31,16 +29,12 @@ export default defineAdapter({
|
|
|
31
29
|
if (config.connection === 'webhook') {
|
|
32
30
|
return new KookWebhookEndpoint({
|
|
33
31
|
id: context.id,
|
|
34
|
-
gateway,
|
|
35
|
-
sideEvents,
|
|
36
32
|
http: context.use(httpHostToken),
|
|
37
33
|
config,
|
|
38
34
|
});
|
|
39
35
|
}
|
|
40
36
|
return new KookWebsocketEndpoint({
|
|
41
37
|
id: context.id,
|
|
42
|
-
gateway,
|
|
43
|
-
sideEvents,
|
|
44
38
|
config,
|
|
45
39
|
});
|
|
46
40
|
},
|
package/adapters/kook.ts
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Implementation lives under `src/` (endpoint / webhook / ws / protocol).
|
|
4
4
|
*/
|
|
5
5
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
6
|
-
import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
|
|
7
6
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
8
7
|
import {
|
|
9
8
|
KookWebhookEndpoint,
|
|
@@ -27,6 +26,7 @@ export type { CreateKookClient, KookClientTransport } from '../src/ws.js';
|
|
|
27
26
|
|
|
28
27
|
export default defineAdapter<KookAdapterConfig>({
|
|
29
28
|
capabilities: ['inbound', 'outbound'],
|
|
29
|
+
operations: ['recall'],
|
|
30
30
|
// KOOK 图片消息消费远程 URL;KMarkdown 由 endpoint codec 原生消费;
|
|
31
31
|
// 无按钮交互面,交互段降级纯文本。
|
|
32
32
|
segments: {
|
|
@@ -36,8 +36,6 @@ export default defineAdapter<KookAdapterConfig>({
|
|
|
36
36
|
},
|
|
37
37
|
create(context) {
|
|
38
38
|
const config = resolveKookConfig(context.config);
|
|
39
|
-
const gateway = context.use(messageGatewayToken);
|
|
40
|
-
const sideEvents = context.use(sideEventGatewayToken);
|
|
41
39
|
// 注册到插件运行时状态(kook.endpoint list 的"运行中"数据源)
|
|
42
40
|
context.use(kookRuntimeStateToken).endpoints.set(config.id, {
|
|
43
41
|
id: config.id,
|
|
@@ -46,16 +44,12 @@ export default defineAdapter<KookAdapterConfig>({
|
|
|
46
44
|
if (config.connection === 'webhook') {
|
|
47
45
|
return new KookWebhookEndpoint({
|
|
48
46
|
id: context.id,
|
|
49
|
-
gateway,
|
|
50
|
-
sideEvents,
|
|
51
47
|
http: context.use(httpHostToken),
|
|
52
48
|
config,
|
|
53
49
|
});
|
|
54
50
|
}
|
|
55
51
|
return new KookWebsocketEndpoint({
|
|
56
52
|
id: context.id,
|
|
57
|
-
gateway,
|
|
58
|
-
sideEvents,
|
|
59
53
|
config,
|
|
60
54
|
});
|
|
61
55
|
},
|
package/agent/tools/blacklist.ts
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getKookAgentDeps } from '../../src/kook-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string; action: 'add' | 'remove'; user_id: string; remark?: string }>({
|
|
7
6
|
description: 'KOOK 服务器黑名单管理:添加/移除',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('服务器 ID'),
|
|
11
9
|
action: z.enum(['add', 'remove']).describe('add|remove'),
|
|
12
10
|
user_id: z.string().describe('用户 ID'),
|
|
13
11
|
remark: z.string().optional().describe('备注(add 可选)'),
|
|
14
12
|
}),
|
|
15
|
-
|
|
13
|
+
adapter: 'kook',
|
|
16
14
|
tags: ['kook'],
|
|
17
15
|
permissions: [platformPermit('guild_admin')],
|
|
18
|
-
async execute({
|
|
19
|
-
const
|
|
16
|
+
async execute({ guild_id, action, user_id, remark }: { guild_id: string; action: 'add' | 'remove'; user_id: string; remark?: string }, context) {
|
|
17
|
+
const member = context.$client.pickGuildMember(guild_id, user_id);
|
|
20
18
|
switch (action) {
|
|
21
19
|
case 'add': {
|
|
22
|
-
const success = await
|
|
20
|
+
const success = await member.addToBlackList(remark);
|
|
23
21
|
return { success, message: success ? `已将 ${user_id} 加入黑名单` : '操作失败' };
|
|
24
22
|
}
|
|
25
23
|
case 'remove': {
|
|
26
|
-
const success = await
|
|
24
|
+
const success = await member.removeFromBlackList();
|
|
27
25
|
return { success, message: success ? `已将 ${user_id} 从黑名单移除` : '操作失败' };
|
|
28
26
|
}
|
|
29
27
|
default:
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getKookAgentDeps } from '../../src/kook-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string; name: string }>({
|
|
7
6
|
description: '在 KOOK 服务器中创建新角色',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('服务器 ID'),
|
|
11
9
|
name: z.string().describe('角色名称'),
|
|
12
10
|
}),
|
|
13
|
-
|
|
11
|
+
adapter: 'kook',
|
|
14
12
|
tags: ['kook'],
|
|
15
13
|
permissions: [platformPermit('guild_owner')],
|
|
16
|
-
async execute({
|
|
17
|
-
const
|
|
18
|
-
const role = await
|
|
14
|
+
async execute({ guild_id, name }: { guild_id: string; name: string }, context) {
|
|
15
|
+
const client = context.$client;
|
|
16
|
+
const role = await client.pickGuild(guild_id).createRole(name);
|
|
19
17
|
return {
|
|
20
18
|
success: true,
|
|
21
19
|
message: `已创建角色 "${name}"`,
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getKookAgentDeps } from '../../src/kook-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string; role_id: string }>({
|
|
7
6
|
description: '删除 KOOK 服务器中的角色',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('服务器 ID'),
|
|
11
9
|
role_id: z.string().describe('角色 ID'),
|
|
12
10
|
}),
|
|
13
|
-
|
|
11
|
+
adapter: 'kook',
|
|
14
12
|
tags: ['kook'],
|
|
15
13
|
permissions: [platformPermit('guild_owner')],
|
|
16
|
-
async execute({
|
|
17
|
-
const
|
|
18
|
-
const success = await
|
|
14
|
+
async execute({ guild_id, role_id }: { guild_id: string; role_id: string }, context) {
|
|
15
|
+
const client = context.$client;
|
|
16
|
+
const success = await client.pickGuild(guild_id).deleteRole(role_id);
|
|
19
17
|
return { success, message: success ? `已删除角色 ${role_id}` : '删除角色失败' };
|
|
20
18
|
},
|
|
21
19
|
});
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getKookAgentDeps } from '../../src/kook-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string; user_id: string; role_id: string }>({
|
|
7
6
|
description: '给用户授予 KOOK 服务器角色',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('服务器 ID'),
|
|
11
9
|
user_id: z.string().describe('用户 ID'),
|
|
12
10
|
role_id: z.string().describe('角色 ID'),
|
|
13
11
|
}),
|
|
14
|
-
|
|
12
|
+
adapter: 'kook',
|
|
15
13
|
tags: ['kook'],
|
|
16
14
|
permissions: [platformPermit('manage_roles')],
|
|
17
|
-
async execute({
|
|
18
|
-
const
|
|
19
|
-
const success = await
|
|
15
|
+
async execute({ guild_id, user_id, role_id }: { guild_id: string; user_id: string; role_id: string }, context) {
|
|
16
|
+
const client = context.$client;
|
|
17
|
+
const success = await client.pickGuildMember(guild_id, user_id).grant(role_id);
|
|
20
18
|
return { success, message: success ? `已授予用户 ${user_id} 角色 ${role_id}` : '授予角色失败' };
|
|
21
19
|
},
|
|
22
20
|
});
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { getKookAgentDeps } from '../../src/kook-agent-deps.js';
|
|
4
3
|
|
|
5
|
-
export default defineAgentTool<{
|
|
4
|
+
export default defineAgentTool<{ guild_id: string }>({
|
|
6
5
|
description: '获取 KOOK 服务器的角色列表',
|
|
7
6
|
inputSchema: z.object({
|
|
8
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
9
7
|
guild_id: z.string().describe('服务器 ID'),
|
|
10
8
|
}),
|
|
11
|
-
|
|
9
|
+
adapter: 'kook',
|
|
12
10
|
tags: ['kook'],
|
|
13
|
-
async execute({
|
|
14
|
-
const
|
|
15
|
-
const roles = await
|
|
11
|
+
async execute({ guild_id }: { guild_id: string }, context) {
|
|
12
|
+
const client = context.$client;
|
|
13
|
+
const roles = await client.pickGuild(guild_id).getRoleList();
|
|
16
14
|
return {
|
|
17
15
|
roles: roles.map((r) => ({
|
|
18
16
|
id: String(r.role_id),
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { platformPermit } from '../../src/platform-permit.js';
|
|
4
|
-
import { getKookAgentDeps } from '../../src/kook-agent-deps.js';
|
|
5
4
|
|
|
6
|
-
export default defineAgentTool<{
|
|
5
|
+
export default defineAgentTool<{ guild_id: string; user_id: string; role_id: string }>({
|
|
7
6
|
description: '撤销用户的 KOOK 服务器角色',
|
|
8
7
|
inputSchema: z.object({
|
|
9
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
10
8
|
guild_id: z.string().describe('服务器 ID'),
|
|
11
9
|
user_id: z.string().describe('用户 ID'),
|
|
12
10
|
role_id: z.string().describe('角色 ID'),
|
|
13
11
|
}),
|
|
14
|
-
|
|
12
|
+
adapter: 'kook',
|
|
15
13
|
tags: ['kook'],
|
|
16
14
|
permissions: [platformPermit('manage_roles')],
|
|
17
|
-
async execute({
|
|
18
|
-
const
|
|
19
|
-
const success = await
|
|
15
|
+
async execute({ guild_id, user_id, role_id }: { guild_id: string; user_id: string; role_id: string }, context) {
|
|
16
|
+
const client = context.$client;
|
|
17
|
+
const success = await client.pickGuildMember(guild_id, user_id).revoke(role_id);
|
|
20
18
|
return { success, message: success ? `已撤销用户 ${user_id} 的角色 ${role_id}` : '撤销角色失败' };
|
|
21
19
|
},
|
|
22
20
|
});
|
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { KookClientTransport } from './ws.js';
|
|
2
|
+
export type KookClientEventMap = Record<string, unknown>;
|
|
3
|
+
declare module '@zhin.js/feature-kit' {
|
|
4
|
+
interface AdapterClientRegistry {
|
|
5
|
+
readonly kook: {
|
|
6
|
+
readonly client: KookClientTransport;
|
|
7
|
+
readonly events: KookClientEventMap;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export declare const kookClient: import("@zhin.js/adapter").EndpointClientToken<KookClientTransport, KookClientEventMap>;
|
package/lib/client.js
ADDED
package/lib/endpoint.d.ts
CHANGED
|
@@ -1,57 +1,41 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
2
|
+
import { type EndpointControl, type EndpointManagement, type EndpointSendRequest } from 'zhin.js/adapter';
|
|
3
3
|
import type { HttpHost } from '@zhin.js/host-http';
|
|
4
4
|
import type { CapabilityId } from 'zhin.js';
|
|
5
|
-
import { type KookInboundMessage, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig } from './protocol.js';
|
|
5
|
+
import { type KookInboundMessage, type KookWebhookEventData, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig } from './protocol.js';
|
|
6
6
|
import { type CreateKookClient, type KookClientTransport } from './ws.js';
|
|
7
7
|
export interface KookEndpointOptions {
|
|
8
8
|
readonly id: CapabilityId;
|
|
9
|
-
readonly gateway: MessageGateway;
|
|
10
|
-
readonly sideEvents?: SideEventGateway;
|
|
11
9
|
readonly config: ResolvedKookWebsocketConfig;
|
|
12
10
|
readonly createClient?: CreateKookClient;
|
|
13
11
|
}
|
|
14
|
-
export declare class KookWebsocketEndpoint
|
|
12
|
+
export declare class KookWebsocketEndpoint extends Endpoint<KookClientTransport> {
|
|
15
13
|
#private;
|
|
16
14
|
readonly management: EndpointManagement;
|
|
15
|
+
readonly control: EndpointControl;
|
|
17
16
|
constructor(options: KookEndpointOptions);
|
|
17
|
+
get client(): KookClientTransport;
|
|
18
18
|
start(): Promise<void>;
|
|
19
19
|
open(): void;
|
|
20
20
|
close(): void;
|
|
21
21
|
stop(): Promise<void>;
|
|
22
22
|
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
23
|
-
/** Test / internal: admit a message when open. */
|
|
23
|
+
/** Test / internal: admit a normalized message when open. */
|
|
24
24
|
admit(msg: KookInboundMessage): void;
|
|
25
25
|
recallMessage(messageId: string): Promise<void>;
|
|
26
|
-
getRoleList(guildId: string): Promise<{
|
|
27
|
-
role_id: string | number;
|
|
28
|
-
name: string;
|
|
29
|
-
color?: number;
|
|
30
|
-
position?: number;
|
|
31
|
-
permissions?: unknown;
|
|
32
|
-
}[]>;
|
|
33
|
-
createRole(guildId: string, name: string): Promise<{
|
|
34
|
-
role_id: string | number;
|
|
35
|
-
name: string;
|
|
36
|
-
}>;
|
|
37
|
-
deleteRole(guildId: string, roleId: string): Promise<boolean>;
|
|
38
|
-
grantRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
39
|
-
revokeRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
40
|
-
addToBlacklist(guildId: string, userId: string, remark?: string): Promise<boolean>;
|
|
41
|
-
removeFromBlacklist(guildId: string, userId: string): Promise<boolean>;
|
|
42
26
|
}
|
|
43
27
|
export interface KookWebhookEndpointOptions {
|
|
44
28
|
readonly id: CapabilityId;
|
|
45
|
-
readonly gateway: MessageGateway;
|
|
46
|
-
readonly sideEvents?: SideEventGateway;
|
|
47
29
|
readonly http: HttpHost;
|
|
48
30
|
readonly config: ResolvedKookWebhookConfig;
|
|
49
31
|
readonly createClient?: CreateKookClient;
|
|
50
32
|
}
|
|
51
|
-
export declare class KookWebhookEndpoint
|
|
33
|
+
export declare class KookWebhookEndpoint extends Endpoint<KookClientTransport> {
|
|
52
34
|
#private;
|
|
53
35
|
readonly management: EndpointManagement;
|
|
36
|
+
readonly control: EndpointControl;
|
|
54
37
|
constructor(options: KookWebhookEndpointOptions);
|
|
38
|
+
get client(): KookClientTransport;
|
|
55
39
|
/** Used by webhook handler. */
|
|
56
40
|
get isOpen(): boolean;
|
|
57
41
|
get config(): ResolvedKookWebhookConfig;
|
|
@@ -61,26 +45,11 @@ export declare class KookWebhookEndpoint implements EndpointInstance {
|
|
|
61
45
|
close(): void;
|
|
62
46
|
stop(): Promise<void>;
|
|
63
47
|
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
48
|
+
admitEvent(event: KookWebhookEventData): void;
|
|
64
49
|
/** Test / internal: admit a message when open. */
|
|
65
50
|
admit(msg: KookInboundMessage): void;
|
|
66
51
|
recallMessage(messageId: string): Promise<void>;
|
|
67
52
|
checkAndRememberSn(sn: number): boolean;
|
|
68
|
-
getRoleList(guildId: string): Promise<{
|
|
69
|
-
role_id: string | number;
|
|
70
|
-
name: string;
|
|
71
|
-
color?: number;
|
|
72
|
-
position?: number;
|
|
73
|
-
permissions?: unknown;
|
|
74
|
-
}[]>;
|
|
75
|
-
createRole(guildId: string, name: string): Promise<{
|
|
76
|
-
role_id: string | number;
|
|
77
|
-
name: string;
|
|
78
|
-
}>;
|
|
79
|
-
deleteRole(guildId: string, roleId: string): Promise<boolean>;
|
|
80
|
-
grantRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
81
|
-
revokeRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
82
|
-
addToBlacklist(guildId: string, userId: string, remark?: string): Promise<boolean>;
|
|
83
|
-
removeFromBlacklist(guildId: string, userId: string): Promise<boolean>;
|
|
84
53
|
}
|
|
85
54
|
/**
|
|
86
55
|
* KOOK endpoint 的 EndpointManagement 语义端口(websocket / webhook 共用)。
|
package/lib/endpoint.js
CHANGED
|
@@ -1,29 +1,33 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
2
|
+
import { createRecallEndpointControl, } from 'zhin.js/adapter';
|
|
1
3
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
2
|
-
import {
|
|
3
|
-
import { formatInboundContent, formatOutboundKmarkdown, isKookBotMentioned, kookInboundConversation, senderDisplayName, } from './protocol.js';
|
|
4
|
+
import { formatInboundContent, formatOutboundKmarkdown, isKookBotMentioned, kookInboundConversation, normalizeKookWebhookEvent, senderDisplayName, } from './protocol.js';
|
|
4
5
|
import { registerKookWebhookRoutes } from './webhook.js';
|
|
5
6
|
import { defaultCreateClient, defaultCreateWebhookClient, normalizeKookMessage, } from './ws.js';
|
|
6
7
|
import { receiveKookSideEvent } from './side-event-dispatch.js';
|
|
7
|
-
export class KookWebsocketEndpoint {
|
|
8
|
+
export class KookWebsocketEndpoint extends Endpoint {
|
|
8
9
|
#logger;
|
|
9
10
|
#options;
|
|
10
11
|
#createClient;
|
|
11
12
|
#client = null;
|
|
12
13
|
#open = false;
|
|
13
14
|
#started = false;
|
|
14
|
-
#unregisterAgent;
|
|
15
15
|
management = createKookEndpointManagement(() => this.#requireClient());
|
|
16
|
+
control = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
16
17
|
constructor(options) {
|
|
18
|
+
super();
|
|
17
19
|
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
18
20
|
this.#options = options;
|
|
19
21
|
this.#createClient = options.createClient ?? defaultCreateClient;
|
|
20
22
|
}
|
|
23
|
+
get client() {
|
|
24
|
+
return this.#requireClient();
|
|
25
|
+
}
|
|
21
26
|
async start() {
|
|
22
27
|
if (this.#started)
|
|
23
28
|
return;
|
|
24
29
|
this.#started = true;
|
|
25
30
|
try {
|
|
26
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
27
31
|
this.#client = this.#createClient(this.#options.config);
|
|
28
32
|
this.#bindClient(this.#client);
|
|
29
33
|
await this.#client.connect();
|
|
@@ -48,8 +52,6 @@ export class KookWebsocketEndpoint {
|
|
|
48
52
|
}
|
|
49
53
|
async stop() {
|
|
50
54
|
this.#open = false;
|
|
51
|
-
this.#unregisterAgent?.();
|
|
52
|
-
this.#unregisterAgent = undefined;
|
|
53
55
|
if (this.#client) {
|
|
54
56
|
try {
|
|
55
57
|
this.#client.removeAllListeners();
|
|
@@ -78,7 +80,7 @@ export class KookWebsocketEndpoint {
|
|
|
78
80
|
}));
|
|
79
81
|
return messageId;
|
|
80
82
|
}
|
|
81
|
-
/** Test / internal: admit a message when open. */
|
|
83
|
+
/** Test / internal: admit a normalized message when open. */
|
|
82
84
|
admit(msg) {
|
|
83
85
|
if (!this.#open)
|
|
84
86
|
return;
|
|
@@ -86,7 +88,7 @@ export class KookWebsocketEndpoint {
|
|
|
86
88
|
return;
|
|
87
89
|
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
88
90
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
89
|
-
void this
|
|
91
|
+
void this.emit('message.receive', {
|
|
90
92
|
conversation,
|
|
91
93
|
message: { conversation, id: msg.id },
|
|
92
94
|
content: formatInboundContent(msg),
|
|
@@ -116,37 +118,26 @@ export class KookWebsocketEndpoint {
|
|
|
116
118
|
return;
|
|
117
119
|
await this.#requireClient().recallMsg?.(messageId);
|
|
118
120
|
}
|
|
119
|
-
// ── Agent tool surface ──────────────────────────────────────────────
|
|
120
|
-
async getRoleList(guildId) {
|
|
121
|
-
return this.#requireClient().pickGuild(guildId).getRoleList();
|
|
122
|
-
}
|
|
123
|
-
async createRole(guildId, name) {
|
|
124
|
-
return this.#requireClient().pickGuild(guildId).createRole(name);
|
|
125
|
-
}
|
|
126
|
-
async deleteRole(guildId, roleId) {
|
|
127
|
-
return this.#requireClient().pickGuild(guildId).deleteRole(roleId);
|
|
128
|
-
}
|
|
129
|
-
async grantRole(guildId, userId, roleId) {
|
|
130
|
-
return this.#requireClient().pickGuildMember(guildId, userId).grant(roleId);
|
|
131
|
-
}
|
|
132
|
-
async revokeRole(guildId, userId, roleId) {
|
|
133
|
-
return this.#requireClient().pickGuildMember(guildId, userId).revoke(roleId);
|
|
134
|
-
}
|
|
135
|
-
async addToBlacklist(guildId, userId, remark) {
|
|
136
|
-
return this.#requireClient().pickGuildMember(guildId, userId).addToBlackList(remark);
|
|
137
|
-
}
|
|
138
|
-
async removeFromBlacklist(guildId, userId) {
|
|
139
|
-
return this.#requireClient().pickGuildMember(guildId, userId).removeFromBlackList();
|
|
140
|
-
}
|
|
141
121
|
#bindClient(client) {
|
|
142
122
|
client.on('message', (raw) => {
|
|
123
|
+
this.#emitPlatformEvent('message', raw);
|
|
143
124
|
const msg = normalizeKookMessage(raw);
|
|
144
125
|
if (msg)
|
|
145
126
|
this.admit(msg);
|
|
146
127
|
});
|
|
147
128
|
const receiver = client.receiver;
|
|
148
129
|
receiver?.on('event', (raw) => {
|
|
149
|
-
|
|
130
|
+
this.#emitPlatformEvent('event', raw);
|
|
131
|
+
receiveKookSideEvent((name, payload) => this.emit(name, payload), this.#options.config.id, raw, this.#logger);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
#emitPlatformEvent(name, event) {
|
|
135
|
+
void this.emitPlatform(name, event).catch((error) => {
|
|
136
|
+
this.#logger.warn(formatCompact({
|
|
137
|
+
op: 'kook_platform_event_failed',
|
|
138
|
+
event: name,
|
|
139
|
+
error: error instanceof Error ? error.message : String(error),
|
|
140
|
+
}));
|
|
150
141
|
});
|
|
151
142
|
}
|
|
152
143
|
#requireClient() {
|
|
@@ -155,7 +146,7 @@ export class KookWebsocketEndpoint {
|
|
|
155
146
|
return this.#client;
|
|
156
147
|
}
|
|
157
148
|
}
|
|
158
|
-
export class KookWebhookEndpoint {
|
|
149
|
+
export class KookWebhookEndpoint extends Endpoint {
|
|
159
150
|
#logger;
|
|
160
151
|
#options;
|
|
161
152
|
#createClient;
|
|
@@ -164,13 +155,17 @@ export class KookWebhookEndpoint {
|
|
|
164
155
|
#processedSn = new Set();
|
|
165
156
|
#open = false;
|
|
166
157
|
#started = false;
|
|
167
|
-
#unregisterAgent;
|
|
168
158
|
management = createKookEndpointManagement(() => this.#requireClient());
|
|
159
|
+
control = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
169
160
|
constructor(options) {
|
|
161
|
+
super();
|
|
170
162
|
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
171
163
|
this.#options = options;
|
|
172
164
|
this.#createClient = options.createClient ?? defaultCreateWebhookClient;
|
|
173
165
|
}
|
|
166
|
+
get client() {
|
|
167
|
+
return this.#requireClient();
|
|
168
|
+
}
|
|
174
169
|
/** Used by webhook handler. */
|
|
175
170
|
get isOpen() {
|
|
176
171
|
return this.#open;
|
|
@@ -186,7 +181,6 @@ export class KookWebhookEndpoint {
|
|
|
186
181
|
return;
|
|
187
182
|
this.#started = true;
|
|
188
183
|
try {
|
|
189
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
190
184
|
this.#client = this.#createClient(this.#options.config);
|
|
191
185
|
await this.#client.init();
|
|
192
186
|
this.#routeReleases.push(...registerKookWebhookRoutes(this.#options.http, this));
|
|
@@ -214,8 +208,6 @@ export class KookWebhookEndpoint {
|
|
|
214
208
|
this.#open = false;
|
|
215
209
|
for (const release of this.#routeReleases.splice(0))
|
|
216
210
|
release();
|
|
217
|
-
this.#unregisterAgent?.();
|
|
218
|
-
this.#unregisterAgent = undefined;
|
|
219
211
|
this.#processedSn.clear();
|
|
220
212
|
if (this.#client) {
|
|
221
213
|
try {
|
|
@@ -245,6 +237,23 @@ export class KookWebhookEndpoint {
|
|
|
245
237
|
}));
|
|
246
238
|
return messageId;
|
|
247
239
|
}
|
|
240
|
+
admitEvent(event) {
|
|
241
|
+
void this.emitPlatform(String(event.type ?? 'event'), event).catch((error) => {
|
|
242
|
+
this.#logger.warn(formatCompact({
|
|
243
|
+
op: 'kook_platform_event_failed',
|
|
244
|
+
event: String(event.type ?? 'event'),
|
|
245
|
+
error: error instanceof Error ? error.message : String(error),
|
|
246
|
+
}));
|
|
247
|
+
});
|
|
248
|
+
if (receiveKookSideEvent((name, payload) => this.emit(name, payload), this.#options.config.id, event, this.#logger))
|
|
249
|
+
return;
|
|
250
|
+
const message = normalizeKookWebhookEvent(event, {
|
|
251
|
+
ignore: this.#options.config.ignore,
|
|
252
|
+
selfId: this.selfId,
|
|
253
|
+
});
|
|
254
|
+
if (message)
|
|
255
|
+
this.admit(message);
|
|
256
|
+
}
|
|
248
257
|
/** Test / internal: admit a message when open. */
|
|
249
258
|
admit(msg) {
|
|
250
259
|
if (!this.#open)
|
|
@@ -253,7 +262,7 @@ export class KookWebhookEndpoint {
|
|
|
253
262
|
return;
|
|
254
263
|
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
255
264
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
256
|
-
void this
|
|
265
|
+
void this.emit('message.receive', {
|
|
257
266
|
conversation,
|
|
258
267
|
message: { conversation, id: msg.id },
|
|
259
268
|
content: formatInboundContent(msg),
|
|
@@ -294,27 +303,6 @@ export class KookWebhookEndpoint {
|
|
|
294
303
|
}
|
|
295
304
|
return true;
|
|
296
305
|
}
|
|
297
|
-
async getRoleList(guildId) {
|
|
298
|
-
return this.#requireClient().pickGuild(guildId).getRoleList();
|
|
299
|
-
}
|
|
300
|
-
async createRole(guildId, name) {
|
|
301
|
-
return this.#requireClient().pickGuild(guildId).createRole(name);
|
|
302
|
-
}
|
|
303
|
-
async deleteRole(guildId, roleId) {
|
|
304
|
-
return this.#requireClient().pickGuild(guildId).deleteRole(roleId);
|
|
305
|
-
}
|
|
306
|
-
async grantRole(guildId, userId, roleId) {
|
|
307
|
-
return this.#requireClient().pickGuildMember(guildId, userId).grant(roleId);
|
|
308
|
-
}
|
|
309
|
-
async revokeRole(guildId, userId, roleId) {
|
|
310
|
-
return this.#requireClient().pickGuildMember(guildId, userId).revoke(roleId);
|
|
311
|
-
}
|
|
312
|
-
async addToBlacklist(guildId, userId, remark) {
|
|
313
|
-
return this.#requireClient().pickGuildMember(guildId, userId).addToBlackList(remark);
|
|
314
|
-
}
|
|
315
|
-
async removeFromBlacklist(guildId, userId) {
|
|
316
|
-
return this.#requireClient().pickGuildMember(guildId, userId).removeFromBlackList();
|
|
317
|
-
}
|
|
318
306
|
#requireClient() {
|
|
319
307
|
if (!this.#client)
|
|
320
308
|
throw new Error('KOOK client not initialized');
|