@zhin.js/adapter-kook 7.0.2 → 7.0.5
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 +95 -0
- package/README.md +3 -3
- package/adapters/kook.js +2 -2
- package/adapters/kook.ts +2 -2
- package/lib/endpoint.d.ts +3 -9
- package/lib/endpoint.js +54 -47
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/kook-agent-deps.d.ts +2 -2
- package/lib/kook-agent-deps.js +7 -7
- package/lib/platform-permit.d.ts +2 -3
- package/lib/platform-permit.js +3 -20
- package/lib/protocol.d.ts +8 -11
- package/lib/protocol.js +15 -20
- package/package.json +17 -15
- package/plugin.js +6 -4
- package/schema.json +41 -5
- package/src/endpoint.ts +57 -49
- package/src/index.ts +0 -4
- package/src/kook-agent-deps.ts +8 -8
- package/src/platform-permit.ts +4 -15
- package/src/protocol.ts +20 -28
- /package/commands/endpoint/add/{[name:string].js → [id].js} +0 -0
- /package/commands/endpoint/add/{[name:string].ts → [id].ts} +0 -0
- /package/commands/endpoint/remove/{[name:string].js → [id].js} +0 -0
- /package/commands/endpoint/remove/{[name:string].ts → [id].ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,100 @@
|
|
|
1
1
|
# @zhin.js/adapter-kook
|
|
2
2
|
|
|
3
|
+
## 7.0.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 51015d6: refactor(adapters): migrate platform-permit to PermissionSubject
|
|
8
|
+
|
|
9
|
+
All adapter platform-permit checkers now accept PermissionSubject
|
|
10
|
+
(duck-typed from Message/CommandSession) instead of Message directly.
|
|
11
|
+
registerPlatformPermitChecker is replaced by host.registerPlatform in
|
|
12
|
+
the adapter plugin setup. activity-feedback service updated for new
|
|
13
|
+
PermissionHost integration.
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [6f9c366]
|
|
16
|
+
- Updated dependencies [373a56b]
|
|
17
|
+
- Updated dependencies [0de46a8]
|
|
18
|
+
- Updated dependencies [c106ecc]
|
|
19
|
+
- Updated dependencies [ca92e03]
|
|
20
|
+
- Updated dependencies [b0f37ae]
|
|
21
|
+
- Updated dependencies [ba08a2f]
|
|
22
|
+
- Updated dependencies [b08f7fe]
|
|
23
|
+
- Updated dependencies [daffd4c]
|
|
24
|
+
- Updated dependencies [36c7400]
|
|
25
|
+
- Updated dependencies [a9fa72e]
|
|
26
|
+
- Updated dependencies [c8de3ef]
|
|
27
|
+
- Updated dependencies [60f0fc8]
|
|
28
|
+
- Updated dependencies [574c990]
|
|
29
|
+
- Updated dependencies [d096f16]
|
|
30
|
+
- Updated dependencies [3f29623]
|
|
31
|
+
- Updated dependencies [2916852]
|
|
32
|
+
- Updated dependencies [d047869]
|
|
33
|
+
- Updated dependencies [162fa34]
|
|
34
|
+
- Updated dependencies [e62561e]
|
|
35
|
+
- Updated dependencies [3eeeb46]
|
|
36
|
+
- Updated dependencies [85d0f82]
|
|
37
|
+
- Updated dependencies [61bfc1c]
|
|
38
|
+
- Updated dependencies [04bad47]
|
|
39
|
+
- Updated dependencies [e40b048]
|
|
40
|
+
- Updated dependencies [5a5b1bb]
|
|
41
|
+
- Updated dependencies [f1708c3]
|
|
42
|
+
- Updated dependencies [d254a81]
|
|
43
|
+
- Updated dependencies [7123c47]
|
|
44
|
+
- Updated dependencies [05befc1]
|
|
45
|
+
- Updated dependencies [0663b6a]
|
|
46
|
+
- Updated dependencies [f28f9b3]
|
|
47
|
+
- Updated dependencies [9f340f7]
|
|
48
|
+
- Updated dependencies [e53444f]
|
|
49
|
+
- Updated dependencies [5eedd26]
|
|
50
|
+
- Updated dependencies [92b0dd7]
|
|
51
|
+
- Updated dependencies [f919b6f]
|
|
52
|
+
- Updated dependencies [098e411]
|
|
53
|
+
- Updated dependencies [e1b7c01]
|
|
54
|
+
- Updated dependencies [9b94f87]
|
|
55
|
+
- Updated dependencies [a7df753]
|
|
56
|
+
- @zhin.js/agent@1.1.5
|
|
57
|
+
- @zhin.js/host-http@1.0.8
|
|
58
|
+
- @zhin.js/permission@1.0.1
|
|
59
|
+
- @zhin.js/im-contract@1.0.3
|
|
60
|
+
- @zhin.js/adapter@1.1.7
|
|
61
|
+
- @zhin.js/plugin-runtime@1.1.5
|
|
62
|
+
- @zhin.js/command@1.0.9
|
|
63
|
+
- @zhin.js/core@1.5.4
|
|
64
|
+
- zhin.js@6.0.4
|
|
65
|
+
|
|
66
|
+
## 7.0.4
|
|
67
|
+
|
|
68
|
+
### Patch Changes
|
|
69
|
+
|
|
70
|
+
- f8c7a54: fix: im
|
|
71
|
+
- Updated dependencies [f8c7a54]
|
|
72
|
+
- @zhin.js/logger@1.0.76
|
|
73
|
+
- @zhin.js/host-http@1.0.7
|
|
74
|
+
- @zhin.js/adapter@1.1.6
|
|
75
|
+
- @zhin.js/agent@1.1.4
|
|
76
|
+
- @zhin.js/command@1.0.8
|
|
77
|
+
- @zhin.js/core@1.5.3
|
|
78
|
+
- @zhin.js/im-contract@1.0.2
|
|
79
|
+
- @zhin.js/plugin-runtime@1.1.4
|
|
80
|
+
- zhin.js@6.0.3
|
|
81
|
+
|
|
82
|
+
## 7.0.3
|
|
83
|
+
|
|
84
|
+
### Patch Changes
|
|
85
|
+
|
|
86
|
+
- Updated dependencies [afc0e66]
|
|
87
|
+
- Updated dependencies [2e41ad5]
|
|
88
|
+
- Updated dependencies [9f57124]
|
|
89
|
+
- @zhin.js/core@1.5.2
|
|
90
|
+
- @zhin.js/adapter@1.1.5
|
|
91
|
+
- @zhin.js/im-contract@1.0.1
|
|
92
|
+
- @zhin.js/plugin-runtime@1.1.3
|
|
93
|
+
- @zhin.js/command@1.0.7
|
|
94
|
+
- @zhin.js/host-http@1.0.6
|
|
95
|
+
- @zhin.js/agent@1.1.3
|
|
96
|
+
- zhin.js@6.0.2
|
|
97
|
+
|
|
3
98
|
## 7.0.2
|
|
4
99
|
|
|
5
100
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Zhin.js KOOK(开黑啦)适配器(Plugin Runtime),默认通过 **WebSoc
|
|
|
7
7
|
- WebSocket Gateway 入站(默认;无需公网 HTTPS / host)
|
|
8
8
|
- Webhook 入站(`connection: webhook` + `httpHostToken` + `verify_token`)
|
|
9
9
|
- 解析频道与私聊文本消息
|
|
10
|
-
- 出站 `send({
|
|
10
|
+
- 出站 `send({ conversation, payload })` → KOOK KMarkdown(`kind: 'channel' | 'private'`)
|
|
11
11
|
- 约定式 `defineAdapter` / `definePlugin`(无需 `usePlugin`)
|
|
12
12
|
|
|
13
13
|
## 安装
|
|
@@ -25,8 +25,8 @@ pnpm add @zhin.js/adapter-kook
|
|
|
25
25
|
- 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
|
|
26
26
|
- **WebSocket 路径无需** `@zhin.js/host-http` / `@zhin.js/host-router`
|
|
27
27
|
|
|
28
|
-
入站:`gateway.receive({
|
|
29
|
-
出站:`send({
|
|
28
|
+
入站:`gateway.receive({ conversation, message, content, sender, metadata })`(ConversationRef:`channel` 频道消息带 guild `parent`,`private` 私聊)
|
|
29
|
+
出站:`send({ conversation, payload })` → `sendChannelMsg` / `sendPrivateMsg`
|
|
30
30
|
|
|
31
31
|
## 前置条件
|
|
32
32
|
|
package/adapters/kook.js
CHANGED
|
@@ -21,8 +21,8 @@ export default defineAdapter({
|
|
|
21
21
|
const config = resolveKookConfig(context.config);
|
|
22
22
|
const gateway = context.use(messageGatewayToken);
|
|
23
23
|
// 注册到插件运行时状态(kook.endpoint list 的"运行中"数据源)
|
|
24
|
-
context.use(kookRuntimeStateToken).endpoints.set(config.
|
|
25
|
-
|
|
24
|
+
context.use(kookRuntimeStateToken).endpoints.set(config.id, {
|
|
25
|
+
id: config.id,
|
|
26
26
|
mode: config.connection,
|
|
27
27
|
});
|
|
28
28
|
if (config.connection === 'webhook') {
|
package/adapters/kook.ts
CHANGED
|
@@ -36,8 +36,8 @@ export default defineAdapter<KookAdapterConfig>({
|
|
|
36
36
|
const config = resolveKookConfig(context.config);
|
|
37
37
|
const gateway = context.use(messageGatewayToken);
|
|
38
38
|
// 注册到插件运行时状态(kook.endpoint list 的"运行中"数据源)
|
|
39
|
-
context.use(kookRuntimeStateToken).endpoints.set(config.
|
|
40
|
-
|
|
39
|
+
context.use(kookRuntimeStateToken).endpoints.set(config.id, {
|
|
40
|
+
id: config.id,
|
|
41
41
|
mode: config.connection,
|
|
42
42
|
});
|
|
43
43
|
if (config.connection === 'webhook') {
|
package/lib/endpoint.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EndpointInstance, EndpointManagement } from '@zhin.js/adapter';
|
|
1
|
+
import type { EndpointInstance, EndpointManagement, EndpointSendRequest } 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';
|
|
@@ -18,10 +18,7 @@ export declare class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
18
18
|
open(): void;
|
|
19
19
|
close(): void;
|
|
20
20
|
stop(): Promise<void>;
|
|
21
|
-
send({
|
|
22
|
-
readonly target: string;
|
|
23
|
-
readonly payload: unknown;
|
|
24
|
-
}): Promise<string>;
|
|
21
|
+
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
25
22
|
/** Test / internal: admit a message when open. */
|
|
26
23
|
admit(msg: KookInboundMessage): void;
|
|
27
24
|
recallMessage(messageId: string): Promise<void>;
|
|
@@ -61,10 +58,7 @@ export declare class KookWebhookEndpoint implements EndpointInstance {
|
|
|
61
58
|
open(): void;
|
|
62
59
|
close(): void;
|
|
63
60
|
stop(): Promise<void>;
|
|
64
|
-
send({
|
|
65
|
-
readonly target: string;
|
|
66
|
-
readonly payload: unknown;
|
|
67
|
-
}): Promise<string>;
|
|
61
|
+
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
68
62
|
/** Test / internal: admit a message when open. */
|
|
69
63
|
admit(msg: KookInboundMessage): void;
|
|
70
64
|
recallMessage(messageId: string): Promise<void>;
|
package/lib/endpoint.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { formatCompact,
|
|
1
|
+
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
2
2
|
import { registerKookAgentEndpoint } from './kook-agent-deps.js';
|
|
3
|
-
import { formatInboundContent,
|
|
3
|
+
import { formatInboundContent, formatOutboundKmarkdown, isKookBotMentioned, kookInboundConversation, senderDisplayName, } from './protocol.js';
|
|
4
4
|
import { registerKookWebhookRoutes } from './webhook.js';
|
|
5
5
|
import { defaultCreateClient, defaultCreateWebhookClient, normalizeKookMessage, } from './ws.js';
|
|
6
|
-
const logger = getLogger('kook');
|
|
7
6
|
export class KookWebsocketEndpoint {
|
|
7
|
+
#logger;
|
|
8
8
|
#options;
|
|
9
9
|
#createClient;
|
|
10
10
|
#client = null;
|
|
@@ -13,6 +13,7 @@ export class KookWebsocketEndpoint {
|
|
|
13
13
|
#unregisterAgent;
|
|
14
14
|
management = createKookEndpointManagement(() => this.#requireClient());
|
|
15
15
|
constructor(options) {
|
|
16
|
+
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
16
17
|
this.#options = options;
|
|
17
18
|
this.#createClient = options.createClient ?? defaultCreateClient;
|
|
18
19
|
}
|
|
@@ -21,20 +22,20 @@ export class KookWebsocketEndpoint {
|
|
|
21
22
|
return;
|
|
22
23
|
this.#started = true;
|
|
23
24
|
try {
|
|
24
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.
|
|
25
|
+
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
25
26
|
this.#client = this.#createClient(this.#options.config);
|
|
26
27
|
this.#bindClient(this.#client);
|
|
27
28
|
await this.#client.connect();
|
|
28
|
-
logger.info(formatCompact({
|
|
29
|
+
this.#logger.info(formatCompact({
|
|
29
30
|
op: 'connect',
|
|
30
|
-
endpoint: this.#options.config.
|
|
31
|
+
endpoint: this.#options.config.id,
|
|
31
32
|
mode: 'websocket',
|
|
32
33
|
self_id: this.#client.self_id != null ? String(this.#client.self_id) : undefined,
|
|
33
34
|
}));
|
|
34
35
|
}
|
|
35
36
|
catch (error) {
|
|
36
37
|
await this.stop();
|
|
37
|
-
logger.error('Failed to connect KOOK websocket:', error);
|
|
38
|
+
this.#logger.error('Failed to connect KOOK websocket:', error);
|
|
38
39
|
throw error;
|
|
39
40
|
}
|
|
40
41
|
}
|
|
@@ -59,20 +60,19 @@ export class KookWebsocketEndpoint {
|
|
|
59
60
|
this.#client = null;
|
|
60
61
|
}
|
|
61
62
|
this.#started = false;
|
|
62
|
-
logger.debug(formatCompact({ op: 'disconnect'
|
|
63
|
+
this.#logger.debug(formatCompact({ op: 'disconnect' }));
|
|
63
64
|
}
|
|
64
|
-
async send({
|
|
65
|
+
async send({ conversation, payload }) {
|
|
65
66
|
const body = formatOutboundKmarkdown(payload);
|
|
66
|
-
const parsed = parseSendTarget(target);
|
|
67
67
|
const client = this.#requireClient();
|
|
68
|
-
const result =
|
|
69
|
-
? await client.sendPrivateMsg(
|
|
70
|
-
: await client.sendChannelMsg(
|
|
68
|
+
const result = conversation.kind === 'private'
|
|
69
|
+
? await client.sendPrivateMsg(conversation.id, body)
|
|
70
|
+
: await client.sendChannelMsg(conversation.id, body);
|
|
71
71
|
const messageId = result?.msg_id != null ? String(result.msg_id) : '';
|
|
72
|
-
logger.debug(formatCompact({
|
|
72
|
+
this.#logger.debug(formatCompact({
|
|
73
73
|
op: 'kook_send',
|
|
74
|
-
endpoint: this.#options.config.
|
|
75
|
-
target
|
|
74
|
+
endpoint: this.#options.config.id,
|
|
75
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
76
76
|
messageId,
|
|
77
77
|
}));
|
|
78
78
|
return messageId;
|
|
@@ -83,26 +83,29 @@ export class KookWebsocketEndpoint {
|
|
|
83
83
|
return;
|
|
84
84
|
if (msg.authorBot)
|
|
85
85
|
return;
|
|
86
|
-
const
|
|
86
|
+
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
87
87
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
88
88
|
void this.#options.gateway.receive({
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
conversation,
|
|
90
|
+
message: { conversation, id: msg.id },
|
|
91
91
|
content: formatInboundContent(msg),
|
|
92
|
-
sender:
|
|
93
|
-
|
|
92
|
+
sender: {
|
|
93
|
+
id: msg.authorId,
|
|
94
|
+
name: senderDisplayName(msg) || undefined,
|
|
95
|
+
...(msg.authorRoles?.length ? { roles: msg.authorRoles.map(String) } : {}),
|
|
96
|
+
},
|
|
97
|
+
endpointId: this.#options.config.id,
|
|
98
|
+
...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
|
|
94
99
|
metadata: Object.freeze({
|
|
95
|
-
endpoint: this.#options.config.name,
|
|
96
100
|
channelKind: msg.channelKind,
|
|
97
101
|
userId: msg.authorId,
|
|
98
102
|
guildId: msg.guildId,
|
|
99
103
|
roles: msg.authorRoles,
|
|
100
|
-
...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
|
|
101
104
|
}),
|
|
102
105
|
}).catch((err) => {
|
|
103
|
-
logger.warn(formatCompact({
|
|
106
|
+
this.#logger.warn(formatCompact({
|
|
104
107
|
op: 'kook_gateway_receive_failed',
|
|
105
|
-
target
|
|
108
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
106
109
|
error: err instanceof Error ? err.message : String(err),
|
|
107
110
|
}));
|
|
108
111
|
});
|
|
@@ -148,6 +151,7 @@ export class KookWebsocketEndpoint {
|
|
|
148
151
|
}
|
|
149
152
|
}
|
|
150
153
|
export class KookWebhookEndpoint {
|
|
154
|
+
#logger;
|
|
151
155
|
#options;
|
|
152
156
|
#createClient;
|
|
153
157
|
#client = null;
|
|
@@ -158,6 +162,7 @@ export class KookWebhookEndpoint {
|
|
|
158
162
|
#unregisterAgent;
|
|
159
163
|
management = createKookEndpointManagement(() => this.#requireClient());
|
|
160
164
|
constructor(options) {
|
|
165
|
+
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
161
166
|
this.#options = options;
|
|
162
167
|
this.#createClient = options.createClient ?? defaultCreateWebhookClient;
|
|
163
168
|
}
|
|
@@ -176,13 +181,13 @@ export class KookWebhookEndpoint {
|
|
|
176
181
|
return;
|
|
177
182
|
this.#started = true;
|
|
178
183
|
try {
|
|
179
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.
|
|
184
|
+
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
180
185
|
this.#client = this.#createClient(this.#options.config);
|
|
181
186
|
await this.#client.init();
|
|
182
187
|
this.#routeReleases.push(...registerKookWebhookRoutes(this.#options.http, this));
|
|
183
|
-
logger.info(formatCompact({
|
|
188
|
+
this.#logger.info(formatCompact({
|
|
184
189
|
op: 'connect',
|
|
185
|
-
endpoint: this.#options.config.
|
|
190
|
+
endpoint: this.#options.config.id,
|
|
186
191
|
mode: 'webhook',
|
|
187
192
|
path: this.#options.config.webhookPath,
|
|
188
193
|
self_id: this.#client.self_id != null ? String(this.#client.self_id) : undefined,
|
|
@@ -190,7 +195,7 @@ export class KookWebhookEndpoint {
|
|
|
190
195
|
}
|
|
191
196
|
catch (error) {
|
|
192
197
|
await this.stop();
|
|
193
|
-
logger.error('Failed to connect KOOK webhook:', error);
|
|
198
|
+
this.#logger.error('Failed to connect KOOK webhook:', error);
|
|
194
199
|
throw error;
|
|
195
200
|
}
|
|
196
201
|
}
|
|
@@ -218,20 +223,19 @@ export class KookWebhookEndpoint {
|
|
|
218
223
|
this.#client = null;
|
|
219
224
|
}
|
|
220
225
|
this.#started = false;
|
|
221
|
-
logger.debug(formatCompact({ op: 'disconnect'
|
|
226
|
+
this.#logger.debug(formatCompact({ op: 'disconnect' }));
|
|
222
227
|
}
|
|
223
|
-
async send({
|
|
228
|
+
async send({ conversation, payload }) {
|
|
224
229
|
const body = formatOutboundKmarkdown(payload);
|
|
225
|
-
const parsed = parseSendTarget(target);
|
|
226
230
|
const client = this.#requireClient();
|
|
227
|
-
const result =
|
|
228
|
-
? await client.sendPrivateMsg(
|
|
229
|
-
: await client.sendChannelMsg(
|
|
231
|
+
const result = conversation.kind === 'private'
|
|
232
|
+
? await client.sendPrivateMsg(conversation.id, body)
|
|
233
|
+
: await client.sendChannelMsg(conversation.id, body);
|
|
230
234
|
const messageId = result?.msg_id != null ? String(result.msg_id) : '';
|
|
231
|
-
logger.debug(formatCompact({
|
|
235
|
+
this.#logger.debug(formatCompact({
|
|
232
236
|
op: 'kook_send',
|
|
233
|
-
endpoint: this.#options.config.
|
|
234
|
-
target
|
|
237
|
+
endpoint: this.#options.config.id,
|
|
238
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
235
239
|
messageId,
|
|
236
240
|
}));
|
|
237
241
|
return messageId;
|
|
@@ -242,26 +246,29 @@ export class KookWebhookEndpoint {
|
|
|
242
246
|
return;
|
|
243
247
|
if (msg.authorBot)
|
|
244
248
|
return;
|
|
245
|
-
const
|
|
249
|
+
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
246
250
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
247
251
|
void this.#options.gateway.receive({
|
|
248
|
-
|
|
249
|
-
|
|
252
|
+
conversation,
|
|
253
|
+
message: { conversation, id: msg.id },
|
|
250
254
|
content: formatInboundContent(msg),
|
|
251
|
-
sender:
|
|
252
|
-
|
|
255
|
+
sender: {
|
|
256
|
+
id: msg.authorId,
|
|
257
|
+
name: senderDisplayName(msg) || undefined,
|
|
258
|
+
...(msg.authorRoles?.length ? { roles: msg.authorRoles.map(String) } : {}),
|
|
259
|
+
},
|
|
260
|
+
endpointId: this.#options.config.id,
|
|
261
|
+
...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
|
|
253
262
|
metadata: Object.freeze({
|
|
254
|
-
endpoint: this.#options.config.name,
|
|
255
263
|
channelKind: msg.channelKind,
|
|
256
264
|
userId: msg.authorId,
|
|
257
265
|
guildId: msg.guildId,
|
|
258
266
|
roles: msg.authorRoles,
|
|
259
|
-
...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
|
|
260
267
|
}),
|
|
261
268
|
}).catch((err) => {
|
|
262
|
-
logger.warn(formatCompact({
|
|
269
|
+
this.#logger.warn(formatCompact({
|
|
263
270
|
op: 'kook_gateway_receive_failed',
|
|
264
|
-
target
|
|
271
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
265
272
|
error: err instanceof Error ? err.message : String(err),
|
|
266
273
|
}));
|
|
267
274
|
});
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { formatInboundContent,
|
|
1
|
+
export { formatInboundContent, formatOutboundKmarkdown, resolveKookConfig, senderDisplayName, KookPermission, type KookAdapterConfig, type KookInboundMessage, type KookWireSegment, type LogLevel, type ResolvedKookConfig, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig, } from './protocol.js';
|
|
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
5
|
export { getKookAgentDeps, registerKookAgentEndpoint, setKookAgentDeps, type KookAgentDeps, type KookAgentEndpoint, } from './kook-agent-deps.js';
|
|
6
|
-
export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit,
|
|
6
|
+
export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit, type KookSenderInfo, } from './platform-permit.js';
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { formatInboundContent,
|
|
1
|
+
export { formatInboundContent, formatOutboundKmarkdown, resolveKookConfig, senderDisplayName, KookPermission, } from './protocol.js';
|
|
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
5
|
export { getKookAgentDeps, registerKookAgentEndpoint, setKookAgentDeps, } from './kook-agent-deps.js';
|
|
6
|
-
export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit,
|
|
6
|
+
export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit, } from './platform-permit.js';
|
package/lib/kook-agent-deps.d.ts
CHANGED
|
@@ -21,9 +21,9 @@ export interface KookAgentEndpoint {
|
|
|
21
21
|
removeFromBlacklist(guildId: string, userId: string): Promise<boolean>;
|
|
22
22
|
}
|
|
23
23
|
export interface KookAgentDeps {
|
|
24
|
-
getEndpoint: (
|
|
24
|
+
getEndpoint: (endpointKey: string) => KookAgentEndpoint;
|
|
25
25
|
}
|
|
26
|
-
export declare function registerKookAgentEndpoint(
|
|
26
|
+
export declare function registerKookAgentEndpoint(endpointKey: string, endpoint: KookAgentEndpoint): () => void;
|
|
27
27
|
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
28
28
|
export declare function setKookAgentDeps(deps: KookAgentDeps | null): void;
|
|
29
29
|
export declare function getKookAgentDeps(): KookAgentDeps;
|
package/lib/kook-agent-deps.js
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
const endpoints = new Map();
|
|
6
6
|
let override = null;
|
|
7
|
-
export function registerKookAgentEndpoint(
|
|
8
|
-
endpoints.set(
|
|
7
|
+
export function registerKookAgentEndpoint(endpointKey, endpoint) {
|
|
8
|
+
endpoints.set(endpointKey, endpoint);
|
|
9
9
|
return () => {
|
|
10
|
-
if (endpoints.get(
|
|
11
|
-
endpoints.delete(
|
|
10
|
+
if (endpoints.get(endpointKey) === endpoint) {
|
|
11
|
+
endpoints.delete(endpointKey);
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
14
|
}
|
|
@@ -20,10 +20,10 @@ export function getKookAgentDeps() {
|
|
|
20
20
|
if (override)
|
|
21
21
|
return override;
|
|
22
22
|
return {
|
|
23
|
-
getEndpoint(
|
|
24
|
-
const registered = endpoints.get(
|
|
23
|
+
getEndpoint(endpointKey) {
|
|
24
|
+
const registered = endpoints.get(endpointKey);
|
|
25
25
|
if (!registered)
|
|
26
|
-
throw new Error(`Endpoint ${
|
|
26
|
+
throw new Error(`Endpoint ${endpointKey} 不存在`);
|
|
27
27
|
return registered;
|
|
28
28
|
},
|
|
29
29
|
};
|
package/lib/platform-permit.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* KOOK platform permit — guild / channel 差异化门禁
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import type { PermissionSubject } from '@zhin.js/permission';
|
|
5
5
|
import { KookPermission } from './protocol.js';
|
|
6
6
|
export declare function platformPermit(perm: string): string;
|
|
7
7
|
export declare function kookGroupPermitResolver(logicalPerm: string): string;
|
|
@@ -19,5 +19,4 @@ export declare function normalizeKookSenderForPermit(info: KookSenderInfo, isCha
|
|
|
19
19
|
role?: string;
|
|
20
20
|
permissions?: string[];
|
|
21
21
|
};
|
|
22
|
-
export declare function checkKookPlatformPermit(perm: string,
|
|
23
|
-
export declare function registerKookPlatformPermitChecker(): () => void;
|
|
22
|
+
export declare function checkKookPlatformPermit(perm: string, subject: PermissionSubject): boolean;
|
package/lib/platform-permit.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* KOOK platform permit — guild / channel 差异化门禁
|
|
3
|
-
*/
|
|
4
|
-
import { registerPlatformPermitChecker } from '@zhin.js/core';
|
|
5
1
|
import { KookPermission } from './protocol.js';
|
|
6
2
|
const ADAPTER = 'kook';
|
|
7
3
|
export function platformPermit(perm) {
|
|
@@ -33,19 +29,9 @@ export function normalizeKookSenderForPermit(info, isChannel) {
|
|
|
33
29
|
}
|
|
34
30
|
return { role: 'member', permissions };
|
|
35
31
|
}
|
|
36
|
-
function
|
|
37
|
-
const
|
|
38
|
-
const permissions =
|
|
39
|
-
if (sender.isGuildOwner)
|
|
40
|
-
permissions.push('guild_owner');
|
|
41
|
-
if (sender.isAdmin)
|
|
42
|
-
permissions.push('guild_admin');
|
|
43
|
-
if (sender.permission === KookPermission.ChannelAdmin)
|
|
44
|
-
permissions.push('channel_admin');
|
|
45
|
-
return { role: sender.role, permissions };
|
|
46
|
-
}
|
|
47
|
-
export function checkKookPlatformPermit(perm, message) {
|
|
48
|
-
const { role, permissions } = senderPermits(message);
|
|
32
|
+
export function checkKookPlatformPermit(perm, subject) {
|
|
33
|
+
const role = subject.sender?.role?.[0];
|
|
34
|
+
const permissions = subject.sender?.permissions ?? [];
|
|
49
35
|
const has = (t) => permissions.includes(t);
|
|
50
36
|
switch (perm) {
|
|
51
37
|
case 'guild_owner':
|
|
@@ -60,6 +46,3 @@ export function checkKookPlatformPermit(perm, message) {
|
|
|
60
46
|
return false;
|
|
61
47
|
}
|
|
62
48
|
}
|
|
63
|
-
export function registerKookPlatformPermitChecker() {
|
|
64
|
-
return registerPlatformPermitChecker(ADAPTER, checkKookPlatformPermit);
|
|
65
|
-
}
|
package/lib/protocol.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
4
4
|
*/
|
|
5
5
|
import type { IncomingMessage } from 'node:http';
|
|
6
|
+
import type { ConversationRef } from '@zhin.js/im-contract';
|
|
6
7
|
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'mark' | 'off';
|
|
7
8
|
export declare enum KookPermission {
|
|
8
9
|
Normal = 1,
|
|
@@ -12,7 +13,7 @@ export declare enum KookPermission {
|
|
|
12
13
|
}
|
|
13
14
|
/** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
|
|
14
15
|
export interface KookAdapterConfig {
|
|
15
|
-
readonly
|
|
16
|
+
readonly id?: string;
|
|
16
17
|
readonly token?: string;
|
|
17
18
|
/** Default `websocket`. `webhook` requires httpHostToken + verify_token. */
|
|
18
19
|
readonly connection?: 'websocket' | 'webhook';
|
|
@@ -27,7 +28,7 @@ export interface KookAdapterConfig {
|
|
|
27
28
|
/** Transitional: legacy root `endpoints[]` with `context: kook`. */
|
|
28
29
|
readonly endpoints?: ReadonlyArray<{
|
|
29
30
|
readonly context?: string;
|
|
30
|
-
readonly
|
|
31
|
+
readonly id?: string;
|
|
31
32
|
readonly token?: string;
|
|
32
33
|
readonly connection?: 'websocket' | 'webhook';
|
|
33
34
|
readonly webhookPath?: string;
|
|
@@ -43,7 +44,7 @@ export interface KookAdapterConfig {
|
|
|
43
44
|
export interface ResolvedKookWebsocketConfig {
|
|
44
45
|
readonly context: 'kook';
|
|
45
46
|
readonly connection: 'websocket';
|
|
46
|
-
readonly
|
|
47
|
+
readonly id: string;
|
|
47
48
|
readonly token: string;
|
|
48
49
|
readonly data_dir?: string;
|
|
49
50
|
readonly timeout: number;
|
|
@@ -54,7 +55,7 @@ export interface ResolvedKookWebsocketConfig {
|
|
|
54
55
|
export interface ResolvedKookWebhookConfig {
|
|
55
56
|
readonly context: 'kook';
|
|
56
57
|
readonly connection: 'webhook';
|
|
57
|
-
readonly
|
|
58
|
+
readonly id: string;
|
|
58
59
|
readonly token: string;
|
|
59
60
|
readonly webhookPath: string;
|
|
60
61
|
readonly verifyToken: string;
|
|
@@ -106,16 +107,12 @@ export interface KookWireSegment {
|
|
|
106
107
|
readonly type: string;
|
|
107
108
|
readonly data?: Record<string, unknown>;
|
|
108
109
|
}
|
|
109
|
-
export interface ParsedSendTarget {
|
|
110
|
-
readonly kind: 'private' | 'channel';
|
|
111
|
-
readonly id: string;
|
|
112
|
-
}
|
|
113
110
|
export declare function resolveKookConfig(config?: KookAdapterConfig): ResolvedKookConfig;
|
|
114
111
|
/**
|
|
115
|
-
*
|
|
112
|
+
* 入站归一化 → ConversationRef:频道消息的所属 guild 进 `parent`(guild 容器
|
|
113
|
+
* 映射为 channel 容器);私聊(PERSON)无容器,直接 kind 'private'。
|
|
116
114
|
*/
|
|
117
|
-
export declare function
|
|
118
|
-
export declare function parseSendTarget(target: string): ParsedSendTarget;
|
|
115
|
+
export declare function kookInboundConversation(endpointKey: string, msg: KookInboundMessage): ConversationRef;
|
|
119
116
|
export declare function senderDisplayName(msg: KookInboundMessage): string;
|
|
120
117
|
/** Build inbound text for MessageGateway.receive */
|
|
121
118
|
export declare function formatInboundContent(msg: KookInboundMessage): string;
|
package/lib/protocol.js
CHANGED
|
@@ -21,8 +21,8 @@ export function resolveKookConfig(config = {}) {
|
|
|
21
21
|
if (!token) {
|
|
22
22
|
throw new TypeError('KOOK adapter requires token (plugins.<key>.token or endpoints with context: kook)');
|
|
23
23
|
}
|
|
24
|
-
const
|
|
25
|
-
|| (typeof entry?.
|
|
24
|
+
const id = (typeof config.id === 'string' && config.id)
|
|
25
|
+
|| (typeof entry?.id === 'string' && entry.id)
|
|
26
26
|
|| process.env.KOOK_BOT_NAME
|
|
27
27
|
|| 'kook-bot';
|
|
28
28
|
const connection = config.connection
|
|
@@ -40,7 +40,7 @@ export function resolveKookConfig(config = {}) {
|
|
|
40
40
|
return {
|
|
41
41
|
context: 'kook',
|
|
42
42
|
connection: 'webhook',
|
|
43
|
-
|
|
43
|
+
id,
|
|
44
44
|
token,
|
|
45
45
|
webhookPath: normalizeWebhookPath(config.webhookPath ?? entry?.webhookPath ?? process.env.KOOK_WEBHOOK_PATH ?? '/kook/webhook'),
|
|
46
46
|
verifyToken,
|
|
@@ -52,7 +52,7 @@ export function resolveKookConfig(config = {}) {
|
|
|
52
52
|
return {
|
|
53
53
|
context: 'kook',
|
|
54
54
|
connection: 'websocket',
|
|
55
|
-
|
|
55
|
+
id,
|
|
56
56
|
token,
|
|
57
57
|
data_dir: config.data_dir ?? entry?.data_dir,
|
|
58
58
|
timeout: config.timeout ?? entry?.timeout ?? 10_000,
|
|
@@ -62,23 +62,18 @@ export function resolveKookConfig(config = {}) {
|
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
|
-
*
|
|
65
|
+
* 入站归一化 → ConversationRef:频道消息的所属 guild 进 `parent`(guild 容器
|
|
66
|
+
* 映射为 channel 容器);私聊(PERSON)无容器,直接 kind 'private'。
|
|
66
67
|
*/
|
|
67
|
-
export function
|
|
68
|
-
return
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const rest = target.slice(sep + 1);
|
|
77
|
-
if (head === 'private')
|
|
78
|
-
return { kind: 'private', id: rest };
|
|
79
|
-
if (head === 'channel' || head === 'group')
|
|
80
|
-
return { kind: 'channel', id: rest };
|
|
81
|
-
return { kind: 'channel', id: target };
|
|
68
|
+
export function kookInboundConversation(endpointKey, msg) {
|
|
69
|
+
return {
|
|
70
|
+
endpoint: { id: endpointKey, adapter: endpointKey.split('\0')[0] ?? endpointKey },
|
|
71
|
+
kind: msg.channelKind,
|
|
72
|
+
id: msg.channelId,
|
|
73
|
+
...(msg.guildId && msg.channelKind === 'channel'
|
|
74
|
+
? { parent: { kind: 'channel', id: msg.guildId } }
|
|
75
|
+
: {}),
|
|
76
|
+
};
|
|
82
77
|
}
|
|
83
78
|
export function senderDisplayName(msg) {
|
|
84
79
|
return msg.authorName || msg.authorId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-kook",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.5",
|
|
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,20 +34,22 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"kook-client": "^1.0.4",
|
|
37
|
-
"@zhin.js/adapter": "1.1.
|
|
38
|
-
"@zhin.js/command": "1.0.
|
|
39
|
-
"@zhin.js/core": "1.5.
|
|
40
|
-
"@zhin.js/host-http": "1.0.
|
|
41
|
-
"@zhin.js/
|
|
42
|
-
"@zhin.js/
|
|
37
|
+
"@zhin.js/adapter": "1.1.7",
|
|
38
|
+
"@zhin.js/command": "1.0.9",
|
|
39
|
+
"@zhin.js/core": "1.5.4",
|
|
40
|
+
"@zhin.js/host-http": "1.0.8",
|
|
41
|
+
"@zhin.js/im-contract": "1.0.3",
|
|
42
|
+
"@zhin.js/logger": "1.0.76",
|
|
43
|
+
"@zhin.js/permission": "1.0.1",
|
|
44
|
+
"@zhin.js/plugin-runtime": "1.1.5"
|
|
43
45
|
},
|
|
44
46
|
"peerDependencies": {
|
|
45
47
|
"zod": "^4.0.0",
|
|
46
|
-
"@zhin.js/adapter": "1.1.
|
|
47
|
-
"@zhin.js/agent": "1.1.
|
|
48
|
-
"@zhin.js/core": "1.5.
|
|
49
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
50
|
-
"zhin.js": "6.0.
|
|
48
|
+
"@zhin.js/adapter": "1.1.7",
|
|
49
|
+
"@zhin.js/agent": "1.1.5",
|
|
50
|
+
"@zhin.js/core": "1.5.4",
|
|
51
|
+
"@zhin.js/plugin-runtime": "1.1.5",
|
|
52
|
+
"zhin.js": "6.0.4"
|
|
51
53
|
},
|
|
52
54
|
"peerDependenciesMeta": {
|
|
53
55
|
"zhin.js": {
|
|
@@ -65,9 +67,9 @@
|
|
|
65
67
|
"typescript": "^6.0.3",
|
|
66
68
|
"vitest": "^4.1.10",
|
|
67
69
|
"zod": "^4.4.3",
|
|
68
|
-
"@zhin.js/agent": "1.1.
|
|
69
|
-
"@zhin.js/host-http": "1.0.
|
|
70
|
-
"zhin.js": "6.0.
|
|
70
|
+
"@zhin.js/agent": "1.1.5",
|
|
71
|
+
"@zhin.js/host-http": "1.0.8",
|
|
72
|
+
"zhin.js": "6.0.4"
|
|
71
73
|
},
|
|
72
74
|
"files": [
|
|
73
75
|
"adapters",
|
package/plugin.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { createEndpointRuntimeState } from '@zhin.js/adapter';
|
|
3
3
|
import { definePlugin } from '@zhin.js/plugin-runtime';
|
|
4
|
-
import {
|
|
4
|
+
import { permissionHostToken } from '@zhin.js/permission';
|
|
5
|
+
import { checkKookPlatformPermit } from "./lib/platform-permit.js";
|
|
5
6
|
import { kookRuntimeStateToken } from "./lib/kook-runtime-state.js";
|
|
6
7
|
export default definePlugin({
|
|
7
8
|
name: 'kook',
|
|
@@ -9,9 +10,10 @@ export default definePlugin({
|
|
|
9
10
|
displayName: 'KOOK WebSocket Adapter',
|
|
10
11
|
},
|
|
11
12
|
setup(context) {
|
|
12
|
-
// 运行中 endpoint 注册表(kook.endpoint list 的"运行中"数据源)
|
|
13
13
|
context.resources.provide(kookRuntimeStateToken, createEndpointRuntimeState());
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
if (context.resources.has(permissionHostToken)) {
|
|
15
|
+
const host = context.resources.use(permissionHostToken);
|
|
16
|
+
return host.registerPlatform('kook', checkKookPlatformPermit);
|
|
17
|
+
}
|
|
16
18
|
},
|
|
17
19
|
});
|
package/schema.json
CHANGED
|
@@ -50,16 +50,48 @@
|
|
|
50
50
|
],
|
|
51
51
|
"default": "info"
|
|
52
52
|
},
|
|
53
|
+
"master": {
|
|
54
|
+
"type": [
|
|
55
|
+
"string",
|
|
56
|
+
"number"
|
|
57
|
+
],
|
|
58
|
+
"description": "框架 master(KOOK user id;AI/工具权限、endpoint 管理)。endpoints[i].master 可逐项覆盖"
|
|
59
|
+
},
|
|
60
|
+
"trusted": {
|
|
61
|
+
"type": "array",
|
|
62
|
+
"items": {
|
|
63
|
+
"type": [
|
|
64
|
+
"string",
|
|
65
|
+
"number"
|
|
66
|
+
],
|
|
67
|
+
"description": "Trusted KOOK user id"
|
|
68
|
+
},
|
|
69
|
+
"description": "框架 trusted 用户列表(弱于 master)。endpoints[i].trusted 可逐项追加"
|
|
70
|
+
},
|
|
53
71
|
"endpoints": {
|
|
54
72
|
"type": "array",
|
|
55
|
-
"description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(
|
|
73
|
+
"description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(id 必填,其余覆盖顶层)",
|
|
56
74
|
"items": {
|
|
57
75
|
"type": "object",
|
|
58
76
|
"additionalProperties": true,
|
|
59
77
|
"properties": {
|
|
60
|
-
"
|
|
61
|
-
"type":
|
|
62
|
-
|
|
78
|
+
"master": {
|
|
79
|
+
"type": [
|
|
80
|
+
"string",
|
|
81
|
+
"number"
|
|
82
|
+
],
|
|
83
|
+
"description": "本 endpoint 的框架 master(KOOK user id);覆盖顶层 master"
|
|
84
|
+
},
|
|
85
|
+
"trusted": {
|
|
86
|
+
"type": "array",
|
|
87
|
+
"items": {
|
|
88
|
+
"type": [
|
|
89
|
+
"string",
|
|
90
|
+
"number"
|
|
91
|
+
],
|
|
92
|
+
"description": "Trusted KOOK user id"
|
|
93
|
+
},
|
|
94
|
+
"description": "本 endpoint 的 trusted 列表"
|
|
63
95
|
},
|
|
64
96
|
"token": {
|
|
65
97
|
"type": "string",
|
|
@@ -72,10 +104,14 @@
|
|
|
72
104
|
"encrypt_key": {
|
|
73
105
|
"type": "string",
|
|
74
106
|
"description": "Optional Encrypt Key when message encryption is enabled in KOOK console."
|
|
107
|
+
},
|
|
108
|
+
"id": {
|
|
109
|
+
"type": "string",
|
|
110
|
+
"description": "KOOK bot name"
|
|
75
111
|
}
|
|
76
112
|
},
|
|
77
113
|
"required": [
|
|
78
|
-
"
|
|
114
|
+
"id",
|
|
79
115
|
"token"
|
|
80
116
|
]
|
|
81
117
|
}
|
package/src/endpoint.ts
CHANGED
|
@@ -7,18 +7,18 @@ import type {
|
|
|
7
7
|
EndpointGroup,
|
|
8
8
|
EndpointInstance,
|
|
9
9
|
EndpointManagement,
|
|
10
|
+
EndpointSendRequest,
|
|
10
11
|
} from '@zhin.js/adapter';
|
|
11
12
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
12
13
|
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
13
|
-
import { formatCompact,
|
|
14
|
+
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
14
15
|
import type { CapabilityId } from '@zhin.js/plugin-runtime';
|
|
15
16
|
import { registerKookAgentEndpoint } from './kook-agent-deps.js';
|
|
16
17
|
import {
|
|
17
18
|
formatInboundContent,
|
|
18
|
-
formatInboundTarget,
|
|
19
19
|
formatOutboundKmarkdown,
|
|
20
20
|
isKookBotMentioned,
|
|
21
|
-
|
|
21
|
+
kookInboundConversation,
|
|
22
22
|
senderDisplayName,
|
|
23
23
|
type KookInboundMessage,
|
|
24
24
|
type ResolvedKookWebhookConfig,
|
|
@@ -33,8 +33,6 @@ import {
|
|
|
33
33
|
type KookClientTransport,
|
|
34
34
|
} from './ws.js';
|
|
35
35
|
|
|
36
|
-
const logger = getLogger('kook');
|
|
37
|
-
|
|
38
36
|
export interface KookEndpointOptions {
|
|
39
37
|
readonly id: CapabilityId;
|
|
40
38
|
readonly gateway: MessageGateway;
|
|
@@ -43,6 +41,8 @@ export interface KookEndpointOptions {
|
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
export class KookWebsocketEndpoint implements EndpointInstance {
|
|
44
|
+
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
45
|
+
|
|
46
46
|
readonly #options: KookEndpointOptions;
|
|
47
47
|
readonly #createClient: CreateKookClient;
|
|
48
48
|
#client: KookClientTransport | null = null;
|
|
@@ -52,6 +52,7 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
52
52
|
readonly management: EndpointManagement = createKookEndpointManagement(() => this.#requireClient());
|
|
53
53
|
|
|
54
54
|
constructor(options: KookEndpointOptions) {
|
|
55
|
+
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
55
56
|
this.#options = options;
|
|
56
57
|
this.#createClient = options.createClient ?? (defaultCreateClient as CreateKookClient);
|
|
57
58
|
}
|
|
@@ -60,19 +61,19 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
60
61
|
if (this.#started) return;
|
|
61
62
|
this.#started = true;
|
|
62
63
|
try {
|
|
63
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.
|
|
64
|
+
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
64
65
|
this.#client = this.#createClient(this.#options.config);
|
|
65
66
|
this.#bindClient(this.#client);
|
|
66
67
|
await this.#client.connect();
|
|
67
|
-
logger.info(formatCompact({
|
|
68
|
+
this.#logger.info(formatCompact({
|
|
68
69
|
op: 'connect',
|
|
69
|
-
endpoint: this.#options.config.
|
|
70
|
+
endpoint: this.#options.config.id,
|
|
70
71
|
mode: 'websocket',
|
|
71
72
|
self_id: this.#client.self_id != null ? String(this.#client.self_id) : undefined,
|
|
72
73
|
}));
|
|
73
74
|
} catch (error) {
|
|
74
75
|
await this.stop();
|
|
75
|
-
logger.error('Failed to connect KOOK websocket:', error);
|
|
76
|
+
this.#logger.error('Failed to connect KOOK websocket:', error);
|
|
76
77
|
throw error;
|
|
77
78
|
}
|
|
78
79
|
}
|
|
@@ -99,21 +100,20 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
99
100
|
this.#client = null;
|
|
100
101
|
}
|
|
101
102
|
this.#started = false;
|
|
102
|
-
logger.debug(formatCompact({ op: 'disconnect'
|
|
103
|
+
this.#logger.debug(formatCompact({ op: 'disconnect' }));
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
async send({
|
|
106
|
+
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
106
107
|
const body = formatOutboundKmarkdown(payload);
|
|
107
|
-
const parsed = parseSendTarget(target);
|
|
108
108
|
const client = this.#requireClient();
|
|
109
|
-
const result =
|
|
110
|
-
? await client.sendPrivateMsg(
|
|
111
|
-
: await client.sendChannelMsg(
|
|
109
|
+
const result = conversation.kind === 'private'
|
|
110
|
+
? await client.sendPrivateMsg(conversation.id, body)
|
|
111
|
+
: await client.sendChannelMsg(conversation.id, body);
|
|
112
112
|
const messageId = result?.msg_id != null ? String(result.msg_id) : '';
|
|
113
|
-
logger.debug(formatCompact({
|
|
113
|
+
this.#logger.debug(formatCompact({
|
|
114
114
|
op: 'kook_send',
|
|
115
|
-
endpoint: this.#options.config.
|
|
116
|
-
target
|
|
115
|
+
endpoint: this.#options.config.id,
|
|
116
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
117
117
|
messageId,
|
|
118
118
|
}));
|
|
119
119
|
return messageId;
|
|
@@ -123,26 +123,29 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
123
123
|
admit(msg: KookInboundMessage): void {
|
|
124
124
|
if (!this.#open) return;
|
|
125
125
|
if (msg.authorBot) return;
|
|
126
|
-
const
|
|
126
|
+
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
127
127
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
128
128
|
void this.#options.gateway.receive({
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
conversation,
|
|
130
|
+
message: { conversation, id: msg.id },
|
|
131
131
|
content: formatInboundContent(msg),
|
|
132
|
-
sender:
|
|
133
|
-
|
|
132
|
+
sender: {
|
|
133
|
+
id: msg.authorId,
|
|
134
|
+
name: senderDisplayName(msg) || undefined,
|
|
135
|
+
...(msg.authorRoles?.length ? { roles: msg.authorRoles.map(String) } : {}),
|
|
136
|
+
},
|
|
137
|
+
endpointId: this.#options.config.id,
|
|
138
|
+
...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
|
|
134
139
|
metadata: Object.freeze({
|
|
135
|
-
endpoint: this.#options.config.name,
|
|
136
140
|
channelKind: msg.channelKind,
|
|
137
141
|
userId: msg.authorId,
|
|
138
142
|
guildId: msg.guildId,
|
|
139
143
|
roles: msg.authorRoles,
|
|
140
|
-
...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
|
|
141
144
|
}),
|
|
142
145
|
}).catch((err) => {
|
|
143
|
-
logger.warn(formatCompact({
|
|
146
|
+
this.#logger.warn(formatCompact({
|
|
144
147
|
op: 'kook_gateway_receive_failed',
|
|
145
|
-
target
|
|
148
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
146
149
|
error: err instanceof Error ? err.message : String(err),
|
|
147
150
|
}));
|
|
148
151
|
});
|
|
@@ -205,6 +208,8 @@ export interface KookWebhookEndpointOptions {
|
|
|
205
208
|
}
|
|
206
209
|
|
|
207
210
|
export class KookWebhookEndpoint implements EndpointInstance {
|
|
211
|
+
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
212
|
+
|
|
208
213
|
readonly #options: KookWebhookEndpointOptions;
|
|
209
214
|
readonly #createClient: CreateKookClient;
|
|
210
215
|
#client: KookClientTransport | null = null;
|
|
@@ -216,6 +221,7 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
216
221
|
readonly management: EndpointManagement = createKookEndpointManagement(() => this.#requireClient());
|
|
217
222
|
|
|
218
223
|
constructor(options: KookWebhookEndpointOptions) {
|
|
224
|
+
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
219
225
|
this.#options = options;
|
|
220
226
|
this.#createClient = options.createClient ?? (defaultCreateWebhookClient as CreateKookClient);
|
|
221
227
|
}
|
|
@@ -237,20 +243,20 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
237
243
|
if (this.#started) return;
|
|
238
244
|
this.#started = true;
|
|
239
245
|
try {
|
|
240
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.
|
|
246
|
+
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
241
247
|
this.#client = this.#createClient(this.#options.config);
|
|
242
248
|
await (this.#client as Client).init();
|
|
243
249
|
this.#routeReleases.push(...registerKookWebhookRoutes(this.#options.http, this));
|
|
244
|
-
logger.info(formatCompact({
|
|
250
|
+
this.#logger.info(formatCompact({
|
|
245
251
|
op: 'connect',
|
|
246
|
-
endpoint: this.#options.config.
|
|
252
|
+
endpoint: this.#options.config.id,
|
|
247
253
|
mode: 'webhook',
|
|
248
254
|
path: this.#options.config.webhookPath,
|
|
249
255
|
self_id: this.#client.self_id != null ? String(this.#client.self_id) : undefined,
|
|
250
256
|
}));
|
|
251
257
|
} catch (error) {
|
|
252
258
|
await this.stop();
|
|
253
|
-
logger.error('Failed to connect KOOK webhook:', error);
|
|
259
|
+
this.#logger.error('Failed to connect KOOK webhook:', error);
|
|
254
260
|
throw error;
|
|
255
261
|
}
|
|
256
262
|
}
|
|
@@ -279,21 +285,20 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
279
285
|
this.#client = null;
|
|
280
286
|
}
|
|
281
287
|
this.#started = false;
|
|
282
|
-
logger.debug(formatCompact({ op: 'disconnect'
|
|
288
|
+
this.#logger.debug(formatCompact({ op: 'disconnect' }));
|
|
283
289
|
}
|
|
284
290
|
|
|
285
|
-
async send({
|
|
291
|
+
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
286
292
|
const body = formatOutboundKmarkdown(payload);
|
|
287
|
-
const parsed = parseSendTarget(target);
|
|
288
293
|
const client = this.#requireClient();
|
|
289
|
-
const result =
|
|
290
|
-
? await client.sendPrivateMsg(
|
|
291
|
-
: await client.sendChannelMsg(
|
|
294
|
+
const result = conversation.kind === 'private'
|
|
295
|
+
? await client.sendPrivateMsg(conversation.id, body)
|
|
296
|
+
: await client.sendChannelMsg(conversation.id, body);
|
|
292
297
|
const messageId = result?.msg_id != null ? String(result.msg_id) : '';
|
|
293
|
-
logger.debug(formatCompact({
|
|
298
|
+
this.#logger.debug(formatCompact({
|
|
294
299
|
op: 'kook_send',
|
|
295
|
-
endpoint: this.#options.config.
|
|
296
|
-
target
|
|
300
|
+
endpoint: this.#options.config.id,
|
|
301
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
297
302
|
messageId,
|
|
298
303
|
}));
|
|
299
304
|
return messageId;
|
|
@@ -303,26 +308,29 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
303
308
|
admit(msg: KookInboundMessage): void {
|
|
304
309
|
if (!this.#open) return;
|
|
305
310
|
if (msg.authorBot) return;
|
|
306
|
-
const
|
|
311
|
+
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
307
312
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
308
313
|
void this.#options.gateway.receive({
|
|
309
|
-
|
|
310
|
-
|
|
314
|
+
conversation,
|
|
315
|
+
message: { conversation, id: msg.id },
|
|
311
316
|
content: formatInboundContent(msg),
|
|
312
|
-
sender:
|
|
313
|
-
|
|
317
|
+
sender: {
|
|
318
|
+
id: msg.authorId,
|
|
319
|
+
name: senderDisplayName(msg) || undefined,
|
|
320
|
+
...(msg.authorRoles?.length ? { roles: msg.authorRoles.map(String) } : {}),
|
|
321
|
+
},
|
|
322
|
+
endpointId: this.#options.config.id,
|
|
323
|
+
...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
|
|
314
324
|
metadata: Object.freeze({
|
|
315
|
-
endpoint: this.#options.config.name,
|
|
316
325
|
channelKind: msg.channelKind,
|
|
317
326
|
userId: msg.authorId,
|
|
318
327
|
guildId: msg.guildId,
|
|
319
328
|
roles: msg.authorRoles,
|
|
320
|
-
...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
|
|
321
329
|
}),
|
|
322
330
|
}).catch((err) => {
|
|
323
|
-
logger.warn(formatCompact({
|
|
331
|
+
this.#logger.warn(formatCompact({
|
|
324
332
|
op: 'kook_gateway_receive_failed',
|
|
325
|
-
target
|
|
333
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
326
334
|
error: err instanceof Error ? err.message : String(err),
|
|
327
335
|
}));
|
|
328
336
|
});
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export {
|
|
2
2
|
formatInboundContent,
|
|
3
|
-
formatInboundTarget,
|
|
4
3
|
formatOutboundKmarkdown,
|
|
5
|
-
parseSendTarget,
|
|
6
4
|
resolveKookConfig,
|
|
7
5
|
senderDisplayName,
|
|
8
6
|
KookPermission,
|
|
@@ -10,7 +8,6 @@ export {
|
|
|
10
8
|
type KookInboundMessage,
|
|
11
9
|
type KookWireSegment,
|
|
12
10
|
type LogLevel,
|
|
13
|
-
type ParsedSendTarget,
|
|
14
11
|
type ResolvedKookConfig,
|
|
15
12
|
type ResolvedKookWebhookConfig,
|
|
16
13
|
type ResolvedKookWebsocketConfig,
|
|
@@ -50,6 +47,5 @@ export {
|
|
|
50
47
|
kookGroupPermitResolver,
|
|
51
48
|
normalizeKookSenderForPermit,
|
|
52
49
|
platformPermit,
|
|
53
|
-
registerKookPlatformPermitChecker,
|
|
54
50
|
type KookSenderInfo,
|
|
55
51
|
} from './platform-permit.js';
|
package/src/kook-agent-deps.ts
CHANGED
|
@@ -20,20 +20,20 @@ export interface KookAgentEndpoint {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export interface KookAgentDeps {
|
|
23
|
-
getEndpoint: (
|
|
23
|
+
getEndpoint: (endpointKey: string) => KookAgentEndpoint;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
const endpoints = new Map<string, KookAgentEndpoint>();
|
|
27
27
|
let override: KookAgentDeps | null = null;
|
|
28
28
|
|
|
29
29
|
export function registerKookAgentEndpoint(
|
|
30
|
-
|
|
30
|
+
endpointKey: string,
|
|
31
31
|
endpoint: KookAgentEndpoint,
|
|
32
32
|
): () => void {
|
|
33
|
-
endpoints.set(
|
|
33
|
+
endpoints.set(endpointKey, endpoint);
|
|
34
34
|
return () => {
|
|
35
|
-
if (endpoints.get(
|
|
36
|
-
endpoints.delete(
|
|
35
|
+
if (endpoints.get(endpointKey) === endpoint) {
|
|
36
|
+
endpoints.delete(endpointKey);
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
}
|
|
@@ -46,9 +46,9 @@ export function setKookAgentDeps(deps: KookAgentDeps | null): void {
|
|
|
46
46
|
export function getKookAgentDeps(): KookAgentDeps {
|
|
47
47
|
if (override) return override;
|
|
48
48
|
return {
|
|
49
|
-
getEndpoint(
|
|
50
|
-
const registered = endpoints.get(
|
|
51
|
-
if (!registered) throw new Error(`Endpoint ${
|
|
49
|
+
getEndpoint(endpointKey: string): KookAgentEndpoint {
|
|
50
|
+
const registered = endpoints.get(endpointKey);
|
|
51
|
+
if (!registered) throw new Error(`Endpoint ${endpointKey} 不存在`);
|
|
52
52
|
return registered;
|
|
53
53
|
},
|
|
54
54
|
};
|
package/src/platform-permit.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* KOOK platform permit — guild / channel 差异化门禁
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import type { PermissionSubject } from '@zhin.js/permission';
|
|
5
5
|
import { KookPermission } from './protocol.js';
|
|
6
6
|
|
|
7
7
|
const ADAPTER = 'kook';
|
|
@@ -54,17 +54,9 @@ export function normalizeKookSenderForPermit(
|
|
|
54
54
|
return { role: 'member', permissions };
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
function
|
|
58
|
-
const
|
|
59
|
-
const permissions =
|
|
60
|
-
if (sender.isGuildOwner) permissions.push('guild_owner');
|
|
61
|
-
if (sender.isAdmin) permissions.push('guild_admin');
|
|
62
|
-
if (sender.permission === KookPermission.ChannelAdmin) permissions.push('channel_admin');
|
|
63
|
-
return { role: sender.role, permissions };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function checkKookPlatformPermit(perm: string, message: Message<any>): boolean {
|
|
67
|
-
const { role, permissions } = senderPermits(message);
|
|
57
|
+
export function checkKookPlatformPermit(perm: string, subject: PermissionSubject): boolean {
|
|
58
|
+
const role = subject.sender?.role?.[0];
|
|
59
|
+
const permissions = subject.sender?.permissions ?? [];
|
|
68
60
|
const has = (t: string) => permissions.includes(t);
|
|
69
61
|
|
|
70
62
|
switch (perm) {
|
|
@@ -81,6 +73,3 @@ export function checkKookPlatformPermit(perm: string, message: Message<any>): bo
|
|
|
81
73
|
}
|
|
82
74
|
}
|
|
83
75
|
|
|
84
|
-
export function registerKookPlatformPermitChecker(): () => void {
|
|
85
|
-
return registerPlatformPermitChecker(ADAPTER, checkKookPlatformPermit);
|
|
86
|
-
}
|
package/src/protocol.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { inflateSync } from 'node:zlib';
|
|
|
8
8
|
import type { IncomingMessage } from 'node:http';
|
|
9
9
|
import { pickCredential } from '@zhin.js/adapter';
|
|
10
10
|
import { isMediaRef } from '@zhin.js/core';
|
|
11
|
+
import type { ConversationRef } from '@zhin.js/im-contract';
|
|
11
12
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
12
13
|
|
|
13
14
|
const logger = getLogger('kook');
|
|
@@ -31,7 +32,7 @@ export enum KookPermission {
|
|
|
31
32
|
|
|
32
33
|
/** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
|
|
33
34
|
export interface KookAdapterConfig {
|
|
34
|
-
readonly
|
|
35
|
+
readonly id?: string;
|
|
35
36
|
readonly token?: string;
|
|
36
37
|
/** Default `websocket`. `webhook` requires httpHostToken + verify_token. */
|
|
37
38
|
readonly connection?: 'websocket' | 'webhook';
|
|
@@ -46,7 +47,7 @@ export interface KookAdapterConfig {
|
|
|
46
47
|
/** Transitional: legacy root `endpoints[]` with `context: kook`. */
|
|
47
48
|
readonly endpoints?: ReadonlyArray<{
|
|
48
49
|
readonly context?: string;
|
|
49
|
-
readonly
|
|
50
|
+
readonly id?: string;
|
|
50
51
|
readonly token?: string;
|
|
51
52
|
readonly connection?: 'websocket' | 'webhook';
|
|
52
53
|
readonly webhookPath?: string;
|
|
@@ -63,7 +64,7 @@ export interface KookAdapterConfig {
|
|
|
63
64
|
export interface ResolvedKookWebsocketConfig {
|
|
64
65
|
readonly context: 'kook';
|
|
65
66
|
readonly connection: 'websocket';
|
|
66
|
-
readonly
|
|
67
|
+
readonly id: string;
|
|
67
68
|
readonly token: string;
|
|
68
69
|
readonly data_dir?: string;
|
|
69
70
|
readonly timeout: number;
|
|
@@ -75,7 +76,7 @@ export interface ResolvedKookWebsocketConfig {
|
|
|
75
76
|
export interface ResolvedKookWebhookConfig {
|
|
76
77
|
readonly context: 'kook';
|
|
77
78
|
readonly connection: 'webhook';
|
|
78
|
-
readonly
|
|
79
|
+
readonly id: string;
|
|
79
80
|
readonly token: string;
|
|
80
81
|
readonly webhookPath: string;
|
|
81
82
|
readonly verifyToken: string;
|
|
@@ -133,11 +134,6 @@ export interface KookWireSegment {
|
|
|
133
134
|
readonly data?: Record<string, unknown>;
|
|
134
135
|
}
|
|
135
136
|
|
|
136
|
-
export interface ParsedSendTarget {
|
|
137
|
-
readonly kind: 'private' | 'channel';
|
|
138
|
-
readonly id: string;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
137
|
export function resolveKookConfig(config: KookAdapterConfig = {}): ResolvedKookConfig {
|
|
142
138
|
const entry = config.endpoints?.find((item) => item.context === 'kook' || !item.context);
|
|
143
139
|
const token = pickCredential(config.token, entry?.token, process.env.KOOK_TOKEN, process.env.KOOK_BOT_TOKEN);
|
|
@@ -146,8 +142,8 @@ export function resolveKookConfig(config: KookAdapterConfig = {}): ResolvedKookC
|
|
|
146
142
|
'KOOK adapter requires token (plugins.<key>.token or endpoints with context: kook)',
|
|
147
143
|
);
|
|
148
144
|
}
|
|
149
|
-
const
|
|
150
|
-
|| (typeof entry?.
|
|
145
|
+
const id = (typeof config.id === 'string' && config.id)
|
|
146
|
+
|| (typeof entry?.id === 'string' && entry.id)
|
|
151
147
|
|| process.env.KOOK_BOT_NAME
|
|
152
148
|
|| 'kook-bot';
|
|
153
149
|
const connection = config.connection
|
|
@@ -168,7 +164,7 @@ export function resolveKookConfig(config: KookAdapterConfig = {}): ResolvedKookC
|
|
|
168
164
|
return {
|
|
169
165
|
context: 'kook',
|
|
170
166
|
connection: 'webhook',
|
|
171
|
-
|
|
167
|
+
id,
|
|
172
168
|
token,
|
|
173
169
|
webhookPath: normalizeWebhookPath(
|
|
174
170
|
config.webhookPath ?? entry?.webhookPath ?? process.env.KOOK_WEBHOOK_PATH ?? '/kook/webhook',
|
|
@@ -183,7 +179,7 @@ export function resolveKookConfig(config: KookAdapterConfig = {}): ResolvedKookC
|
|
|
183
179
|
return {
|
|
184
180
|
context: 'kook',
|
|
185
181
|
connection: 'websocket',
|
|
186
|
-
|
|
182
|
+
id,
|
|
187
183
|
token,
|
|
188
184
|
data_dir: config.data_dir ?? entry?.data_dir,
|
|
189
185
|
timeout: config.timeout ?? entry?.timeout ?? 10_000,
|
|
@@ -194,22 +190,18 @@ export function resolveKookConfig(config: KookAdapterConfig = {}): ResolvedKookC
|
|
|
194
190
|
}
|
|
195
191
|
|
|
196
192
|
/**
|
|
197
|
-
*
|
|
193
|
+
* 入站归一化 → ConversationRef:频道消息的所属 guild 进 `parent`(guild 容器
|
|
194
|
+
* 映射为 channel 容器);私聊(PERSON)无容器,直接 kind 'private'。
|
|
198
195
|
*/
|
|
199
|
-
export function
|
|
200
|
-
return
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
const head = target.slice(0, sep);
|
|
209
|
-
const rest = target.slice(sep + 1);
|
|
210
|
-
if (head === 'private') return { kind: 'private', id: rest };
|
|
211
|
-
if (head === 'channel' || head === 'group') return { kind: 'channel', id: rest };
|
|
212
|
-
return { kind: 'channel', id: target };
|
|
196
|
+
export function kookInboundConversation(endpointKey: string, msg: KookInboundMessage): ConversationRef {
|
|
197
|
+
return {
|
|
198
|
+
endpoint: { id: endpointKey, adapter: endpointKey.split('\0')[0] ?? endpointKey },
|
|
199
|
+
kind: msg.channelKind,
|
|
200
|
+
id: msg.channelId,
|
|
201
|
+
...(msg.guildId && msg.channelKind === 'channel'
|
|
202
|
+
? { parent: { kind: 'channel' as const, id: msg.guildId } }
|
|
203
|
+
: {}),
|
|
204
|
+
};
|
|
213
205
|
}
|
|
214
206
|
|
|
215
207
|
export function senderDisplayName(msg: KookInboundMessage): string {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|