@zhin.js/adapter-kook 8.0.0 → 8.0.2
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 +30 -0
- package/README.md +11 -2
- package/adapters/kook.js +0 -7
- package/adapters/kook.ts +0 -7
- package/agent/tools/blacklist.ts +6 -8
- package/agent/tools/create_role.ts +5 -7
- package/agent/tools/delete_role.ts +5 -7
- package/agent/tools/grant_role.ts +5 -7
- package/agent/tools/list_roles.ts +5 -7
- package/agent/tools/revoke_role.ts +5 -7
- package/lib/client.d.ts +11 -0
- package/lib/client.js +2 -0
- package/lib/endpoint.d.ts +9 -42
- package/lib/endpoint.js +44 -59
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/kook-endpoint-commands.d.ts +1 -1
- package/lib/protocol.d.ts +1 -1
- package/lib/protocol.js +1 -1
- package/lib/side-event-dispatch.d.ts +2 -2
- package/lib/side-event-dispatch.js +2 -4
- package/lib/webhook.d.ts +2 -3
- package/lib/webhook.js +2 -11
- package/package.json +15 -14
- package/src/client.ts +15 -0
- package/src/endpoint.ts +52 -79
- package/src/index.ts +1 -7
- package/src/protocol.ts +1 -1
- package/src/side-event-dispatch.ts +3 -4
- package/src/webhook.ts +2 -10
- package/lib/kook-agent-deps.d.ts +0 -29
- package/lib/kook-agent-deps.js +0 -30
- package/src/kook-agent-deps.ts +0 -55
|
@@ -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": "8.0.
|
|
3
|
+
"version": "8.0.2",
|
|
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.2.
|
|
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.2.
|
|
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.17",
|
|
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.17",
|
|
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,3 +1,4 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* KookEndpoint — lifecycle, outbound, admit, OpenAPI helpers for agent tools.
|
|
3
4
|
*/
|
|
@@ -7,22 +8,21 @@ import {
|
|
|
7
8
|
type EndpointControl,
|
|
8
9
|
type EndpointChannel,
|
|
9
10
|
type EndpointGroup,
|
|
10
|
-
type EndpointInstance,
|
|
11
11
|
type EndpointManagement,
|
|
12
12
|
type EndpointSendRequest,
|
|
13
13
|
} from 'zhin.js/adapter';
|
|
14
|
-
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
15
14
|
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
16
15
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
17
16
|
import type { CapabilityId } from 'zhin.js';
|
|
18
|
-
import { registerKookAgentEndpoint } from './kook-agent-deps.js';
|
|
19
17
|
import {
|
|
20
18
|
formatInboundContent,
|
|
21
19
|
formatOutboundKmarkdown,
|
|
22
20
|
isKookBotMentioned,
|
|
23
21
|
kookInboundConversation,
|
|
22
|
+
normalizeKookWebhookEvent,
|
|
24
23
|
senderDisplayName,
|
|
25
24
|
type KookInboundMessage,
|
|
25
|
+
type KookWebhookEventData,
|
|
26
26
|
type ResolvedKookWebhookConfig,
|
|
27
27
|
type ResolvedKookWebsocketConfig,
|
|
28
28
|
} from './protocol.js';
|
|
@@ -38,13 +38,11 @@ import { receiveKookSideEvent } from './side-event-dispatch.js';
|
|
|
38
38
|
|
|
39
39
|
export interface KookEndpointOptions {
|
|
40
40
|
readonly id: CapabilityId;
|
|
41
|
-
readonly gateway: MessageGateway;
|
|
42
|
-
readonly sideEvents?: SideEventGateway;
|
|
43
41
|
readonly config: ResolvedKookWebsocketConfig;
|
|
44
42
|
readonly createClient?: CreateKookClient;
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
export class KookWebsocketEndpoint
|
|
45
|
+
export class KookWebsocketEndpoint extends Endpoint<KookClientTransport> {
|
|
48
46
|
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
49
47
|
|
|
50
48
|
readonly #options: KookEndpointOptions;
|
|
@@ -52,21 +50,24 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
52
50
|
#client: KookClientTransport | null = null;
|
|
53
51
|
#open = false;
|
|
54
52
|
#started = false;
|
|
55
|
-
#unregisterAgent?: () => void;
|
|
56
53
|
readonly management: EndpointManagement = createKookEndpointManagement(() => this.#requireClient());
|
|
57
54
|
readonly control: EndpointControl = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
58
55
|
|
|
59
56
|
constructor(options: KookEndpointOptions) {
|
|
57
|
+
super();
|
|
60
58
|
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
61
59
|
this.#options = options;
|
|
62
60
|
this.#createClient = options.createClient ?? (defaultCreateClient as CreateKookClient);
|
|
63
61
|
}
|
|
64
62
|
|
|
63
|
+
get client(): KookClientTransport {
|
|
64
|
+
return this.#requireClient();
|
|
65
|
+
}
|
|
66
|
+
|
|
65
67
|
async start(): Promise<void> {
|
|
66
68
|
if (this.#started) return;
|
|
67
69
|
this.#started = true;
|
|
68
70
|
try {
|
|
69
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
70
71
|
this.#client = this.#createClient(this.#options.config);
|
|
71
72
|
this.#bindClient(this.#client);
|
|
72
73
|
await this.#client.connect();
|
|
@@ -93,8 +94,6 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
93
94
|
|
|
94
95
|
async stop(): Promise<void> {
|
|
95
96
|
this.#open = false;
|
|
96
|
-
this.#unregisterAgent?.();
|
|
97
|
-
this.#unregisterAgent = undefined;
|
|
98
97
|
if (this.#client) {
|
|
99
98
|
try {
|
|
100
99
|
this.#client.removeAllListeners();
|
|
@@ -124,13 +123,13 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
124
123
|
return messageId;
|
|
125
124
|
}
|
|
126
125
|
|
|
127
|
-
/** Test / internal: admit a message when open. */
|
|
126
|
+
/** Test / internal: admit a normalized message when open. */
|
|
128
127
|
admit(msg: KookInboundMessage): void {
|
|
129
128
|
if (!this.#open) return;
|
|
130
129
|
if (msg.authorBot) return;
|
|
131
130
|
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
132
131
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
133
|
-
void this
|
|
132
|
+
void this.emit('message.receive', {
|
|
134
133
|
conversation,
|
|
135
134
|
message: { conversation, id: msg.id },
|
|
136
135
|
content: formatInboundContent(msg),
|
|
@@ -161,44 +160,26 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
161
160
|
await this.#requireClient().recallMsg?.(messageId);
|
|
162
161
|
}
|
|
163
162
|
|
|
164
|
-
// ── Agent tool surface ──────────────────────────────────────────────
|
|
165
|
-
|
|
166
|
-
async getRoleList(guildId: string) {
|
|
167
|
-
return this.#requireClient().pickGuild(guildId).getRoleList();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async createRole(guildId: string, name: string) {
|
|
171
|
-
return this.#requireClient().pickGuild(guildId).createRole(name);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async deleteRole(guildId: string, roleId: string) {
|
|
175
|
-
return this.#requireClient().pickGuild(guildId).deleteRole(roleId);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async grantRole(guildId: string, userId: string, roleId: string) {
|
|
179
|
-
return this.#requireClient().pickGuildMember(guildId, userId).grant(roleId);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
async revokeRole(guildId: string, userId: string, roleId: string) {
|
|
183
|
-
return this.#requireClient().pickGuildMember(guildId, userId).revoke(roleId);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async addToBlacklist(guildId: string, userId: string, remark?: string) {
|
|
187
|
-
return this.#requireClient().pickGuildMember(guildId, userId).addToBlackList(remark);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async removeFromBlacklist(guildId: string, userId: string) {
|
|
191
|
-
return this.#requireClient().pickGuildMember(guildId, userId).removeFromBlackList();
|
|
192
|
-
}
|
|
193
|
-
|
|
194
163
|
#bindClient(client: KookClientTransport): void {
|
|
195
164
|
client.on('message', (raw) => {
|
|
165
|
+
this.#emitPlatformEvent('message', raw);
|
|
196
166
|
const msg = normalizeKookMessage(raw);
|
|
197
167
|
if (msg) this.admit(msg);
|
|
198
168
|
});
|
|
199
169
|
const receiver = (client as { receiver?: { on(event: string, listener: (...args: unknown[]) => void): void } }).receiver;
|
|
200
170
|
receiver?.on('event', (raw) => {
|
|
201
|
-
|
|
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
|
+
}));
|
|
202
183
|
});
|
|
203
184
|
}
|
|
204
185
|
|
|
@@ -210,14 +191,12 @@ export class KookWebsocketEndpoint implements EndpointInstance {
|
|
|
210
191
|
|
|
211
192
|
export interface KookWebhookEndpointOptions {
|
|
212
193
|
readonly id: CapabilityId;
|
|
213
|
-
readonly gateway: MessageGateway;
|
|
214
|
-
readonly sideEvents?: SideEventGateway;
|
|
215
194
|
readonly http: HttpHost;
|
|
216
195
|
readonly config: ResolvedKookWebhookConfig;
|
|
217
196
|
readonly createClient?: CreateKookClient;
|
|
218
197
|
}
|
|
219
198
|
|
|
220
|
-
export class KookWebhookEndpoint
|
|
199
|
+
export class KookWebhookEndpoint extends Endpoint<KookClientTransport> {
|
|
221
200
|
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
222
201
|
|
|
223
202
|
readonly #options: KookWebhookEndpointOptions;
|
|
@@ -227,16 +206,20 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
227
206
|
#processedSn = new Set<number>();
|
|
228
207
|
#open = false;
|
|
229
208
|
#started = false;
|
|
230
|
-
#unregisterAgent?: () => void;
|
|
231
209
|
readonly management: EndpointManagement = createKookEndpointManagement(() => this.#requireClient());
|
|
232
210
|
readonly control: EndpointControl = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
233
211
|
|
|
234
212
|
constructor(options: KookWebhookEndpointOptions) {
|
|
213
|
+
super();
|
|
235
214
|
this.#logger = getAdapterLogger('kook', options.config.id);
|
|
236
215
|
this.#options = options;
|
|
237
216
|
this.#createClient = options.createClient ?? (defaultCreateWebhookClient as CreateKookClient);
|
|
238
217
|
}
|
|
239
218
|
|
|
219
|
+
get client(): KookClientTransport {
|
|
220
|
+
return this.#requireClient();
|
|
221
|
+
}
|
|
222
|
+
|
|
240
223
|
/** Used by webhook handler. */
|
|
241
224
|
get isOpen(): boolean {
|
|
242
225
|
return this.#open;
|
|
@@ -254,7 +237,6 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
254
237
|
if (this.#started) return;
|
|
255
238
|
this.#started = true;
|
|
256
239
|
try {
|
|
257
|
-
this.#unregisterAgent = registerKookAgentEndpoint(this.#options.config.id, this);
|
|
258
240
|
this.#client = this.#createClient(this.#options.config);
|
|
259
241
|
await (this.#client as Client).init();
|
|
260
242
|
this.#routeReleases.push(...registerKookWebhookRoutes(this.#options.http, this));
|
|
@@ -283,8 +265,6 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
283
265
|
async stop(): Promise<void> {
|
|
284
266
|
this.#open = false;
|
|
285
267
|
for (const release of this.#routeReleases.splice(0)) release();
|
|
286
|
-
this.#unregisterAgent?.();
|
|
287
|
-
this.#unregisterAgent = undefined;
|
|
288
268
|
this.#processedSn.clear();
|
|
289
269
|
if (this.#client) {
|
|
290
270
|
try {
|
|
@@ -315,13 +295,34 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
315
295
|
return messageId;
|
|
316
296
|
}
|
|
317
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
|
+
|
|
318
319
|
/** Test / internal: admit a message when open. */
|
|
319
320
|
admit(msg: KookInboundMessage): void {
|
|
320
321
|
if (!this.#open) return;
|
|
321
322
|
if (msg.authorBot) return;
|
|
322
323
|
const conversation = kookInboundConversation(String(this.#options.id), msg);
|
|
323
324
|
const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
|
|
324
|
-
void this
|
|
325
|
+
void this.emit('message.receive', {
|
|
325
326
|
conversation,
|
|
326
327
|
message: { conversation, id: msg.id },
|
|
327
328
|
content: formatInboundContent(msg),
|
|
@@ -362,34 +363,6 @@ export class KookWebhookEndpoint implements EndpointInstance {
|
|
|
362
363
|
return true;
|
|
363
364
|
}
|
|
364
365
|
|
|
365
|
-
async getRoleList(guildId: string) {
|
|
366
|
-
return this.#requireClient().pickGuild(guildId).getRoleList();
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
async createRole(guildId: string, name: string) {
|
|
370
|
-
return this.#requireClient().pickGuild(guildId).createRole(name);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
async deleteRole(guildId: string, roleId: string) {
|
|
374
|
-
return this.#requireClient().pickGuild(guildId).deleteRole(roleId);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
async grantRole(guildId: string, userId: string, roleId: string) {
|
|
378
|
-
return this.#requireClient().pickGuildMember(guildId, userId).grant(roleId);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
async revokeRole(guildId: string, userId: string, roleId: string) {
|
|
382
|
-
return this.#requireClient().pickGuildMember(guildId, userId).revoke(roleId);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
async addToBlacklist(guildId: string, userId: string, remark?: string) {
|
|
386
|
-
return this.#requireClient().pickGuildMember(guildId, userId).addToBlackList(remark);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
async removeFromBlacklist(guildId: string, userId: string) {
|
|
390
|
-
return this.#requireClient().pickGuildMember(guildId, userId).removeFromBlackList();
|
|
391
|
-
}
|
|
392
|
-
|
|
393
366
|
#requireClient(): KookClientTransport {
|
|
394
367
|
if (!this.#client) throw new Error('KOOK client not initialized');
|
|
395
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
|
-
}
|