@zhin.js/adapter-napcat 6.0.2 → 6.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/napcat.js +2 -2
- package/adapters/napcat.ts +2 -2
- package/lib/http-endpoint.d.ts +2 -5
- package/lib/http-endpoint.js +26 -22
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/napcat-agent-deps.d.ts +3 -3
- package/lib/napcat-agent-deps.js +9 -9
- package/lib/protocol.d.ts +12 -6
- package/lib/protocol.js +33 -26
- package/lib/ws-endpoint.d.ts +2 -5
- package/lib/ws-endpoint.js +31 -28
- package/lib/ws-transport.d.ts +1 -1
- package/lib/ws-transport.js +1 -1
- package/lib/wss-endpoint.d.ts +2 -5
- package/lib/wss-endpoint.js +24 -20
- package/package.json +16 -14
- package/plugin.js +5 -4
- package/schema.json +41 -5
- package/src/http-endpoint.ts +29 -24
- package/src/index.ts +2 -2
- package/src/napcat-agent-deps.ts +10 -10
- package/src/protocol.ts +38 -28
- package/src/ws-endpoint.ts +34 -29
- package/src/ws-transport.ts +2 -2
- package/src/wss-endpoint.ts +27 -22
- /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/src/protocol.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
5
5
|
*/
|
|
6
6
|
import { isMediaRef, type MediaRef } from '@zhin.js/core';
|
|
7
|
+
import type { ConversationRef } from '@zhin.js/im-contract';
|
|
7
8
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
8
9
|
|
|
9
10
|
const logger = getLogger('napcat');
|
|
@@ -12,7 +13,7 @@ const logger = getLogger('napcat');
|
|
|
12
13
|
export interface NapCatLegacyEndpointRow {
|
|
13
14
|
readonly context?: string;
|
|
14
15
|
readonly connection?: 'ws' | 'wss' | 'http';
|
|
15
|
-
readonly
|
|
16
|
+
readonly id?: string;
|
|
16
17
|
readonly access_token?: string;
|
|
17
18
|
readonly url?: string;
|
|
18
19
|
readonly path?: string;
|
|
@@ -26,7 +27,7 @@ export interface NapCatLegacyEndpointRow {
|
|
|
26
27
|
/** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
|
|
27
28
|
export interface NapCatAdapterConfig {
|
|
28
29
|
readonly connection?: 'ws' | 'wss' | 'http';
|
|
29
|
-
readonly
|
|
30
|
+
readonly id?: string;
|
|
30
31
|
readonly access_token?: string;
|
|
31
32
|
readonly url?: string;
|
|
32
33
|
readonly path?: string;
|
|
@@ -41,7 +42,7 @@ export interface NapCatAdapterConfig {
|
|
|
41
42
|
|
|
42
43
|
export interface NapCatConfigBase {
|
|
43
44
|
readonly context: 'napcat';
|
|
44
|
-
readonly
|
|
45
|
+
readonly id: string;
|
|
45
46
|
readonly access_token?: string;
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -142,8 +143,8 @@ function normalizeConnection(
|
|
|
142
143
|
export function resolveNapCatConfig(config: NapCatAdapterConfig = {}): ResolvedNapCatConfig {
|
|
143
144
|
const entry = config.endpoints?.find((item) => item.context === 'napcat');
|
|
144
145
|
const connection = normalizeConnection(config.connection ?? entry?.connection);
|
|
145
|
-
const
|
|
146
|
-
|| (typeof entry?.
|
|
146
|
+
const id = (typeof config.id === 'string' && config.id)
|
|
147
|
+
|| (typeof entry?.id === 'string' && entry.id)
|
|
147
148
|
|| process.env.NAPCAT_BOT_NAME
|
|
148
149
|
|| 'napcat-bot';
|
|
149
150
|
const access_token = config.access_token ?? entry?.access_token;
|
|
@@ -158,7 +159,7 @@ export function resolveNapCatConfig(config: NapCatAdapterConfig = {}): ResolvedN
|
|
|
158
159
|
return {
|
|
159
160
|
context: 'napcat',
|
|
160
161
|
connection: 'ws',
|
|
161
|
-
|
|
162
|
+
id,
|
|
162
163
|
access_token,
|
|
163
164
|
url,
|
|
164
165
|
reconnect_interval: config.reconnect_interval ?? entry?.reconnect_interval ?? 5000,
|
|
@@ -172,7 +173,7 @@ export function resolveNapCatConfig(config: NapCatAdapterConfig = {}): ResolvedN
|
|
|
172
173
|
return {
|
|
173
174
|
context: 'napcat',
|
|
174
175
|
connection: 'wss',
|
|
175
|
-
|
|
176
|
+
id,
|
|
176
177
|
access_token,
|
|
177
178
|
path,
|
|
178
179
|
heartbeat_interval: config.heartbeat_interval ?? entry?.heartbeat_interval ?? 30_000,
|
|
@@ -188,7 +189,7 @@ export function resolveNapCatConfig(config: NapCatAdapterConfig = {}): ResolvedN
|
|
|
188
189
|
return {
|
|
189
190
|
context: 'napcat',
|
|
190
191
|
connection: 'http',
|
|
191
|
-
|
|
192
|
+
id,
|
|
192
193
|
access_token,
|
|
193
194
|
http_url,
|
|
194
195
|
post_path,
|
|
@@ -213,23 +214,33 @@ export function getChannelId(ev: NapCatEvent): string {
|
|
|
213
214
|
return '';
|
|
214
215
|
}
|
|
215
216
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
/**
|
|
218
|
+
* 入站归一化 → ConversationRef:群消息 → kind 'group';私聊临时会话
|
|
219
|
+
* (sub_type 'group')→ kind 'private' + 群容器进 `parent`;其余私聊 → 'private'。
|
|
220
|
+
*/
|
|
221
|
+
export function napcatInboundConversation(endpointKey: string, ev: NapCatEvent): ConversationRef {
|
|
222
|
+
const endpoint = { id: endpointKey, adapter: endpointKey.split('\0')[0] ?? endpointKey };
|
|
223
|
+
const isGroup = ev.message_type === 'group' || (ev.group_id != null && ev.message_type !== 'private');
|
|
224
|
+
if (isGroup && ev.group_id != null) {
|
|
225
|
+
return { endpoint, kind: 'group', id: String(ev.group_id) };
|
|
226
|
+
}
|
|
227
|
+
if (ev.sub_type === 'group' && ev.group_id != null) {
|
|
228
|
+
return {
|
|
229
|
+
endpoint,
|
|
230
|
+
kind: 'private',
|
|
231
|
+
id: ev.user_id != null ? String(ev.user_id) : '',
|
|
232
|
+
parent: { kind: 'group', id: String(ev.group_id) },
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return { endpoint, kind: 'private', id: ev.user_id != null ? String(ev.user_id) : '' };
|
|
221
236
|
}
|
|
222
237
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const rest = target.slice(sep + 1);
|
|
230
|
-
if (head === 'group') return { message_type: 'group', id: rest };
|
|
231
|
-
if (head === 'private') return { message_type: 'private', id: rest };
|
|
232
|
-
return { message_type: 'private', id: target };
|
|
238
|
+
/** 出站:ConversationRef → OneBot 私聊/群聊目标。 */
|
|
239
|
+
export function napcatOutboundTarget(conversation: ConversationRef): ParsedSendTarget {
|
|
240
|
+
return {
|
|
241
|
+
message_type: conversation.kind === 'group' ? 'group' : 'private',
|
|
242
|
+
id: conversation.id,
|
|
243
|
+
};
|
|
233
244
|
}
|
|
234
245
|
|
|
235
246
|
export function formatInboundContent(ev: NapCatEvent): string {
|
|
@@ -373,15 +384,14 @@ export function formatOutboundSegments(payload: unknown): MessageSegment[] {
|
|
|
373
384
|
}
|
|
374
385
|
|
|
375
386
|
export function buildSendAction(
|
|
376
|
-
target:
|
|
387
|
+
target: ParsedSendTarget,
|
|
377
388
|
message: MessageSegment[],
|
|
378
389
|
): { action: string; params: Record<string, unknown> } {
|
|
379
|
-
|
|
380
|
-
if (parsed.message_type === 'group') {
|
|
390
|
+
if (target.message_type === 'group') {
|
|
381
391
|
return {
|
|
382
392
|
action: 'send_group_msg',
|
|
383
393
|
params: {
|
|
384
|
-
group_id: Number(
|
|
394
|
+
group_id: Number(target.id) || target.id,
|
|
385
395
|
message,
|
|
386
396
|
},
|
|
387
397
|
};
|
|
@@ -389,7 +399,7 @@ export function buildSendAction(
|
|
|
389
399
|
return {
|
|
390
400
|
action: 'send_private_msg',
|
|
391
401
|
params: {
|
|
392
|
-
user_id: Number(
|
|
402
|
+
user_id: Number(target.id) || target.id,
|
|
393
403
|
message,
|
|
394
404
|
},
|
|
395
405
|
};
|
package/src/ws-endpoint.ts
CHANGED
|
@@ -8,9 +8,10 @@ import {
|
|
|
8
8
|
type EndpointInstance,
|
|
9
9
|
type EndpointLifecycle,
|
|
10
10
|
type EndpointManagement,
|
|
11
|
+
type EndpointSendRequest,
|
|
11
12
|
} from '@zhin.js/adapter';
|
|
12
13
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
13
|
-
import { formatCompact,
|
|
14
|
+
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
14
15
|
import type { CapabilityId } from '@zhin.js/plugin-runtime';
|
|
15
16
|
import { createNapCatEndpointManagement } from './endpoint-management.js';
|
|
16
17
|
import { registerNapcatAgentEndpoint } from './napcat-agent-deps.js';
|
|
@@ -24,9 +25,10 @@ import {
|
|
|
24
25
|
buildSendAction,
|
|
25
26
|
buildWsConnectOptions,
|
|
26
27
|
formatInboundContent,
|
|
27
|
-
formatInboundTarget,
|
|
28
28
|
formatOutboundSegments,
|
|
29
29
|
isMessageEvent,
|
|
30
|
+
napcatInboundConversation,
|
|
31
|
+
napcatOutboundTarget,
|
|
30
32
|
senderNickname,
|
|
31
33
|
senderUserId,
|
|
32
34
|
type NapCatEvent,
|
|
@@ -43,8 +45,6 @@ import {
|
|
|
43
45
|
type NapCatWsSocket,
|
|
44
46
|
} from './ws-types.js';
|
|
45
47
|
|
|
46
|
-
const logger = getLogger('napcat');
|
|
47
|
-
|
|
48
48
|
export interface NapCatWsEndpointOptions {
|
|
49
49
|
readonly id: CapabilityId;
|
|
50
50
|
readonly gateway: MessageGateway;
|
|
@@ -56,6 +56,8 @@ export interface NapCatWsEndpointOptions {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
export class NapCatWsEndpoint implements EndpointInstance {
|
|
59
|
+
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
60
|
+
|
|
59
61
|
readonly #options: NapCatWsEndpointOptions;
|
|
60
62
|
readonly #inboundDeduper = new InboundMessageDeduper();
|
|
61
63
|
readonly management: EndpointManagement = createNapCatEndpointManagement(this);
|
|
@@ -67,9 +69,10 @@ export class NapCatWsEndpoint implements EndpointInstance {
|
|
|
67
69
|
#unregisterAgent?: () => void;
|
|
68
70
|
|
|
69
71
|
constructor(options: NapCatWsEndpointOptions) {
|
|
72
|
+
this.#logger = getAdapterLogger('napcat', options.config.id);
|
|
70
73
|
this.#options = options;
|
|
71
74
|
this.#lifecycle = createEndpointLifecycle({
|
|
72
|
-
name: options.config.
|
|
75
|
+
name: options.config.id,
|
|
73
76
|
// reconnect_interval 旧语义为固定间隔:multiplier 1 + 无 jitter + 不封顶
|
|
74
77
|
reconnect: {
|
|
75
78
|
initialIntervalMs: options.config.reconnect_interval,
|
|
@@ -82,7 +85,7 @@ export class NapCatWsEndpoint implements EndpointInstance {
|
|
|
82
85
|
|
|
83
86
|
async start(): Promise<void> {
|
|
84
87
|
if (this.#lifecycle.started) return;
|
|
85
|
-
this.#unregisterAgent = registerNapcatAgentEndpoint(this.#options.config.
|
|
88
|
+
this.#unregisterAgent = registerNapcatAgentEndpoint(this.#options.config.id, this);
|
|
86
89
|
try {
|
|
87
90
|
await this.#lifecycle.start((handle) => this.#connect(handle));
|
|
88
91
|
} catch (err) {
|
|
@@ -118,15 +121,15 @@ export class NapCatWsEndpoint implements EndpointInstance {
|
|
|
118
121
|
}
|
|
119
122
|
}
|
|
120
123
|
|
|
121
|
-
async send({
|
|
124
|
+
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
122
125
|
const message = formatOutboundSegments(payload);
|
|
123
|
-
const { action, params } = buildSendAction(
|
|
126
|
+
const { action, params } = buildSendAction(napcatOutboundTarget(conversation), message);
|
|
124
127
|
const data = await this.callApi(action, params) as { message_id?: number | string } | undefined;
|
|
125
128
|
const messageId = data?.message_id != null ? String(data.message_id) : '';
|
|
126
|
-
logger.debug(formatCompact({
|
|
129
|
+
this.#logger.debug(formatCompact({
|
|
127
130
|
op: 'napcat_send',
|
|
128
|
-
endpoint: this.#options.config.
|
|
129
|
-
target
|
|
131
|
+
endpoint: this.#options.config.id,
|
|
132
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
130
133
|
messageId,
|
|
131
134
|
}));
|
|
132
135
|
return messageId;
|
|
@@ -326,31 +329,34 @@ export class NapCatWsEndpoint implements EndpointInstance {
|
|
|
326
329
|
if (Array.isArray(ev.message) || typeof ev.message === 'string') {
|
|
327
330
|
ev = { ...ev, message: normalizeMessage(ev.message) };
|
|
328
331
|
}
|
|
329
|
-
const
|
|
332
|
+
const conversation = napcatInboundConversation(String(this.#options.id), ev);
|
|
330
333
|
const content = formatInboundContent(ev);
|
|
331
334
|
const nickname = senderNickname(ev);
|
|
332
335
|
const mentioned = isNapCatBotMentioned(ev);
|
|
333
336
|
void this.#options.gateway.receive({
|
|
334
|
-
|
|
335
|
-
|
|
337
|
+
conversation,
|
|
338
|
+
message: { conversation, id: msgId },
|
|
336
339
|
content,
|
|
337
|
-
sender:
|
|
338
|
-
|
|
340
|
+
sender: {
|
|
341
|
+
id: senderUserId(ev),
|
|
342
|
+
name: nickname,
|
|
343
|
+
...(ev.sender?.role ? { roles: [ev.sender.role] } : {}),
|
|
344
|
+
},
|
|
345
|
+
endpointId: this.#options.config.id,
|
|
346
|
+
...(mentioned ? { mentioned: true } : {}),
|
|
339
347
|
metadata: Object.freeze({
|
|
340
348
|
message_type: ev.message_type,
|
|
341
349
|
user_id: ev.user_id != null ? String(ev.user_id) : undefined,
|
|
342
350
|
group_id: ev.group_id != null ? String(ev.group_id) : undefined,
|
|
343
|
-
endpoint: this.#options.config.name,
|
|
344
351
|
time: ev.time,
|
|
345
352
|
self_id: ev.self_id != null ? String(ev.self_id) : undefined,
|
|
346
353
|
role: ev.sender?.role,
|
|
347
354
|
...(nickname ? { nickname } : {}),
|
|
348
|
-
...(mentioned ? { mentioned: true } : {}),
|
|
349
355
|
}),
|
|
350
356
|
}).catch((err) => {
|
|
351
|
-
logger.warn(formatCompact({
|
|
357
|
+
this.#logger.warn(formatCompact({
|
|
352
358
|
op: 'napcat_gateway_receive_failed',
|
|
353
|
-
target
|
|
359
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
354
360
|
error: err instanceof Error ? err.message : String(err),
|
|
355
361
|
}));
|
|
356
362
|
});
|
|
@@ -378,14 +384,14 @@ export class NapCatWsEndpoint implements EndpointInstance {
|
|
|
378
384
|
if (settled) return;
|
|
379
385
|
settled = true;
|
|
380
386
|
if (!this.#options.config.access_token) {
|
|
381
|
-
logger.warn(formatCompact({
|
|
382
|
-
endpoint: this.#options.config.
|
|
387
|
+
this.#logger.warn(formatCompact({
|
|
388
|
+
endpoint: this.#options.config.id,
|
|
383
389
|
ok: false,
|
|
384
390
|
error: 'missing access_token',
|
|
385
391
|
}));
|
|
386
392
|
}
|
|
387
|
-
logger.debug(formatCompact({
|
|
388
|
-
endpoint: this.#options.config.
|
|
393
|
+
this.#logger.debug(formatCompact({
|
|
394
|
+
endpoint: this.#options.config.id,
|
|
389
395
|
mode: 'ws',
|
|
390
396
|
url: safeUrl,
|
|
391
397
|
}));
|
|
@@ -404,7 +410,7 @@ export class NapCatWsEndpoint implements EndpointInstance {
|
|
|
404
410
|
|
|
405
411
|
ws.on('message', (data) => {
|
|
406
412
|
handleNapCatWsMessage(data, {
|
|
407
|
-
|
|
413
|
+
endpointId: this.#options.config.id,
|
|
408
414
|
pending: this.#pending,
|
|
409
415
|
admit: (event) => this.admit(event),
|
|
410
416
|
});
|
|
@@ -422,9 +428,8 @@ export class NapCatWsEndpoint implements EndpointInstance {
|
|
|
422
428
|
: codeNum === 1006
|
|
423
429
|
? ' [abnormal]'
|
|
424
430
|
: '';
|
|
425
|
-
logger.warn(formatCompact({
|
|
431
|
+
this.#logger.warn(formatCompact({
|
|
426
432
|
op: 'disconnect',
|
|
427
|
-
endpoint: this.#options.config.name,
|
|
428
433
|
code: codeNum,
|
|
429
434
|
error: `${reasonStr || 'closed'}${codeHint}`,
|
|
430
435
|
reconnect_ms: this.#options.config.reconnect_interval,
|
|
@@ -439,9 +444,9 @@ export class NapCatWsEndpoint implements EndpointInstance {
|
|
|
439
444
|
|
|
440
445
|
ws.on('error', (err) => {
|
|
441
446
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
442
|
-
logger.warn(formatCompact({
|
|
447
|
+
this.#logger.warn(formatCompact({
|
|
443
448
|
op: 'ws_error',
|
|
444
|
-
endpoint: this.#options.config.
|
|
449
|
+
endpoint: this.#options.config.id,
|
|
445
450
|
ok: false,
|
|
446
451
|
error: error.message,
|
|
447
452
|
}));
|
package/src/ws-transport.ts
CHANGED
|
@@ -23,7 +23,7 @@ export function decodeWsPayload(data: unknown): string {
|
|
|
23
23
|
export function handleNapCatWsMessage(
|
|
24
24
|
data: unknown,
|
|
25
25
|
options: {
|
|
26
|
-
readonly
|
|
26
|
+
readonly endpointId: string;
|
|
27
27
|
readonly pending: Map<string, NapCatPendingAction>;
|
|
28
28
|
readonly admit: (ev: NapCatEvent) => void;
|
|
29
29
|
},
|
|
@@ -50,7 +50,7 @@ export function handleNapCatWsMessage(
|
|
|
50
50
|
} catch (error) {
|
|
51
51
|
logger.warn(formatCompact({
|
|
52
52
|
op: 'napcat_parse_failed',
|
|
53
|
-
endpoint: options.
|
|
53
|
+
endpoint: options.endpointId,
|
|
54
54
|
error: error instanceof Error ? error.message : String(error),
|
|
55
55
|
}));
|
|
56
56
|
}
|
package/src/wss-endpoint.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* NapCat reverse WSS endpoint — accepts inbound WebSocket from NapCat.
|
|
3
3
|
*/
|
|
4
4
|
import { clearInterval } from 'node:timers';
|
|
5
|
-
import type { EndpointInstance, EndpointManagement } from '@zhin.js/adapter';
|
|
5
|
+
import type { EndpointInstance, EndpointManagement, EndpointSendRequest } from '@zhin.js/adapter';
|
|
6
6
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
7
7
|
import type { HttpHost, WsConnection } from '@zhin.js/host-http';
|
|
8
|
-
import { formatCompact,
|
|
8
|
+
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
9
9
|
import type { CapabilityId } from '@zhin.js/plugin-runtime';
|
|
10
10
|
import { createNapCatEndpointManagement } from './endpoint-management.js';
|
|
11
11
|
import { registerNapcatAgentEndpoint } from './napcat-agent-deps.js';
|
|
@@ -18,9 +18,10 @@ import {
|
|
|
18
18
|
import {
|
|
19
19
|
buildSendAction,
|
|
20
20
|
formatInboundContent,
|
|
21
|
-
formatInboundTarget,
|
|
22
21
|
formatOutboundSegments,
|
|
23
22
|
isMessageEvent,
|
|
23
|
+
napcatInboundConversation,
|
|
24
|
+
napcatOutboundTarget,
|
|
24
25
|
senderNickname,
|
|
25
26
|
senderUserId,
|
|
26
27
|
type NapCatEvent,
|
|
@@ -39,8 +40,6 @@ import {
|
|
|
39
40
|
} from './ws-types.js';
|
|
40
41
|
import { verifyNapCatAccessToken } from './wss-auth.js';
|
|
41
42
|
|
|
42
|
-
const logger = getLogger('napcat');
|
|
43
|
-
|
|
44
43
|
export interface NapCatWssEndpointOptions {
|
|
45
44
|
readonly id: CapabilityId;
|
|
46
45
|
readonly gateway: MessageGateway;
|
|
@@ -49,6 +48,8 @@ export interface NapCatWssEndpointOptions {
|
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
export class NapCatWssEndpoint implements EndpointInstance {
|
|
51
|
+
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
52
|
+
|
|
52
53
|
readonly #options: NapCatWssEndpointOptions;
|
|
53
54
|
readonly #inboundDeduper = new InboundMessageDeduper();
|
|
54
55
|
readonly management: EndpointManagement = createNapCatEndpointManagement(this);
|
|
@@ -62,6 +63,7 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
62
63
|
#unregisterAgent?: () => void;
|
|
63
64
|
|
|
64
65
|
constructor(options: NapCatWssEndpointOptions) {
|
|
66
|
+
this.#logger = getAdapterLogger('napcat', options.config.id);
|
|
65
67
|
this.#options = options;
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -69,16 +71,16 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
69
71
|
if (this.#started) return;
|
|
70
72
|
this.#started = true;
|
|
71
73
|
this.#unregisterAgent = registerNapcatAgentEndpoint(
|
|
72
|
-
this.#options.config.
|
|
74
|
+
this.#options.config.id,
|
|
73
75
|
this as unknown as NapCatWsEndpoint,
|
|
74
76
|
);
|
|
75
77
|
const handle = this.#options.http.ws(this.#options.config.path);
|
|
76
78
|
this.#wsRelease = handle.onConnection((connection) => {
|
|
77
79
|
this.#acceptConnection(connection);
|
|
78
80
|
});
|
|
79
|
-
logger.info(formatCompact({
|
|
81
|
+
this.#logger.info(formatCompact({
|
|
80
82
|
op: 'listen',
|
|
81
|
-
endpoint: this.#options.config.
|
|
83
|
+
endpoint: this.#options.config.id,
|
|
82
84
|
mode: 'wss',
|
|
83
85
|
path: this.#options.config.path,
|
|
84
86
|
}));
|
|
@@ -115,9 +117,9 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
115
117
|
this.#started = false;
|
|
116
118
|
}
|
|
117
119
|
|
|
118
|
-
async send({
|
|
120
|
+
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
119
121
|
const message = formatOutboundSegments(payload);
|
|
120
|
-
const { action, params } = buildSendAction(
|
|
122
|
+
const { action, params } = buildSendAction(napcatOutboundTarget(conversation), message);
|
|
121
123
|
const data = await this.callApi(action, params) as { message_id?: number | string } | undefined;
|
|
122
124
|
return data?.message_id != null ? String(data.message_id) : '';
|
|
123
125
|
}
|
|
@@ -139,30 +141,33 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
139
141
|
if (Array.isArray(ev.message) || typeof ev.message === 'string') {
|
|
140
142
|
ev = { ...ev, message: normalizeMessage(ev.message) };
|
|
141
143
|
}
|
|
142
|
-
const
|
|
144
|
+
const conversation = napcatInboundConversation(String(this.#options.id), ev);
|
|
143
145
|
const nickname = senderNickname(ev);
|
|
144
146
|
const mentioned = isNapCatBotMentioned(ev);
|
|
145
147
|
void this.#options.gateway.receive({
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
conversation,
|
|
149
|
+
message: { conversation, id: msgId },
|
|
148
150
|
content: formatInboundContent(ev),
|
|
149
|
-
sender:
|
|
150
|
-
|
|
151
|
+
sender: {
|
|
152
|
+
id: senderUserId(ev),
|
|
153
|
+
name: nickname,
|
|
154
|
+
...(ev.sender?.role ? { roles: [ev.sender.role] } : {}),
|
|
155
|
+
},
|
|
156
|
+
endpointId: this.#options.config.id,
|
|
157
|
+
...(mentioned ? { mentioned: true } : {}),
|
|
151
158
|
metadata: Object.freeze({
|
|
152
159
|
message_type: ev.message_type,
|
|
153
160
|
user_id: ev.user_id != null ? String(ev.user_id) : undefined,
|
|
154
161
|
group_id: ev.group_id != null ? String(ev.group_id) : undefined,
|
|
155
|
-
endpoint: this.#options.config.name,
|
|
156
162
|
time: ev.time,
|
|
157
163
|
self_id: ev.self_id != null ? String(ev.self_id) : undefined,
|
|
158
164
|
role: ev.sender?.role,
|
|
159
165
|
...(nickname ? { nickname } : {}),
|
|
160
|
-
...(mentioned ? { mentioned: true } : {}),
|
|
161
166
|
}),
|
|
162
167
|
}).catch((err) => {
|
|
163
|
-
logger.warn(formatCompact({
|
|
168
|
+
this.#logger.warn(formatCompact({
|
|
164
169
|
op: 'napcat_gateway_receive_failed',
|
|
165
|
-
target
|
|
170
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
166
171
|
error: err instanceof Error ? err.message : String(err),
|
|
167
172
|
}));
|
|
168
173
|
});
|
|
@@ -189,7 +194,7 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
189
194
|
);
|
|
190
195
|
socket.on('message', (data) => {
|
|
191
196
|
handleNapCatWsMessage(data, {
|
|
192
|
-
|
|
197
|
+
endpointId: this.#options.config.id,
|
|
193
198
|
pending: this.#pending,
|
|
194
199
|
admit: (event) => this.admit(event),
|
|
195
200
|
});
|
|
@@ -203,8 +208,8 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
203
208
|
}
|
|
204
209
|
}
|
|
205
210
|
});
|
|
206
|
-
logger.debug(formatCompact({
|
|
207
|
-
endpoint: this.#options.config.
|
|
211
|
+
this.#logger.debug(formatCompact({
|
|
212
|
+
endpoint: this.#options.config.id,
|
|
208
213
|
mode: 'wss',
|
|
209
214
|
peer: connection.request.socket.remoteAddress,
|
|
210
215
|
}));
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|