@zhin.js/adapter-kook 8.0.0 → 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 +22 -0
- package/README.md +11 -2
- package/adapters/kook.js +0 -7
- package/adapters/kook.ts +0 -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 +9 -42
- package/lib/endpoint.js +44 -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 +52 -79
- 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,27 @@
|
|
|
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
|
+
|
|
3
25
|
## 8.0.0
|
|
4
26
|
|
|
5
27
|
### 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";
|
|
@@ -22,8 +21,6 @@ export default defineAdapter({
|
|
|
22
21
|
},
|
|
23
22
|
create(context) {
|
|
24
23
|
const config = resolveKookConfig(context.config);
|
|
25
|
-
const gateway = context.use(messageGatewayToken);
|
|
26
|
-
const sideEvents = context.use(sideEventGatewayToken);
|
|
27
24
|
// 注册到插件运行时状态(kook.endpoint list 的"运行中"数据源)
|
|
28
25
|
context.use(kookRuntimeStateToken).endpoints.set(config.id, {
|
|
29
26
|
id: config.id,
|
|
@@ -32,16 +29,12 @@ export default defineAdapter({
|
|
|
32
29
|
if (config.connection === 'webhook') {
|
|
33
30
|
return new KookWebhookEndpoint({
|
|
34
31
|
id: context.id,
|
|
35
|
-
gateway,
|
|
36
|
-
sideEvents,
|
|
37
32
|
http: context.use(httpHostToken),
|
|
38
33
|
config,
|
|
39
34
|
});
|
|
40
35
|
}
|
|
41
36
|
return new KookWebsocketEndpoint({
|
|
42
37
|
id: context.id,
|
|
43
|
-
gateway,
|
|
44
|
-
sideEvents,
|
|
45
38
|
config,
|
|
46
39
|
});
|
|
47
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,
|
|
@@ -37,8 +36,6 @@ export default defineAdapter<KookAdapterConfig>({
|
|
|
37
36
|
},
|
|
38
37
|
create(context) {
|
|
39
38
|
const config = resolveKookConfig(context.config);
|
|
40
|
-
const gateway = context.use(messageGatewayToken);
|
|
41
|
-
const sideEvents = context.use(sideEventGatewayToken);
|
|
42
39
|
// 注册到插件运行时状态(kook.endpoint list 的"运行中"数据源)
|
|
43
40
|
context.use(kookRuntimeStateToken).endpoints.set(config.id, {
|
|
44
41
|
id: config.id,
|
|
@@ -47,16 +44,12 @@ export default defineAdapter<KookAdapterConfig>({
|
|
|
47
44
|
if (config.connection === 'webhook') {
|
|
48
45
|
return new KookWebhookEndpoint({
|
|
49
46
|
id: context.id,
|
|
50
|
-
gateway,
|
|
51
|
-
sideEvents,
|
|
52
47
|
http: context.use(httpHostToken),
|
|
53
48
|
config,
|
|
54
49
|
});
|
|
55
50
|
}
|
|
56
51
|
return new KookWebsocketEndpoint({
|
|
57
52
|
id: context.id,
|
|
58
|
-
gateway,
|
|
59
|
-
sideEvents,
|
|
60
53
|
config,
|
|
61
54
|
});
|
|
62
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,59 +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;
|
|
17
15
|
readonly control: EndpointControl;
|
|
18
16
|
constructor(options: KookEndpointOptions);
|
|
17
|
+
get client(): KookClientTransport;
|
|
19
18
|
start(): Promise<void>;
|
|
20
19
|
open(): void;
|
|
21
20
|
close(): void;
|
|
22
21
|
stop(): Promise<void>;
|
|
23
22
|
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
24
|
-
/** Test / internal: admit a message when open. */
|
|
23
|
+
/** Test / internal: admit a normalized message when open. */
|
|
25
24
|
admit(msg: KookInboundMessage): void;
|
|
26
25
|
recallMessage(messageId: string): Promise<void>;
|
|
27
|
-
getRoleList(guildId: string): Promise<{
|
|
28
|
-
role_id: string | number;
|
|
29
|
-
name: string;
|
|
30
|
-
color?: number;
|
|
31
|
-
position?: number;
|
|
32
|
-
permissions?: unknown;
|
|
33
|
-
}[]>;
|
|
34
|
-
createRole(guildId: string, name: string): Promise<{
|
|
35
|
-
role_id: string | number;
|
|
36
|
-
name: string;
|
|
37
|
-
}>;
|
|
38
|
-
deleteRole(guildId: string, roleId: string): Promise<boolean>;
|
|
39
|
-
grantRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
40
|
-
revokeRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
41
|
-
addToBlacklist(guildId: string, userId: string, remark?: string): Promise<boolean>;
|
|
42
|
-
removeFromBlacklist(guildId: string, userId: string): Promise<boolean>;
|
|
43
26
|
}
|
|
44
27
|
export interface KookWebhookEndpointOptions {
|
|
45
28
|
readonly id: CapabilityId;
|
|
46
|
-
readonly gateway: MessageGateway;
|
|
47
|
-
readonly sideEvents?: SideEventGateway;
|
|
48
29
|
readonly http: HttpHost;
|
|
49
30
|
readonly config: ResolvedKookWebhookConfig;
|
|
50
31
|
readonly createClient?: CreateKookClient;
|
|
51
32
|
}
|
|
52
|
-
export declare class KookWebhookEndpoint
|
|
33
|
+
export declare class KookWebhookEndpoint extends Endpoint<KookClientTransport> {
|
|
53
34
|
#private;
|
|
54
35
|
readonly management: EndpointManagement;
|
|
55
36
|
readonly control: EndpointControl;
|
|
56
37
|
constructor(options: KookWebhookEndpointOptions);
|
|
38
|
+
get client(): KookClientTransport;
|
|
57
39
|
/** Used by webhook handler. */
|
|
58
40
|
get isOpen(): boolean;
|
|
59
41
|
get config(): ResolvedKookWebhookConfig;
|
|
@@ -63,26 +45,11 @@ export declare class KookWebhookEndpoint implements EndpointInstance {
|
|
|
63
45
|
close(): void;
|
|
64
46
|
stop(): Promise<void>;
|
|
65
47
|
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
48
|
+
admitEvent(event: KookWebhookEventData): void;
|
|
66
49
|
/** Test / internal: admit a message when open. */
|
|
67
50
|
admit(msg: KookInboundMessage): void;
|
|
68
51
|
recallMessage(messageId: string): Promise<void>;
|
|
69
52
|
checkAndRememberSn(sn: number): boolean;
|
|
70
|
-
getRoleList(guildId: string): Promise<{
|
|
71
|
-
role_id: string | number;
|
|
72
|
-
name: string;
|
|
73
|
-
color?: number;
|
|
74
|
-
position?: number;
|
|
75
|
-
permissions?: unknown;
|
|
76
|
-
}[]>;
|
|
77
|
-
createRole(guildId: string, name: string): Promise<{
|
|
78
|
-
role_id: string | number;
|
|
79
|
-
name: string;
|
|
80
|
-
}>;
|
|
81
|
-
deleteRole(guildId: string, roleId: string): Promise<boolean>;
|
|
82
|
-
grantRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
83
|
-
revokeRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
84
|
-
addToBlacklist(guildId: string, userId: string, remark?: string): Promise<boolean>;
|
|
85
|
-
removeFromBlacklist(guildId: string, userId: string): Promise<boolean>;
|
|
86
53
|
}
|
|
87
54
|
/**
|
|
88
55
|
* KOOK endpoint 的 EndpointManagement 语义端口(websocket / webhook 共用)。
|
package/lib/endpoint.js
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
import { createRecallEndpointControl, } from 'zhin.js/adapter';
|
|
2
3
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
3
|
-
import {
|
|
4
|
-
import { formatInboundContent, formatOutboundKmarkdown, isKookBotMentioned, kookInboundConversation, senderDisplayName, } from './protocol.js';
|
|
4
|
+
import { formatInboundContent, formatOutboundKmarkdown, isKookBotMentioned, kookInboundConversation, normalizeKookWebhookEvent, senderDisplayName, } from './protocol.js';
|
|
5
5
|
import { registerKookWebhookRoutes } from './webhook.js';
|
|
6
6
|
import { defaultCreateClient, defaultCreateWebhookClient, normalizeKookMessage, } from './ws.js';
|
|
7
7
|
import { receiveKookSideEvent } from './side-event-dispatch.js';
|
|
8
|
-
export class KookWebsocketEndpoint {
|
|
8
|
+
export class KookWebsocketEndpoint extends Endpoint {
|
|
9
9
|
#logger;
|
|
10
10
|
#options;
|
|
11
11
|
#createClient;
|
|
12
12
|
#client = null;
|
|
13
13
|
#open = false;
|
|
14
14
|
#started = false;
|
|
15
|
-
#unregisterAgent;
|
|
16
15
|
management = createKookEndpointManagement(() => this.#requireClient());
|
|
17
16
|
control = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
18
17
|
constructor(options) {
|
|
18
|
+
super();
|
|
19
19
|
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
20
20
|
this.#options = options;
|
|
21
21
|
this.#createClient = options.createClient ?? defaultCreateClient;
|
|
22
22
|
}
|
|
23
|
+
get client() {
|
|
24
|
+
return this.#requireClient();
|
|
25
|
+
}
|
|
23
26
|
async start() {
|
|
24
27
|
if (this.#started)
|
|
25
28
|
return;
|
|
26
29
|
this.#started = true;
|
|
27
30
|
try {
|
|
28
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
29
31
|
this.#client = this.#createClient(this.#options.config);
|
|
30
32
|
this.#bindClient(this.#client);
|
|
31
33
|
await this.#client.connect();
|
|
@@ -50,8 +52,6 @@ export class KookWebsocketEndpoint {
|
|
|
50
52
|
}
|
|
51
53
|
async stop() {
|
|
52
54
|
this.#open = false;
|
|
53
|
-
this.#unregisterAgent?.();
|
|
54
|
-
this.#unregisterAgent = undefined;
|
|
55
55
|
if (this.#client) {
|
|
56
56
|
try {
|
|
57
57
|
this.#client.removeAllListeners();
|
|
@@ -80,7 +80,7 @@ export class KookWebsocketEndpoint {
|
|
|
80
80
|
}));
|
|
81
81
|
return messageId;
|
|
82
82
|
}
|
|
83
|
-
/** Test / internal: admit a message when open. */
|
|
83
|
+
/** Test / internal: admit a normalized message when open. */
|
|
84
84
|
admit(msg) {
|
|
85
85
|
if (!this.#open)
|
|
86
86
|
return;
|
|
@@ -88,7 +88,7 @@ export class KookWebsocketEndpoint {
|
|
|
88
88
|
return;
|
|
89
89
|
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
90
90
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
91
|
-
void this
|
|
91
|
+
void this.emit('message.receive', {
|
|
92
92
|
conversation,
|
|
93
93
|
message: { conversation, id: msg.id },
|
|
94
94
|
content: formatInboundContent(msg),
|
|
@@ -118,37 +118,26 @@ export class KookWebsocketEndpoint {
|
|
|
118
118
|
return;
|
|
119
119
|
await this.#requireClient().recallMsg?.(messageId);
|
|
120
120
|
}
|
|
121
|
-
// ── Agent tool surface ──────────────────────────────────────────────
|
|
122
|
-
async getRoleList(guildId) {
|
|
123
|
-
return this.#requireClient().pickGuild(guildId).getRoleList();
|
|
124
|
-
}
|
|
125
|
-
async createRole(guildId, name) {
|
|
126
|
-
return this.#requireClient().pickGuild(guildId).createRole(name);
|
|
127
|
-
}
|
|
128
|
-
async deleteRole(guildId, roleId) {
|
|
129
|
-
return this.#requireClient().pickGuild(guildId).deleteRole(roleId);
|
|
130
|
-
}
|
|
131
|
-
async grantRole(guildId, userId, roleId) {
|
|
132
|
-
return this.#requireClient().pickGuildMember(guildId, userId).grant(roleId);
|
|
133
|
-
}
|
|
134
|
-
async revokeRole(guildId, userId, roleId) {
|
|
135
|
-
return this.#requireClient().pickGuildMember(guildId, userId).revoke(roleId);
|
|
136
|
-
}
|
|
137
|
-
async addToBlacklist(guildId, userId, remark) {
|
|
138
|
-
return this.#requireClient().pickGuildMember(guildId, userId).addToBlackList(remark);
|
|
139
|
-
}
|
|
140
|
-
async removeFromBlacklist(guildId, userId) {
|
|
141
|
-
return this.#requireClient().pickGuildMember(guildId, userId).removeFromBlackList();
|
|
142
|
-
}
|
|
143
121
|
#bindClient(client) {
|
|
144
122
|
client.on('message', (raw) => {
|
|
123
|
+
this.#emitPlatformEvent('message', raw);
|
|
145
124
|
const msg = normalizeKookMessage(raw);
|
|
146
125
|
if (msg)
|
|
147
126
|
this.admit(msg);
|
|
148
127
|
});
|
|
149
128
|
const receiver = client.receiver;
|
|
150
129
|
receiver?.on('event', (raw) => {
|
|
151
|
-
|
|
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
|
+
}));
|
|
152
141
|
});
|
|
153
142
|
}
|
|
154
143
|
#requireClient() {
|
|
@@ -157,7 +146,7 @@ export class KookWebsocketEndpoint {
|
|
|
157
146
|
return this.#client;
|
|
158
147
|
}
|
|
159
148
|
}
|
|
160
|
-
export class KookWebhookEndpoint {
|
|
149
|
+
export class KookWebhookEndpoint extends Endpoint {
|
|
161
150
|
#logger;
|
|
162
151
|
#options;
|
|
163
152
|
#createClient;
|
|
@@ -166,14 +155,17 @@ export class KookWebhookEndpoint {
|
|
|
166
155
|
#processedSn = new Set();
|
|
167
156
|
#open = false;
|
|
168
157
|
#started = false;
|
|
169
|
-
#unregisterAgent;
|
|
170
158
|
management = createKookEndpointManagement(() => this.#requireClient());
|
|
171
159
|
control = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
172
160
|
constructor(options) {
|
|
161
|
+
super();
|
|
173
162
|
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
174
163
|
this.#options = options;
|
|
175
164
|
this.#createClient = options.createClient ?? defaultCreateWebhookClient;
|
|
176
165
|
}
|
|
166
|
+
get client() {
|
|
167
|
+
return this.#requireClient();
|
|
168
|
+
}
|
|
177
169
|
/** Used by webhook handler. */
|
|
178
170
|
get isOpen() {
|
|
179
171
|
return this.#open;
|
|
@@ -189,7 +181,6 @@ export class KookWebhookEndpoint {
|
|
|
189
181
|
return;
|
|
190
182
|
this.#started = true;
|
|
191
183
|
try {
|
|
192
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
193
184
|
this.#client = this.#createClient(this.#options.config);
|
|
194
185
|
await this.#client.init();
|
|
195
186
|
this.#routeReleases.push(...registerKookWebhookRoutes(this.#options.http, this));
|
|
@@ -217,8 +208,6 @@ export class KookWebhookEndpoint {
|
|
|
217
208
|
this.#open = false;
|
|
218
209
|
for (const release of this.#routeReleases.splice(0))
|
|
219
210
|
release();
|
|
220
|
-
this.#unregisterAgent?.();
|
|
221
|
-
this.#unregisterAgent = undefined;
|
|
222
211
|
this.#processedSn.clear();
|
|
223
212
|
if (this.#client) {
|
|
224
213
|
try {
|
|
@@ -248,6 +237,23 @@ export class KookWebhookEndpoint {
|
|
|
248
237
|
}));
|
|
249
238
|
return messageId;
|
|
250
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
|
+
}
|
|
251
257
|
/** Test / internal: admit a message when open. */
|
|
252
258
|
admit(msg) {
|
|
253
259
|
if (!this.#open)
|
|
@@ -256,7 +262,7 @@ export class KookWebhookEndpoint {
|
|
|
256
262
|
return;
|
|
257
263
|
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
258
264
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
259
|
-
void this
|
|
265
|
+
void this.emit('message.receive', {
|
|
260
266
|
conversation,
|
|
261
267
|
message: { conversation, id: msg.id },
|
|
262
268
|
content: formatInboundContent(msg),
|
|
@@ -297,27 +303,6 @@ export class KookWebhookEndpoint {
|
|
|
297
303
|
}
|
|
298
304
|
return true;
|
|
299
305
|
}
|
|
300
|
-
async getRoleList(guildId) {
|
|
301
|
-
return this.#requireClient().pickGuild(guildId).getRoleList();
|
|
302
|
-
}
|
|
303
|
-
async createRole(guildId, name) {
|
|
304
|
-
return this.#requireClient().pickGuild(guildId).createRole(name);
|
|
305
|
-
}
|
|
306
|
-
async deleteRole(guildId, roleId) {
|
|
307
|
-
return this.#requireClient().pickGuild(guildId).deleteRole(roleId);
|
|
308
|
-
}
|
|
309
|
-
async grantRole(guildId, userId, roleId) {
|
|
310
|
-
return this.#requireClient().pickGuildMember(guildId, userId).grant(roleId);
|
|
311
|
-
}
|
|
312
|
-
async revokeRole(guildId, userId, roleId) {
|
|
313
|
-
return this.#requireClient().pickGuildMember(guildId, userId).revoke(roleId);
|
|
314
|
-
}
|
|
315
|
-
async addToBlacklist(guildId, userId, remark) {
|
|
316
|
-
return this.#requireClient().pickGuildMember(guildId, userId).addToBlackList(remark);
|
|
317
|
-
}
|
|
318
|
-
async removeFromBlacklist(guildId, userId) {
|
|
319
|
-
return this.#requireClient().pickGuildMember(guildId, userId).removeFromBlackList();
|
|
320
|
-
}
|
|
321
306
|
#requireClient() {
|
|
322
307
|
if (!this.#client)
|
|
323
308
|
throw new Error('KOOK client not initialized');
|
package/lib/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export { formatInboundContent, formatOutboundKmarkdown, resolveKookConfig, sende
|
|
|
2
2
|
export { KookWebhookEndpoint, KookWebsocketEndpoint, type KookEndpointOptions, type KookWebhookEndpointOptions, } from './endpoint.js';
|
|
3
3
|
export { registerKookWebhookRoutes, handleKookWebhookRequest, type KookWebhookHandler, } from './webhook.js';
|
|
4
4
|
export { defaultCreateClient, defaultCreateWebhookClient, normalizeKookMessage, type CreateKookClient, type KookClientTransport, } from './ws.js';
|
|
5
|
-
export {
|
|
5
|
+
export { kookClient, type KookClientEventMap } from './client.js';
|
|
6
6
|
export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit, type KookSenderInfo, } from './platform-permit.js';
|
package/lib/index.js
CHANGED
|
@@ -2,5 +2,5 @@ export { formatInboundContent, formatOutboundKmarkdown, resolveKookConfig, sende
|
|
|
2
2
|
export { KookWebhookEndpoint, KookWebsocketEndpoint, } from './endpoint.js';
|
|
3
3
|
export { registerKookWebhookRoutes, handleKookWebhookRequest, } from './webhook.js';
|
|
4
4
|
export { defaultCreateClient, defaultCreateWebhookClient, normalizeKookMessage, } from './ws.js';
|
|
5
|
-
export {
|
|
5
|
+
export { kookClient } from './client.js';
|
|
6
6
|
export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit, } from './platform-permit.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const kookEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage>>>;
|
|
1
|
+
export declare const kookEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
|