@zhin.js/adapter-kook 6.0.0 → 6.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 +27 -0
- package/adapters/kook.ts +11 -0
- package/commands/endpoint/add/[name:string].ts +3 -0
- package/commands/endpoint/list.ts +3 -0
- package/commands/endpoint/remove/[name:string].ts +3 -0
- package/lib/endpoint.d.ts +10 -2
- package/lib/endpoint.js +65 -0
- package/lib/kook-endpoint-commands.d.ts +1 -0
- package/lib/kook-endpoint-commands.js +18 -0
- package/lib/kook-runtime-state.d.ts +1 -0
- package/lib/kook-runtime-state.js +6 -0
- package/lib/ws.d.ts +14 -1
- package/package.json +19 -13
- package/plugin.ts +5 -1
- package/src/endpoint.ts +71 -1
- package/src/kook-endpoint-commands.ts +19 -0
- package/src/kook-runtime-state.ts +7 -0
- package/src/ws.ts +11 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @zhin.js/adapter-kook
|
|
2
2
|
|
|
3
|
+
## 6.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 74b035c: endpoint 管理命令扩展至 18/20 适配器:kook / discord / github(private_key 支持内联文件路径)/ icqq(bindFlow 登记式 add + `icqq login` 引导)/ dingtalk / lark / line / satori / wechat-mp / wecom / weixin-ilink 接入 `endpoint list/add/remove`(字段对齐各自 schema,凭据写 `.env`)。email(smtp/imap 嵌套对象)与 sandbox(无凭据)暂不接。
|
|
8
|
+
- 09d4f25: Console 社交读取面(management 语义端口)多平台落地:napcat/onebot11/onebot12/milky(好友+群+群成员,OneBot 标准动作);discord/kook/satori(guild+频道+成员,分页聚合,id 保精度留字符串);slack(workspace 成员+public channels+conversations.members);line(群/room 成员分页+profile 回退);wechat-mp(followers openid);weixin-ilink(context_token 对端推导);lark(chats+members 全分页)。`EndpointFriend.user_id`/`EndpointGroup.group_id` 放宽为 `number | string`(雪花 id 不丢精度)。telegram/wecom/dingtalk/github/email/sandbox 注明平台无列表面暂不接。
|
|
9
|
+
- Updated dependencies [cdf64e7]
|
|
10
|
+
- Updated dependencies [2d0a159]
|
|
11
|
+
- Updated dependencies [5691aba]
|
|
12
|
+
- Updated dependencies [078e3f7]
|
|
13
|
+
- Updated dependencies [50497a5]
|
|
14
|
+
- Updated dependencies [9c997b2]
|
|
15
|
+
- Updated dependencies [09d4f25]
|
|
16
|
+
- Updated dependencies [43485a9]
|
|
17
|
+
- Updated dependencies [f0ec5ab]
|
|
18
|
+
- Updated dependencies [3e925d0]
|
|
19
|
+
- Updated dependencies [fa66c4c]
|
|
20
|
+
- Updated dependencies [fa66c4c]
|
|
21
|
+
- Updated dependencies [6cb6152]
|
|
22
|
+
- @zhin.js/command@1.0.3
|
|
23
|
+
- @zhin.js/agent@1.0.6
|
|
24
|
+
- @zhin.js/plugin-runtime@1.1.1
|
|
25
|
+
- @zhin.js/host-http@1.0.3
|
|
26
|
+
- zhin.js@5.0.1
|
|
27
|
+
- @zhin.js/adapter@1.1.1
|
|
28
|
+
- @zhin.js/core@1.4.1
|
|
29
|
+
|
|
3
30
|
## 6.0.0
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/adapters/kook.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
resolveKookConfig,
|
|
14
14
|
type KookAdapterConfig,
|
|
15
15
|
} from '../src/protocol.js';
|
|
16
|
+
import { kookRuntimeStateToken } from '../src/kook-runtime-state.js';
|
|
16
17
|
|
|
17
18
|
export {
|
|
18
19
|
KookWebhookEndpoint,
|
|
@@ -26,9 +27,19 @@ export type { CreateKookClient, KookClientTransport } from '../src/ws.js';
|
|
|
26
27
|
|
|
27
28
|
export default defineAdapter<KookAdapterConfig>({
|
|
28
29
|
capabilities: ['inbound', 'outbound'],
|
|
30
|
+
// KOOK 图片消息消费远程 URL;无按钮交互面,交互段降级纯文本。
|
|
31
|
+
segments: {
|
|
32
|
+
outboundMedia: ['url'],
|
|
33
|
+
interactive: 'text',
|
|
34
|
+
},
|
|
29
35
|
create(context) {
|
|
30
36
|
const config = resolveKookConfig(context.config);
|
|
31
37
|
const gateway = context.use(messageGatewayToken);
|
|
38
|
+
// 注册到插件运行时状态(kook endpoint list 的"运行中"数据源)
|
|
39
|
+
context.use(kookRuntimeStateToken).endpoints.set(config.name, {
|
|
40
|
+
name: config.name,
|
|
41
|
+
mode: config.connection,
|
|
42
|
+
});
|
|
32
43
|
if (config.connection === 'webhook') {
|
|
33
44
|
return new KookWebhookEndpoint({
|
|
34
45
|
id: context.id,
|
package/lib/endpoint.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { EndpointInstance } from '@zhin.js/adapter';
|
|
1
|
+
import type { EndpointInstance, EndpointManagement } from '@zhin.js/adapter';
|
|
2
2
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
3
3
|
import type { HttpHost } from '@zhin.js/host-http';
|
|
4
4
|
import type { CapabilityId } from '@zhin.js/plugin-runtime';
|
|
5
5
|
import { type KookInboundMessage, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig } from './protocol.js';
|
|
6
|
-
import { type CreateKookClient } from './ws.js';
|
|
6
|
+
import { type CreateKookClient, type KookClientTransport } from './ws.js';
|
|
7
7
|
export interface KookEndpointOptions {
|
|
8
8
|
readonly id: CapabilityId;
|
|
9
9
|
readonly gateway: MessageGateway;
|
|
@@ -12,6 +12,7 @@ export interface KookEndpointOptions {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class KookWebsocketEndpoint implements EndpointInstance {
|
|
14
14
|
#private;
|
|
15
|
+
readonly management: EndpointManagement;
|
|
15
16
|
constructor(options: KookEndpointOptions);
|
|
16
17
|
start(): Promise<void>;
|
|
17
18
|
open(): void;
|
|
@@ -49,6 +50,7 @@ export interface KookWebhookEndpointOptions {
|
|
|
49
50
|
}
|
|
50
51
|
export declare class KookWebhookEndpoint implements EndpointInstance {
|
|
51
52
|
#private;
|
|
53
|
+
readonly management: EndpointManagement;
|
|
52
54
|
constructor(options: KookWebhookEndpointOptions);
|
|
53
55
|
/** Used by webhook handler. */
|
|
54
56
|
get isOpen(): boolean;
|
|
@@ -82,3 +84,9 @@ export declare class KookWebhookEndpoint implements EndpointInstance {
|
|
|
82
84
|
addToBlacklist(guildId: string, userId: string, remark?: string): Promise<boolean>;
|
|
83
85
|
removeFromBlacklist(guildId: string, userId: string): Promise<boolean>;
|
|
84
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* KOOK endpoint 的 EndpointManagement 语义端口(websocket / webhook 共用)。
|
|
89
|
+
* 数据走 kook-client 的 HTTP API 封装:/api/v3/guild/list、
|
|
90
|
+
* /api/v3/channel/list、/api/v3/guild/user-list(SDK 内部已做分页聚合)。
|
|
91
|
+
*/
|
|
92
|
+
export declare function createKookEndpointManagement(requireClient: () => KookClientTransport): EndpointManagement;
|
package/lib/endpoint.js
CHANGED
|
@@ -11,6 +11,7 @@ export class KookWebsocketEndpoint {
|
|
|
11
11
|
#open = false;
|
|
12
12
|
#started = false;
|
|
13
13
|
#unregisterAgent;
|
|
14
|
+
management = createKookEndpointManagement(() => this.#requireClient());
|
|
14
15
|
constructor(options) {
|
|
15
16
|
this.#options = options;
|
|
16
17
|
this.#createClient = options.createClient ?? defaultCreateClient;
|
|
@@ -150,6 +151,7 @@ export class KookWebhookEndpoint {
|
|
|
150
151
|
#open = false;
|
|
151
152
|
#started = false;
|
|
152
153
|
#unregisterAgent;
|
|
154
|
+
management = createKookEndpointManagement(() => this.#requireClient());
|
|
153
155
|
constructor(options) {
|
|
154
156
|
this.#options = options;
|
|
155
157
|
this.#createClient = options.createClient ?? defaultCreateWebhookClient;
|
|
@@ -297,3 +299,66 @@ export class KookWebhookEndpoint {
|
|
|
297
299
|
return this.#client;
|
|
298
300
|
}
|
|
299
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* KOOK guild/channel/user id 是字符串形式的雪花号,超出
|
|
304
|
+
* Number.MAX_SAFE_INTEGER,Number() 会丢精度。Console 社交面只把 group_id
|
|
305
|
+
* 当 JSON 值透传、并以字符串回传给 listGroupMembers,因此保留原始字符串
|
|
306
|
+
* (仅按契约类型声明强转)是全链路最不丢信息的方案。
|
|
307
|
+
*/
|
|
308
|
+
function toGroupId(id) {
|
|
309
|
+
return id;
|
|
310
|
+
}
|
|
311
|
+
/** KOOK 文字频道标记:HTTP API type=1(2=语音),kook-client 消息侧用 'GROUP'。 */
|
|
312
|
+
function isKookTextChannelType(type) {
|
|
313
|
+
return type === 1 || type === '1' || type === 'GROUP';
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* KOOK endpoint 的 EndpointManagement 语义端口(websocket / webhook 共用)。
|
|
317
|
+
* 数据走 kook-client 的 HTTP API 封装:/api/v3/guild/list、
|
|
318
|
+
* /api/v3/channel/list、/api/v3/guild/user-list(SDK 内部已做分页聚合)。
|
|
319
|
+
*/
|
|
320
|
+
export function createKookEndpointManagement(requireClient) {
|
|
321
|
+
return Object.freeze({
|
|
322
|
+
async listGroups() {
|
|
323
|
+
const guilds = await requireClient().getGuildList();
|
|
324
|
+
const groups = [];
|
|
325
|
+
for (const guild of guilds) {
|
|
326
|
+
if (guild?.id == null)
|
|
327
|
+
continue;
|
|
328
|
+
groups.push({
|
|
329
|
+
group_id: toGroupId(String(guild.id)),
|
|
330
|
+
name: String(guild.name ?? guild.id),
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
return groups;
|
|
334
|
+
},
|
|
335
|
+
async listChannels() {
|
|
336
|
+
const client = requireClient();
|
|
337
|
+
const channels = [];
|
|
338
|
+
for (const guild of await client.getGuildList()) {
|
|
339
|
+
if (guild?.id == null)
|
|
340
|
+
continue;
|
|
341
|
+
const guildId = String(guild.id);
|
|
342
|
+
const guildName = String(guild.name ?? guildId);
|
|
343
|
+
for (const channel of await client.getChannelList(guildId)) {
|
|
344
|
+
if (channel?.id == null)
|
|
345
|
+
continue;
|
|
346
|
+
if (channel.is_category)
|
|
347
|
+
continue;
|
|
348
|
+
if (!isKookTextChannelType(channel.type))
|
|
349
|
+
continue;
|
|
350
|
+
channels.push({
|
|
351
|
+
id: String(channel.id),
|
|
352
|
+
name: channel.name ? String(channel.name) : undefined,
|
|
353
|
+
parent: { type: 'guild', id: guildId, name: guildName },
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return channels;
|
|
358
|
+
},
|
|
359
|
+
async listGroupMembers(groupId) {
|
|
360
|
+
// 平台形状(User.Info[])原样返回
|
|
361
|
+
return requireClient().getGuildUserList(groupId);
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const kookEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage>>>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kook endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
|
|
3
|
+
* commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
|
|
4
|
+
*/
|
|
5
|
+
import { createEndpointCommands } from '@zhin.js/adapter';
|
|
6
|
+
import { defineCommand } from '@zhin.js/command';
|
|
7
|
+
import { kookRuntimeStateToken } from './kook-runtime-state.js';
|
|
8
|
+
export const kookEndpointCommands = createEndpointCommands({
|
|
9
|
+
adapterKey: 'kook',
|
|
10
|
+
adapterDisplayName: 'KOOK',
|
|
11
|
+
fields: [
|
|
12
|
+
{ key: 'token', required: true, env: true, description: 'KOOK bot token' },
|
|
13
|
+
{ key: 'encrypt_key', env: true, description: 'webhook 加密密钥(connection: webhook)' },
|
|
14
|
+
{ key: 'verify_token', env: true, description: 'webhook 验证 token(connection: webhook)' },
|
|
15
|
+
],
|
|
16
|
+
running: (use) => use(kookRuntimeStateToken).endpoints.values(),
|
|
17
|
+
describeEntry: (entry) => `token: ${String(entry.token)}`,
|
|
18
|
+
}, defineCommand);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const kookRuntimeStateToken: import("@zhin.js/plugin-runtime").Token<import("@zhin.js/adapter").EndpointRuntimeState>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KOOK 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
|
|
3
|
+
* 由 plugin.ts setup() provide,adapter create 与 `kook endpoint` 命令共享(同一 owner generation)。
|
|
4
|
+
*/
|
|
5
|
+
import { defineEndpointRuntimeStateToken } from '@zhin.js/adapter';
|
|
6
|
+
export const kookRuntimeStateToken = defineEndpointRuntimeStateToken('kook');
|
package/lib/ws.d.ts
CHANGED
|
@@ -33,7 +33,20 @@ export interface KookClientTransport {
|
|
|
33
33
|
revoke(roleId: string): Promise<boolean>;
|
|
34
34
|
setNickname(nickname: string): Promise<boolean>;
|
|
35
35
|
};
|
|
36
|
-
|
|
36
|
+
/** GET /api/v3/guild/list(kook-client 内部分页聚合)。 */
|
|
37
|
+
getGuildList(): Promise<Array<{
|
|
38
|
+
id: string | number;
|
|
39
|
+
name?: string;
|
|
40
|
+
}>>;
|
|
41
|
+
/** GET /api/v3/channel/list(type: 1=文字 2=语音;is_category 为分组)。 */
|
|
42
|
+
getChannelList(guildId: string): Promise<Array<{
|
|
43
|
+
id: string | number;
|
|
44
|
+
name?: string;
|
|
45
|
+
type?: string | number;
|
|
46
|
+
is_category?: boolean;
|
|
47
|
+
}>>;
|
|
48
|
+
/** GET /api/v3/guild/user-list。 */
|
|
49
|
+
getGuildUserList(guildId: string, channelId?: string): Promise<unknown[]>;
|
|
37
50
|
self_id?: string | number;
|
|
38
51
|
}
|
|
39
52
|
export type CreateKookClient = (config: ResolvedKookConfig) => KookClientTransport;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-kook",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "Zhin.js KOOK adapter for Plugin Runtime (WebSocket gateway or Webhook)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -34,19 +34,20 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"kook-client": "^1.0.4",
|
|
37
|
-
"@zhin.js/adapter": "1.1.
|
|
38
|
-
"@zhin.js/
|
|
39
|
-
"@zhin.js/
|
|
37
|
+
"@zhin.js/adapter": "1.1.1",
|
|
38
|
+
"@zhin.js/command": "1.0.3",
|
|
39
|
+
"@zhin.js/core": "1.4.1",
|
|
40
|
+
"@zhin.js/host-http": "1.0.3",
|
|
40
41
|
"@zhin.js/logger": "1.0.75",
|
|
41
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
42
|
+
"@zhin.js/plugin-runtime": "1.1.1"
|
|
42
43
|
},
|
|
43
44
|
"peerDependencies": {
|
|
44
45
|
"zod": "^4.0.0",
|
|
45
|
-
"@zhin.js/adapter": "1.1.
|
|
46
|
-
"@zhin.js/agent": "1.0.
|
|
47
|
-
"@zhin.js/core": "1.4.
|
|
48
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
49
|
-
"zhin.js": "5.0.
|
|
46
|
+
"@zhin.js/adapter": "1.1.1",
|
|
47
|
+
"@zhin.js/agent": "1.0.6",
|
|
48
|
+
"@zhin.js/core": "1.4.1",
|
|
49
|
+
"@zhin.js/plugin-runtime": "1.1.1",
|
|
50
|
+
"zhin.js": "5.0.1"
|
|
50
51
|
},
|
|
51
52
|
"peerDependenciesMeta": {
|
|
52
53
|
"zhin.js": {
|
|
@@ -64,12 +65,13 @@
|
|
|
64
65
|
"typescript": "^6.0.3",
|
|
65
66
|
"vitest": "^4.1.10",
|
|
66
67
|
"zod": "^4.4.3",
|
|
67
|
-
"@zhin.js/agent": "1.0.
|
|
68
|
-
"@zhin.js/host-http": "1.0.
|
|
69
|
-
"zhin.js": "5.0.
|
|
68
|
+
"@zhin.js/agent": "1.0.6",
|
|
69
|
+
"@zhin.js/host-http": "1.0.3",
|
|
70
|
+
"zhin.js": "5.0.1"
|
|
70
71
|
},
|
|
71
72
|
"files": [
|
|
72
73
|
"adapters",
|
|
74
|
+
"commands",
|
|
73
75
|
"plugin.ts",
|
|
74
76
|
"schema.json",
|
|
75
77
|
"src",
|
|
@@ -95,6 +97,10 @@
|
|
|
95
97
|
{
|
|
96
98
|
"package": "@zhin.js/adapter",
|
|
97
99
|
"api": "^1.0.0"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"package": "@zhin.js/command",
|
|
103
|
+
"api": "^1.0.0"
|
|
98
104
|
}
|
|
99
105
|
],
|
|
100
106
|
"plugins": []
|
package/plugin.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import { createEndpointRuntimeState } from '@zhin.js/adapter';
|
|
1
2
|
import { definePlugin } from '@zhin.js/plugin-runtime';
|
|
2
3
|
import { registerKookPlatformPermitChecker } from './src/platform-permit.js';
|
|
4
|
+
import { kookRuntimeStateToken } from './src/kook-runtime-state.js';
|
|
3
5
|
|
|
4
6
|
export default definePlugin({
|
|
5
7
|
name: 'kook',
|
|
6
8
|
metadata: {
|
|
7
9
|
displayName: 'KOOK WebSocket Adapter',
|
|
8
10
|
},
|
|
9
|
-
setup() {
|
|
11
|
+
setup(context) {
|
|
12
|
+
// 运行中 endpoint 注册表(kook endpoint list 的"运行中"数据源)
|
|
13
|
+
context.resources.provide(kookRuntimeStateToken, createEndpointRuntimeState());
|
|
10
14
|
// 平台权限门禁:guild_owner / guild_admin / channel_admin 等(agent 工具 platformPermit)
|
|
11
15
|
return registerKookPlatformPermitChecker();
|
|
12
16
|
},
|
package/src/endpoint.ts
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* KookEndpoint — lifecycle, outbound, admit, OpenAPI helpers for agent tools.
|
|
3
3
|
*/
|
|
4
4
|
import { Client } from 'kook-client';
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
EndpointChannel,
|
|
7
|
+
EndpointGroup,
|
|
8
|
+
EndpointInstance,
|
|
9
|
+
EndpointManagement,
|
|
10
|
+
} from '@zhin.js/adapter';
|
|
6
11
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
7
12
|
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
8
13
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
@@ -44,6 +49,7 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
44
49
|
#open = false;
|
|
45
50
|
#started = false;
|
|
46
51
|
#unregisterAgent?: () => void;
|
|
52
|
+
readonly management: EndpointManagement = createKookEndpointManagement(() => this.#requireClient());
|
|
47
53
|
|
|
48
54
|
constructor(options: KookEndpointOptions) {
|
|
49
55
|
this.#options = options;
|
|
@@ -202,6 +208,7 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
202
208
|
#open = false;
|
|
203
209
|
#started = false;
|
|
204
210
|
#unregisterAgent?: () => void;
|
|
211
|
+
readonly management: EndpointManagement = createKookEndpointManagement(() => this.#requireClient());
|
|
205
212
|
|
|
206
213
|
constructor(options: KookWebhookEndpointOptions) {
|
|
207
214
|
this.#options = options;
|
|
@@ -359,3 +366,66 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
359
366
|
return this.#client;
|
|
360
367
|
}
|
|
361
368
|
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* KOOK guild/channel/user id 是字符串形式的雪花号,超出
|
|
372
|
+
* Number.MAX_SAFE_INTEGER,Number() 会丢精度。Console 社交面只把 group_id
|
|
373
|
+
* 当 JSON 值透传、并以字符串回传给 listGroupMembers,因此保留原始字符串
|
|
374
|
+
* (仅按契约类型声明强转)是全链路最不丢信息的方案。
|
|
375
|
+
*/
|
|
376
|
+
function toGroupId(id: string): number {
|
|
377
|
+
return id as unknown as number;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/** KOOK 文字频道标记:HTTP API type=1(2=语音),kook-client 消息侧用 'GROUP'。 */
|
|
381
|
+
function isKookTextChannelType(type: string | number | undefined): boolean {
|
|
382
|
+
return type === 1 || type === '1' || type === 'GROUP';
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* KOOK endpoint 的 EndpointManagement 语义端口(websocket / webhook 共用)。
|
|
387
|
+
* 数据走 kook-client 的 HTTP API 封装:/api/v3/guild/list、
|
|
388
|
+
* /api/v3/channel/list、/api/v3/guild/user-list(SDK 内部已做分页聚合)。
|
|
389
|
+
*/
|
|
390
|
+
export function createKookEndpointManagement(
|
|
391
|
+
requireClient: () => KookClientTransport,
|
|
392
|
+
): EndpointManagement {
|
|
393
|
+
return Object.freeze<EndpointManagement>({
|
|
394
|
+
async listGroups(): Promise<readonly EndpointGroup[]> {
|
|
395
|
+
const guilds = await requireClient().getGuildList();
|
|
396
|
+
const groups: EndpointGroup[] = [];
|
|
397
|
+
for (const guild of guilds) {
|
|
398
|
+
if (guild?.id == null) continue;
|
|
399
|
+
groups.push({
|
|
400
|
+
group_id: toGroupId(String(guild.id)),
|
|
401
|
+
name: String(guild.name ?? guild.id),
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
return groups;
|
|
405
|
+
},
|
|
406
|
+
async listChannels(): Promise<readonly EndpointChannel[]> {
|
|
407
|
+
const client = requireClient();
|
|
408
|
+
const channels: EndpointChannel[] = [];
|
|
409
|
+
for (const guild of await client.getGuildList()) {
|
|
410
|
+
if (guild?.id == null) continue;
|
|
411
|
+
const guildId = String(guild.id);
|
|
412
|
+
const guildName = String(guild.name ?? guildId);
|
|
413
|
+
for (const channel of await client.getChannelList(guildId)) {
|
|
414
|
+
if (channel?.id == null) continue;
|
|
415
|
+
if (channel.is_category) continue;
|
|
416
|
+
if (!isKookTextChannelType(channel.type)) continue;
|
|
417
|
+
channels.push({
|
|
418
|
+
id: String(channel.id),
|
|
419
|
+
name: channel.name ? String(channel.name) : undefined,
|
|
420
|
+
parent: { type: 'guild', id: guildId, name: guildName },
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return channels;
|
|
425
|
+
},
|
|
426
|
+
async listGroupMembers(groupId: string): Promise<readonly unknown[]> {
|
|
427
|
+
// 平台形状(User.Info[])原样返回
|
|
428
|
+
return requireClient().getGuildUserList(groupId);
|
|
429
|
+
},
|
|
430
|
+
});
|
|
431
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kook endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
|
|
3
|
+
* commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
|
|
4
|
+
*/
|
|
5
|
+
import { createEndpointCommands } from '@zhin.js/adapter';
|
|
6
|
+
import { defineCommand } from '@zhin.js/command';
|
|
7
|
+
import { kookRuntimeStateToken } from './kook-runtime-state.js';
|
|
8
|
+
|
|
9
|
+
export const kookEndpointCommands = createEndpointCommands({
|
|
10
|
+
adapterKey: 'kook',
|
|
11
|
+
adapterDisplayName: 'KOOK',
|
|
12
|
+
fields: [
|
|
13
|
+
{ key: 'token', required: true, env: true, description: 'KOOK bot token' },
|
|
14
|
+
{ key: 'encrypt_key', env: true, description: 'webhook 加密密钥(connection: webhook)' },
|
|
15
|
+
{ key: 'verify_token', env: true, description: 'webhook 验证 token(connection: webhook)' },
|
|
16
|
+
],
|
|
17
|
+
running: (use) => use(kookRuntimeStateToken).endpoints.values(),
|
|
18
|
+
describeEntry: (entry) => `token: ${String(entry.token)}`,
|
|
19
|
+
}, defineCommand);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KOOK 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
|
|
3
|
+
* 由 plugin.ts setup() provide,adapter create 与 `kook endpoint` 命令共享(同一 owner generation)。
|
|
4
|
+
*/
|
|
5
|
+
import { defineEndpointRuntimeStateToken } from '@zhin.js/adapter';
|
|
6
|
+
|
|
7
|
+
export const kookRuntimeStateToken = defineEndpointRuntimeStateToken('kook');
|
package/src/ws.ts
CHANGED
|
@@ -43,7 +43,17 @@ export interface KookClientTransport {
|
|
|
43
43
|
revoke(roleId: string): Promise<boolean>;
|
|
44
44
|
setNickname(nickname: string): Promise<boolean>;
|
|
45
45
|
};
|
|
46
|
-
|
|
46
|
+
/** GET /api/v3/guild/list(kook-client 内部分页聚合)。 */
|
|
47
|
+
getGuildList(): Promise<Array<{ id: string | number; name?: string }>>;
|
|
48
|
+
/** GET /api/v3/channel/list(type: 1=文字 2=语音;is_category 为分组)。 */
|
|
49
|
+
getChannelList(guildId: string): Promise<Array<{
|
|
50
|
+
id: string | number;
|
|
51
|
+
name?: string;
|
|
52
|
+
type?: string | number;
|
|
53
|
+
is_category?: boolean;
|
|
54
|
+
}>>;
|
|
55
|
+
/** GET /api/v3/guild/user-list。 */
|
|
56
|
+
getGuildUserList(guildId: string, channelId?: string): Promise<unknown[]>;
|
|
47
57
|
self_id?: string | number;
|
|
48
58
|
}
|
|
49
59
|
|