@zhin.js/adapter-kook 7.0.14 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +11 -2
- package/adapters/kook.js +1 -7
- package/adapters/kook.ts +1 -7
- package/agent/tools/blacklist.ts +6 -8
- package/agent/tools/create_role.ts +5 -7
- package/agent/tools/delete_role.ts +5 -7
- package/agent/tools/grant_role.ts +5 -7
- package/agent/tools/list_roles.ts +5 -7
- package/agent/tools/revoke_role.ts +5 -7
- package/lib/client.d.ts +11 -0
- package/lib/client.js +2 -0
- package/lib/endpoint.d.ts +11 -42
- package/lib/endpoint.js +47 -59
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/kook-endpoint-commands.d.ts +1 -1
- package/lib/protocol.d.ts +1 -1
- package/lib/protocol.js +1 -1
- package/lib/side-event-dispatch.d.ts +2 -2
- package/lib/side-event-dispatch.js +2 -4
- package/lib/webhook.d.ts +2 -3
- package/lib/webhook.js +2 -11
- package/package.json +15 -14
- package/src/client.ts +15 -0
- package/src/endpoint.ts +61 -84
- package/src/index.ts +1 -7
- package/src/protocol.ts +1 -1
- package/src/side-event-dispatch.ts +3 -4
- package/src/webhook.ts +2 -10
- package/lib/kook-agent-deps.d.ts +0 -29
- package/lib/kook-agent-deps.js +0 -30
- package/src/kook-agent-deps.ts +0 -55
package/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>>>;
|
package/lib/protocol.d.ts
CHANGED
|
@@ -114,7 +114,7 @@ export declare function resolveKookConfig(config?: KookAdapterConfig): ResolvedK
|
|
|
114
114
|
*/
|
|
115
115
|
export declare function kookInboundConversation(endpointKey: string, msg: KookInboundMessage): ConversationRef;
|
|
116
116
|
export declare function senderDisplayName(msg: KookInboundMessage): string;
|
|
117
|
-
/** Build inbound text for
|
|
117
|
+
/** Build inbound text for OutboundMessageService.receive */
|
|
118
118
|
export declare function formatInboundContent(msg: KookInboundMessage): string;
|
|
119
119
|
/**
|
|
120
120
|
* KOOK @ 用户标记为 `(met)<userId>(met)`;content 含 `(met)<botId>(met)` 时视为 @ 机器人。
|
package/lib/protocol.js
CHANGED
|
@@ -78,7 +78,7 @@ export function kookInboundConversation(endpointKey, msg) {
|
|
|
78
78
|
export function senderDisplayName(msg) {
|
|
79
79
|
return msg.authorName || msg.authorId;
|
|
80
80
|
}
|
|
81
|
-
/** Build inbound text for
|
|
81
|
+
/** Build inbound text for OutboundMessageService.receive */
|
|
82
82
|
export function formatInboundContent(msg) {
|
|
83
83
|
const text = (msg.content || msg.rawMessage || '').trim();
|
|
84
84
|
return text || '(Empty message)';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EndpointEventEmitter } from 'zhin.js/adapter';
|
|
2
2
|
import { type getAdapterLogger } from '@zhin.js/logger';
|
|
3
|
-
export declare function receiveKookSideEvent(
|
|
3
|
+
export declare function receiveKookSideEvent(emit: EndpointEventEmitter, configId: string, raw: unknown, logger: ReturnType<typeof getAdapterLogger>): boolean;
|
|
@@ -12,9 +12,7 @@ function extractKookNoticeType(raw) {
|
|
|
12
12
|
}
|
|
13
13
|
return null;
|
|
14
14
|
}
|
|
15
|
-
export function receiveKookSideEvent(
|
|
16
|
-
if (!sideEvents)
|
|
17
|
-
return false;
|
|
15
|
+
export function receiveKookSideEvent(emit, configId, raw, logger) {
|
|
18
16
|
const noticeType = extractKookNoticeType(raw);
|
|
19
17
|
if (!noticeType)
|
|
20
18
|
return false;
|
|
@@ -29,7 +27,7 @@ export function receiveKookSideEvent(sideEvents, configId, raw, logger) {
|
|
|
29
27
|
: userId != null
|
|
30
28
|
? String(userId)
|
|
31
29
|
: configId;
|
|
32
|
-
void
|
|
30
|
+
void emit('notice.receive', buildNotice(event, {
|
|
33
31
|
$id: `kook:${noticeType}:${event.msg_timestamp ?? Date.now()}:${sceneId}:${String(userId ?? '')}`,
|
|
34
32
|
$adapter: 'kook',
|
|
35
33
|
$endpoint: configId,
|
package/lib/webhook.d.ts
CHANGED
|
@@ -3,14 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
5
5
|
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
6
|
-
import type
|
|
7
|
-
import { type KookInboundMessage, type ResolvedKookWebhookConfig } from './protocol.js';
|
|
6
|
+
import { type KookInboundMessage, type KookWebhookEventData, type ResolvedKookWebhookConfig } from './protocol.js';
|
|
8
7
|
export interface KookWebhookHandler {
|
|
9
8
|
readonly config: ResolvedKookWebhookConfig;
|
|
10
9
|
readonly isOpen: boolean;
|
|
11
10
|
readonly selfId?: string;
|
|
12
|
-
readonly sideEvents?: SideEventGateway;
|
|
13
11
|
admit(msg: KookInboundMessage): void;
|
|
12
|
+
admitEvent(event: KookWebhookEventData): void;
|
|
14
13
|
checkAndRememberSn(sn: number): boolean;
|
|
15
14
|
}
|
|
16
15
|
export declare function registerKookWebhookRoutes(http: HttpHost, handler: KookWebhookHandler): HttpRouteRegistration[];
|
package/lib/webhook.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
2
|
-
import { isKookWebhookChallenge,
|
|
3
|
-
import { receiveKookSideEvent } from './side-event-dispatch.js';
|
|
2
|
+
import { isKookWebhookChallenge, parseKookWebhookBody, readRequestBody, verifyKookWebhookToken, } from './protocol.js';
|
|
4
3
|
const logger = getLogger('kook');
|
|
5
4
|
export function registerKookWebhookRoutes(http, handler) {
|
|
6
5
|
const path = handler.config.webhookPath;
|
|
@@ -68,13 +67,5 @@ export async function handleKookWebhookRequest(request, response, handler) {
|
|
|
68
67
|
}
|
|
69
68
|
}
|
|
70
69
|
function handleKookWebhookEvent(event, handler) {
|
|
71
|
-
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const msg = normalizeKookWebhookEvent(event, {
|
|
75
|
-
ignore: handler.config.ignore,
|
|
76
|
-
selfId: handler.selfId,
|
|
77
|
-
});
|
|
78
|
-
if (msg)
|
|
79
|
-
handler.admit(msg);
|
|
70
|
+
handler.admitEvent(event);
|
|
80
71
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-kook",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.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,20 +34,21 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"kook-client": "^1.0.4",
|
|
37
|
-
"@zhin.js/adapter": "1.1
|
|
38
|
-
"@zhin.js/core": "1.5.
|
|
39
|
-
"@zhin.js/
|
|
37
|
+
"@zhin.js/adapter": "1.2.1",
|
|
38
|
+
"@zhin.js/core": "1.5.14",
|
|
39
|
+
"@zhin.js/feature-kit": "1.0.13",
|
|
40
|
+
"@zhin.js/host-http": "1.0.13",
|
|
40
41
|
"@zhin.js/im-contract": "1.0.4",
|
|
41
|
-
"@zhin.js/logger": "1.0.
|
|
42
|
-
"@zhin.js/permission": "1.0.
|
|
42
|
+
"@zhin.js/logger": "1.0.77",
|
|
43
|
+
"@zhin.js/permission": "1.0.4"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
46
|
"zod": "^4.0.0",
|
|
46
|
-
"@zhin.js/adapter": "1.1
|
|
47
|
-
"@zhin.js/agent": "1.1.
|
|
48
|
-
"@zhin.js/command": "1.0.
|
|
49
|
-
"@zhin.js/core": "1.5.
|
|
50
|
-
"zhin.js": "6.0.
|
|
47
|
+
"@zhin.js/adapter": "1.2.1",
|
|
48
|
+
"@zhin.js/agent": "1.1.16",
|
|
49
|
+
"@zhin.js/command": "1.0.16",
|
|
50
|
+
"@zhin.js/core": "1.5.14",
|
|
51
|
+
"zhin.js": "6.0.14"
|
|
51
52
|
},
|
|
52
53
|
"peerDependenciesMeta": {
|
|
53
54
|
"@zhin.js/agent": {
|
|
@@ -68,9 +69,9 @@
|
|
|
68
69
|
"typescript": "^6.0.3",
|
|
69
70
|
"vitest": "^4.1.10",
|
|
70
71
|
"zod": "^4.4.3",
|
|
71
|
-
"@zhin.js/agent": "1.1.
|
|
72
|
-
"@zhin.js/host-http": "1.0.
|
|
73
|
-
"zhin.js": "6.0.
|
|
72
|
+
"@zhin.js/agent": "1.1.16",
|
|
73
|
+
"@zhin.js/host-http": "1.0.13",
|
|
74
|
+
"zhin.js": "6.0.14"
|
|
74
75
|
},
|
|
75
76
|
"files": [
|
|
76
77
|
"adapters",
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineEndpointClient } from 'zhin.js/adapter';
|
|
2
|
+
import type { KookClientTransport } from './ws.js';
|
|
3
|
+
|
|
4
|
+
export type KookClientEventMap = Record<string, unknown>;
|
|
5
|
+
|
|
6
|
+
declare module '@zhin.js/feature-kit' {
|
|
7
|
+
interface AdapterClientRegistry {
|
|
8
|
+
readonly kook: {
|
|
9
|
+
readonly client: KookClientTransport;
|
|
10
|
+
readonly events: KookClientEventMap;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const kookClient = defineEndpointClient<KookClientTransport, KookClientEventMap>('kook');
|
package/src/endpoint.ts
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* KookEndpoint — lifecycle, outbound, admit, OpenAPI helpers for agent tools.
|
|
3
4
|
*/
|
|
4
5
|
import { Client } from 'kook-client';
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
import {
|
|
7
|
+
createRecallEndpointControl,
|
|
8
|
+
type EndpointControl,
|
|
9
|
+
type EndpointChannel,
|
|
10
|
+
type EndpointGroup,
|
|
11
|
+
type EndpointManagement,
|
|
12
|
+
type EndpointSendRequest,
|
|
11
13
|
} from 'zhin.js/adapter';
|
|
12
|
-
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
13
14
|
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
14
15
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
15
16
|
import type { CapabilityId } from 'zhin.js';
|
|
16
|
-
import { registerKookAgentEndpoint } from './kook-agent-deps.js';
|
|
17
17
|
import {
|
|
18
18
|
formatInboundContent,
|
|
19
19
|
formatOutboundKmarkdown,
|
|
20
20
|
isKookBotMentioned,
|
|
21
21
|
kookInboundConversation,
|
|
22
|
+
normalizeKookWebhookEvent,
|
|
22
23
|
senderDisplayName,
|
|
23
24
|
type KookInboundMessage,
|
|
25
|
+
type KookWebhookEventData,
|
|
24
26
|
type ResolvedKookWebhookConfig,
|
|
25
27
|
type ResolvedKookWebsocketConfig,
|
|
26
28
|
} from './protocol.js';
|
|
@@ -36,13 +38,11 @@ import { receiveKookSideEvent } from './side-event-dispatch.js';
|
|
|
36
38
|
|
|
37
39
|
export interface KookEndpointOptions {
|
|
38
40
|
readonly id: CapabilityId;
|
|
39
|
-
readonly gateway: MessageGateway;
|
|
40
|
-
readonly sideEvents?: SideEventGateway;
|
|
41
41
|
readonly config: ResolvedKookWebsocketConfig;
|
|
42
42
|
readonly createClient?: CreateKookClient;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
export class KookWebsocketEndpoint
|
|
45
|
+
export class KookWebsocketEndpoint extends Endpoint<KookClientTransport> {
|
|
46
46
|
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
47
47
|
|
|
48
48
|
readonly #options: KookEndpointOptions;
|
|
@@ -50,20 +50,24 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
50
50
|
#client: KookClientTransport | null = null;
|
|
51
51
|
#open = false;
|
|
52
52
|
#started = false;
|
|
53
|
-
#unregisterAgent?: () => void;
|
|
54
53
|
readonly management: EndpointManagement = createKookEndpointManagement(() => this.#requireClient());
|
|
54
|
+
readonly control: EndpointControl = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
55
55
|
|
|
56
56
|
constructor(options: KookEndpointOptions) {
|
|
57
|
+
super();
|
|
57
58
|
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
58
59
|
this.#options = options;
|
|
59
60
|
this.#createClient = options.createClient ?? (defaultCreateClient as CreateKookClient);
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
get client(): KookClientTransport {
|
|
64
|
+
return this.#requireClient();
|
|
65
|
+
}
|
|
66
|
+
|
|
62
67
|
async start(): Promise<void> {
|
|
63
68
|
if (this.#started) return;
|
|
64
69
|
this.#started = true;
|
|
65
70
|
try {
|
|
66
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
67
71
|
this.#client = this.#createClient(this.#options.config);
|
|
68
72
|
this.#bindClient(this.#client);
|
|
69
73
|
await this.#client.connect();
|
|
@@ -90,8 +94,6 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
90
94
|
|
|
91
95
|
async stop(): Promise<void> {
|
|
92
96
|
this.#open = false;
|
|
93
|
-
this.#unregisterAgent?.();
|
|
94
|
-
this.#unregisterAgent = undefined;
|
|
95
97
|
if (this.#client) {
|
|
96
98
|
try {
|
|
97
99
|
this.#client.removeAllListeners();
|
|
@@ -121,13 +123,13 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
121
123
|
return messageId;
|
|
122
124
|
}
|
|
123
125
|
|
|
124
|
-
/** Test / internal: admit a message when open. */
|
|
126
|
+
/** Test / internal: admit a normalized message when open. */
|
|
125
127
|
admit(msg: KookInboundMessage): void {
|
|
126
128
|
if (!this.#open) return;
|
|
127
129
|
if (msg.authorBot) return;
|
|
128
130
|
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
129
131
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
130
|
-
void this
|
|
132
|
+
void this.emit('message.receive', {
|
|
131
133
|
conversation,
|
|
132
134
|
message: { conversation, id: msg.id },
|
|
133
135
|
content: formatInboundContent(msg),
|
|
@@ -158,44 +160,26 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
158
160
|
await this.#requireClient().recallMsg?.(messageId);
|
|
159
161
|
}
|
|
160
162
|
|
|
161
|
-
// ── Agent tool surface ──────────────────────────────────────────────
|
|
162
|
-
|
|
163
|
-
async getRoleList(guildId: string) {
|
|
164
|
-
return this.#requireClient().pickGuild(guildId).getRoleList();
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
async createRole(guildId: string, name: string) {
|
|
168
|
-
return this.#requireClient().pickGuild(guildId).createRole(name);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
async deleteRole(guildId: string, roleId: string) {
|
|
172
|
-
return this.#requireClient().pickGuild(guildId).deleteRole(roleId);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
async grantRole(guildId: string, userId: string, roleId: string) {
|
|
176
|
-
return this.#requireClient().pickGuildMember(guildId, userId).grant(roleId);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async revokeRole(guildId: string, userId: string, roleId: string) {
|
|
180
|
-
return this.#requireClient().pickGuildMember(guildId, userId).revoke(roleId);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async addToBlacklist(guildId: string, userId: string, remark?: string) {
|
|
184
|
-
return this.#requireClient().pickGuildMember(guildId, userId).addToBlackList(remark);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
async removeFromBlacklist(guildId: string, userId: string) {
|
|
188
|
-
return this.#requireClient().pickGuildMember(guildId, userId).removeFromBlackList();
|
|
189
|
-
}
|
|
190
|
-
|
|
191
163
|
#bindClient(client: KookClientTransport): void {
|
|
192
164
|
client.on('message', (raw) => {
|
|
165
|
+
this.#emitPlatformEvent('message', raw);
|
|
193
166
|
const msg = normalizeKookMessage(raw);
|
|
194
167
|
if (msg) this.admit(msg);
|
|
195
168
|
});
|
|
196
169
|
const receiver = (client as { receiver?: { on(event: string, listener: (...args: unknown[]) => void): void } }).receiver;
|
|
197
170
|
receiver?.on('event', (raw) => {
|
|
198
|
-
|
|
171
|
+
this.#emitPlatformEvent('event', raw);
|
|
172
|
+
receiveKookSideEvent((name, payload) => this.emit(name, payload), this.#options.config.id, raw, this.#logger);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
#emitPlatformEvent(name: string, event: unknown): void {
|
|
177
|
+
void this.emitPlatform(name, event).catch((error) => {
|
|
178
|
+
this.#logger.warn(formatCompact({
|
|
179
|
+
op: 'kook_platform_event_failed',
|
|
180
|
+
event: name,
|
|
181
|
+
error: error instanceof Error ? error.message : String(error),
|
|
182
|
+
}));
|
|
199
183
|
});
|
|
200
184
|
}
|
|
201
185
|
|
|
@@ -207,14 +191,12 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
207
191
|
|
|
208
192
|
export interface KookWebhookEndpointOptions {
|
|
209
193
|
readonly id: CapabilityId;
|
|
210
|
-
readonly gateway: MessageGateway;
|
|
211
|
-
readonly sideEvents?: SideEventGateway;
|
|
212
194
|
readonly http: HttpHost;
|
|
213
195
|
readonly config: ResolvedKookWebhookConfig;
|
|
214
196
|
readonly createClient?: CreateKookClient;
|
|
215
197
|
}
|
|
216
198
|
|
|
217
|
-
export class KookWebhookEndpoint
|
|
199
|
+
export class KookWebhookEndpoint extends Endpoint<KookClientTransport> {
|
|
218
200
|
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
219
201
|
|
|
220
202
|
readonly #options: KookWebhookEndpointOptions;
|
|
@@ -224,15 +206,20 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
224
206
|
#processedSn = new Set<number>();
|
|
225
207
|
#open = false;
|
|
226
208
|
#started = false;
|
|
227
|
-
#unregisterAgent?: () => void;
|
|
228
209
|
readonly management: EndpointManagement = createKookEndpointManagement(() => this.#requireClient());
|
|
210
|
+
readonly control: EndpointControl = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
229
211
|
|
|
230
212
|
constructor(options: KookWebhookEndpointOptions) {
|
|
213
|
+
super();
|
|
231
214
|
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
232
215
|
this.#options = options;
|
|
233
216
|
this.#createClient = options.createClient ?? (defaultCreateWebhookClient as CreateKookClient);
|
|
234
217
|
}
|
|
235
218
|
|
|
219
|
+
get client(): KookClientTransport {
|
|
220
|
+
return this.#requireClient();
|
|
221
|
+
}
|
|
222
|
+
|
|
236
223
|
/** Used by webhook handler. */
|
|
237
224
|
get isOpen(): boolean {
|
|
238
225
|
return this.#open;
|
|
@@ -250,7 +237,6 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
250
237
|
if (this.#started) return;
|
|
251
238
|
this.#started = true;
|
|
252
239
|
try {
|
|
253
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
254
240
|
this.#client = this.#createClient(this.#options.config);
|
|
255
241
|
await (this.#client as Client).init();
|
|
256
242
|
this.#routeReleases.push(...registerKookWebhookRoutes(this.#options.http, this));
|
|
@@ -279,8 +265,6 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
279
265
|
async stop(): Promise<void> {
|
|
280
266
|
this.#open = false;
|
|
281
267
|
for (const release of this.#routeReleases.splice(0)) release();
|
|
282
|
-
this.#unregisterAgent?.();
|
|
283
|
-
this.#unregisterAgent = undefined;
|
|
284
268
|
this.#processedSn.clear();
|
|
285
269
|
if (this.#client) {
|
|
286
270
|
try {
|
|
@@ -311,13 +295,34 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
311
295
|
return messageId;
|
|
312
296
|
}
|
|
313
297
|
|
|
298
|
+
admitEvent(event: KookWebhookEventData): void {
|
|
299
|
+
void this.emitPlatform(String(event.type ?? 'event'), event).catch((error) => {
|
|
300
|
+
this.#logger.warn(formatCompact({
|
|
301
|
+
op: 'kook_platform_event_failed',
|
|
302
|
+
event: String(event.type ?? 'event'),
|
|
303
|
+
error: error instanceof Error ? error.message : String(error),
|
|
304
|
+
}));
|
|
305
|
+
});
|
|
306
|
+
if (receiveKookSideEvent(
|
|
307
|
+
(name, payload) => this.emit(name, payload),
|
|
308
|
+
this.#options.config.id,
|
|
309
|
+
event,
|
|
310
|
+
this.#logger,
|
|
311
|
+
)) return;
|
|
312
|
+
const message = normalizeKookWebhookEvent(event, {
|
|
313
|
+
ignore: this.#options.config.ignore,
|
|
314
|
+
selfId: this.selfId,
|
|
315
|
+
});
|
|
316
|
+
if (message) this.admit(message);
|
|
317
|
+
}
|
|
318
|
+
|
|
314
319
|
/** Test / internal: admit a message when open. */
|
|
315
320
|
admit(msg: KookInboundMessage): void {
|
|
316
321
|
if (!this.#open) return;
|
|
317
322
|
if (msg.authorBot) return;
|
|
318
323
|
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
319
324
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
320
|
-
void this
|
|
325
|
+
void this.emit('message.receive', {
|
|
321
326
|
conversation,
|
|
322
327
|
message: { conversation, id: msg.id },
|
|
323
328
|
content: formatInboundContent(msg),
|
|
@@ -358,34 +363,6 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
358
363
|
return true;
|
|
359
364
|
}
|
|
360
365
|
|
|
361
|
-
async getRoleList(guildId: string) {
|
|
362
|
-
return this.#requireClient().pickGuild(guildId).getRoleList();
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
async createRole(guildId: string, name: string) {
|
|
366
|
-
return this.#requireClient().pickGuild(guildId).createRole(name);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
async deleteRole(guildId: string, roleId: string) {
|
|
370
|
-
return this.#requireClient().pickGuild(guildId).deleteRole(roleId);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
async grantRole(guildId: string, userId: string, roleId: string) {
|
|
374
|
-
return this.#requireClient().pickGuildMember(guildId, userId).grant(roleId);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
async revokeRole(guildId: string, userId: string, roleId: string) {
|
|
378
|
-
return this.#requireClient().pickGuildMember(guildId, userId).revoke(roleId);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
async addToBlacklist(guildId: string, userId: string, remark?: string) {
|
|
382
|
-
return this.#requireClient().pickGuildMember(guildId, userId).addToBlackList(remark);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
async removeFromBlacklist(guildId: string, userId: string) {
|
|
386
|
-
return this.#requireClient().pickGuildMember(guildId, userId).removeFromBlackList();
|
|
387
|
-
}
|
|
388
|
-
|
|
389
366
|
#requireClient(): KookClientTransport {
|
|
390
367
|
if (!this.#client) throw new Error('KOOK client not initialized');
|
|
391
368
|
return this.#client;
|
package/src/index.ts
CHANGED
|
@@ -34,13 +34,7 @@ export {
|
|
|
34
34
|
type KookClientTransport,
|
|
35
35
|
} from './ws.js';
|
|
36
36
|
|
|
37
|
-
export {
|
|
38
|
-
getKookAgentDeps,
|
|
39
|
-
registerKookAgentEndpoint,
|
|
40
|
-
setKookAgentDeps,
|
|
41
|
-
type KookAgentDeps,
|
|
42
|
-
type KookAgentEndpoint,
|
|
43
|
-
} from './kook-agent-deps.js';
|
|
37
|
+
export { kookClient, type KookClientEventMap } from './client.js';
|
|
44
38
|
|
|
45
39
|
export {
|
|
46
40
|
checkKookPlatformPermit,
|
package/src/protocol.ts
CHANGED
|
@@ -208,7 +208,7 @@ export function senderDisplayName(msg: KookInboundMessage): string {
|
|
|
208
208
|
return msg.authorName || msg.authorId;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
/** Build inbound text for
|
|
211
|
+
/** Build inbound text for OutboundMessageService.receive */
|
|
212
212
|
export function formatInboundContent(msg: KookInboundMessage): string {
|
|
213
213
|
const text = (msg.content || msg.rawMessage || '').trim();
|
|
214
214
|
return text || '(Empty message)';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildNotice, mapNoticeParts, senderFromId, KOOK_NOTICE_PARTS_MAP } from '@zhin.js/core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { EndpointEventEmitter } from 'zhin.js/adapter';
|
|
3
3
|
import { formatCompact, type getAdapterLogger } from '@zhin.js/logger';
|
|
4
4
|
import type { KookWebhookEventData } from './protocol.js';
|
|
5
5
|
|
|
@@ -15,12 +15,11 @@ function extractKookNoticeType(raw: unknown): string | null {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function receiveKookSideEvent(
|
|
18
|
-
|
|
18
|
+
emit: EndpointEventEmitter,
|
|
19
19
|
configId: string,
|
|
20
20
|
raw: unknown,
|
|
21
21
|
logger: ReturnType<typeof getAdapterLogger>,
|
|
22
22
|
): boolean {
|
|
23
|
-
if (!sideEvents) return false;
|
|
24
23
|
const noticeType = extractKookNoticeType(raw);
|
|
25
24
|
if (!noticeType) return false;
|
|
26
25
|
if (!Object.prototype.hasOwnProperty.call(KOOK_NOTICE_PARTS_MAP, noticeType)) return false;
|
|
@@ -33,7 +32,7 @@ export function receiveKookSideEvent(
|
|
|
33
32
|
: userId != null
|
|
34
33
|
? String(userId)
|
|
35
34
|
: configId;
|
|
36
|
-
void
|
|
35
|
+
void emit('notice.receive', buildNotice(event, {
|
|
37
36
|
$id: `kook:${noticeType}:${event.msg_timestamp ?? Date.now()}:${sceneId}:${String(userId ?? '')}`,
|
|
38
37
|
$adapter: 'kook' as never,
|
|
39
38
|
$endpoint: configId,
|
package/src/webhook.ts
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
5
5
|
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
6
|
-
import type { SideEventGateway } from '@zhin.js/core/runtime';
|
|
7
6
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
8
7
|
import {
|
|
9
8
|
isKookWebhookChallenge,
|
|
@@ -24,8 +23,8 @@ export interface KookWebhookHandler {
|
|
|
24
23
|
readonly config: ResolvedKookWebhookConfig;
|
|
25
24
|
readonly isOpen: boolean;
|
|
26
25
|
readonly selfId?: string;
|
|
27
|
-
readonly sideEvents?: SideEventGateway;
|
|
28
26
|
admit(msg: KookInboundMessage): void;
|
|
27
|
+
admitEvent(event: KookWebhookEventData): void;
|
|
29
28
|
checkAndRememberSn(sn: number): boolean;
|
|
30
29
|
}
|
|
31
30
|
|
|
@@ -111,12 +110,5 @@ function handleKookWebhookEvent(
|
|
|
111
110
|
event: KookWebhookEventData,
|
|
112
111
|
handler: KookWebhookHandler,
|
|
113
112
|
): void {
|
|
114
|
-
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const msg = normalizeKookWebhookEvent(event, {
|
|
118
|
-
ignore: handler.config.ignore,
|
|
119
|
-
selfId: handler.selfId,
|
|
120
|
-
});
|
|
121
|
-
if (msg) handler.admit(msg);
|
|
113
|
+
handler.admitEvent(event);
|
|
122
114
|
}
|
package/lib/kook-agent-deps.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for kook.
|
|
3
|
-
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
export interface KookAgentEndpoint {
|
|
6
|
-
getRoleList(guildId: string): Promise<Array<{
|
|
7
|
-
role_id: string | number;
|
|
8
|
-
name: string;
|
|
9
|
-
color?: number;
|
|
10
|
-
position?: number;
|
|
11
|
-
permissions?: unknown;
|
|
12
|
-
}>>;
|
|
13
|
-
createRole(guildId: string, name: string): Promise<{
|
|
14
|
-
role_id: string | number;
|
|
15
|
-
name: string;
|
|
16
|
-
}>;
|
|
17
|
-
deleteRole(guildId: string, roleId: string): Promise<boolean>;
|
|
18
|
-
grantRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
19
|
-
revokeRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
20
|
-
addToBlacklist(guildId: string, userId: string, remark?: string): Promise<boolean>;
|
|
21
|
-
removeFromBlacklist(guildId: string, userId: string): Promise<boolean>;
|
|
22
|
-
}
|
|
23
|
-
export interface KookAgentDeps {
|
|
24
|
-
getEndpoint: (endpointKey: string) => KookAgentEndpoint;
|
|
25
|
-
}
|
|
26
|
-
export declare function registerKookAgentEndpoint(endpointKey: string, endpoint: KookAgentEndpoint): () => void;
|
|
27
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
28
|
-
export declare function setKookAgentDeps(deps: KookAgentDeps | null): void;
|
|
29
|
-
export declare function getKookAgentDeps(): KookAgentDeps;
|
package/lib/kook-agent-deps.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for kook.
|
|
3
|
-
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
const endpoints = new Map();
|
|
6
|
-
let override = null;
|
|
7
|
-
export function registerKookAgentEndpoint(endpointKey, endpoint) {
|
|
8
|
-
endpoints.set(endpointKey, endpoint);
|
|
9
|
-
return () => {
|
|
10
|
-
if (endpoints.get(endpointKey) === endpoint) {
|
|
11
|
-
endpoints.delete(endpointKey);
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
16
|
-
export function setKookAgentDeps(deps) {
|
|
17
|
-
override = deps;
|
|
18
|
-
}
|
|
19
|
-
export function getKookAgentDeps() {
|
|
20
|
-
if (override)
|
|
21
|
-
return override;
|
|
22
|
-
return {
|
|
23
|
-
getEndpoint(endpointKey) {
|
|
24
|
-
const registered = endpoints.get(endpointKey);
|
|
25
|
-
if (!registered)
|
|
26
|
-
throw new Error(`Endpoint ${endpointKey} 不存在`);
|
|
27
|
-
return registered;
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
}
|
package/src/kook-agent-deps.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for kook.
|
|
3
|
-
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface KookAgentEndpoint {
|
|
7
|
-
getRoleList(guildId: string): Promise<Array<{
|
|
8
|
-
role_id: string | number;
|
|
9
|
-
name: string;
|
|
10
|
-
color?: number;
|
|
11
|
-
position?: number;
|
|
12
|
-
permissions?: unknown;
|
|
13
|
-
}>>;
|
|
14
|
-
createRole(guildId: string, name: string): Promise<{ role_id: string | number; name: string }>;
|
|
15
|
-
deleteRole(guildId: string, roleId: string): Promise<boolean>;
|
|
16
|
-
grantRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
17
|
-
revokeRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
18
|
-
addToBlacklist(guildId: string, userId: string, remark?: string): Promise<boolean>;
|
|
19
|
-
removeFromBlacklist(guildId: string, userId: string): Promise<boolean>;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface KookAgentDeps {
|
|
23
|
-
getEndpoint: (endpointKey: string) => KookAgentEndpoint;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const endpoints = new Map<string, KookAgentEndpoint>();
|
|
27
|
-
let override: KookAgentDeps | null = null;
|
|
28
|
-
|
|
29
|
-
export function registerKookAgentEndpoint(
|
|
30
|
-
endpointKey: string,
|
|
31
|
-
endpoint: KookAgentEndpoint,
|
|
32
|
-
): () => void {
|
|
33
|
-
endpoints.set(endpointKey, endpoint);
|
|
34
|
-
return () => {
|
|
35
|
-
if (endpoints.get(endpointKey) === endpoint) {
|
|
36
|
-
endpoints.delete(endpointKey);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
42
|
-
export function setKookAgentDeps(deps: KookAgentDeps | null): void {
|
|
43
|
-
override = deps;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function getKookAgentDeps(): KookAgentDeps {
|
|
47
|
-
if (override) return override;
|
|
48
|
-
return {
|
|
49
|
-
getEndpoint(endpointKey: string): KookAgentEndpoint {
|
|
50
|
-
const registered = endpoints.get(endpointKey);
|
|
51
|
-
if (!registered) throw new Error(`Endpoint ${endpointKey} 不存在`);
|
|
52
|
-
return registered;
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
}
|