@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,100 @@
|
|
|
1
1
|
# @zhin.js/adapter-napcat
|
|
2
2
|
|
|
3
|
+
## 6.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
|
+
## 6.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
|
+
## 6.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
|
## 6.0.2
|
|
4
99
|
|
|
5
100
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Zhin.js [NapCatQQ](https://github.com/NapNeko/NapCatQQ) 适配器(Plugin Runti
|
|
|
8
8
|
- 约定式 `defineAdapter` / `definePlugin`(无需 `usePlugin`)
|
|
9
9
|
- **正向 WebSocket**(`connection: ws`):应用连 NapCat WS
|
|
10
10
|
- `access_token` 鉴权(Bearer + query)
|
|
11
|
-
- 入站经 `messageGatewayToken`(去重 + 自发过滤);出站 `send({
|
|
11
|
+
- 入站经 `messageGatewayToken`(去重 + 自发过滤);出站 `send({ conversation, payload })`
|
|
12
12
|
- 41 个 AI 工具(`agent/tools/`)
|
|
13
13
|
|
|
14
14
|
## 安装
|
|
@@ -24,8 +24,8 @@ pnpm add @zhin.js/adapter-napcat
|
|
|
24
24
|
- `@zhin.js/plugin-runtime` — `plugin.ts`(`definePlugin`)
|
|
25
25
|
- 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
|
|
26
26
|
|
|
27
|
-
入站:`gateway.receive({
|
|
28
|
-
出站:`send({
|
|
27
|
+
入站:`gateway.receive({ conversation, message: { conversation, id }, content, sender, metadata })`(`conversation` 为 ConversationRef:私聊 `kind: 'private'`、群聊 `kind: 'group'`,临时会话群容器进 `parent`)
|
|
28
|
+
出站:`send({ conversation, payload })` → WS `send_private_msg` / `send_group_msg`
|
|
29
29
|
|
|
30
30
|
## 最小配置
|
|
31
31
|
|
package/adapters/napcat.js
CHANGED
|
@@ -25,8 +25,8 @@ export default defineAdapter({
|
|
|
25
25
|
const config = resolveNapCatConfig(context.config);
|
|
26
26
|
const gateway = context.use(messageGatewayToken);
|
|
27
27
|
// 注册到插件运行时状态(napcat.endpoint list 的"运行中"数据源)
|
|
28
|
-
context.use(napcatRuntimeStateToken).endpoints.set(config.
|
|
29
|
-
|
|
28
|
+
context.use(napcatRuntimeStateToken).endpoints.set(config.id, {
|
|
29
|
+
id: config.id,
|
|
30
30
|
mode: config.connection,
|
|
31
31
|
});
|
|
32
32
|
if (config.connection === 'wss') {
|
package/adapters/napcat.ts
CHANGED
|
@@ -36,8 +36,8 @@ export default defineAdapter<NapCatAdapterConfig>({
|
|
|
36
36
|
const config = resolveNapCatConfig(context.config);
|
|
37
37
|
const gateway = context.use(messageGatewayToken);
|
|
38
38
|
// 注册到插件运行时状态(napcat.endpoint list 的"运行中"数据源)
|
|
39
|
-
context.use(napcatRuntimeStateToken).endpoints.set(config.
|
|
40
|
-
|
|
39
|
+
context.use(napcatRuntimeStateToken).endpoints.set(config.id, {
|
|
40
|
+
id: config.id,
|
|
41
41
|
mode: config.connection,
|
|
42
42
|
});
|
|
43
43
|
if (config.connection === 'wss') {
|
package/lib/http-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 NapCatHttpEndpoint 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
|
recallMessage(messageId: string): Promise<void>;
|
|
26
23
|
callApi(action: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
27
24
|
admit(ev: NapCatEvent): void;
|
package/lib/http-endpoint.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { formatCompact,
|
|
1
|
+
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
2
2
|
import { createNapCatEndpointManagement } from './endpoint-management.js';
|
|
3
3
|
import { registerNapcatAgentEndpoint } from './napcat-agent-deps.js';
|
|
4
4
|
import { InboundMessageDeduper, isNapCatBotMentioned, isSelfMessage, normalizeMessage, } from './napcat-inbound.js';
|
|
5
|
-
import { buildSendAction, callNapCatHttpAction, formatInboundContent,
|
|
5
|
+
import { buildSendAction, callNapCatHttpAction, formatInboundContent, formatOutboundSegments, isMessageEvent, napcatInboundConversation, napcatOutboundTarget, senderNickname, senderUserId, } from './protocol.js';
|
|
6
6
|
import { readRequestBody } from './webhook.js';
|
|
7
7
|
import { verifyNapCatAccessToken } from './wss-auth.js';
|
|
8
|
-
const logger = getLogger('napcat');
|
|
9
8
|
export class NapCatHttpEndpoint {
|
|
9
|
+
#logger;
|
|
10
10
|
#options;
|
|
11
11
|
#inboundDeduper = new InboundMessageDeduper();
|
|
12
12
|
management = createNapCatEndpointManagement(this);
|
|
@@ -16,6 +16,7 @@ export class NapCatHttpEndpoint {
|
|
|
16
16
|
#started = false;
|
|
17
17
|
#unregisterAgent;
|
|
18
18
|
constructor(options) {
|
|
19
|
+
this.#logger = getAdapterLogger('napcat', options.config.id);
|
|
19
20
|
this.#options = options;
|
|
20
21
|
this.#callHttpAction = options.callHttpAction ?? callNapCatHttpAction;
|
|
21
22
|
}
|
|
@@ -23,11 +24,11 @@ export class NapCatHttpEndpoint {
|
|
|
23
24
|
if (this.#started)
|
|
24
25
|
return;
|
|
25
26
|
this.#started = true;
|
|
26
|
-
this.#unregisterAgent = registerNapcatAgentEndpoint(this.#options.config.
|
|
27
|
+
this.#unregisterAgent = registerNapcatAgentEndpoint(this.#options.config.id, this);
|
|
27
28
|
this.#setupRoutes();
|
|
28
|
-
logger.info(formatCompact({
|
|
29
|
+
this.#logger.info(formatCompact({
|
|
29
30
|
op: 'listen',
|
|
30
|
-
endpoint: this.#options.config.
|
|
31
|
+
endpoint: this.#options.config.id,
|
|
31
32
|
mode: 'http',
|
|
32
33
|
path: this.#options.config.post_path,
|
|
33
34
|
}));
|
|
@@ -46,21 +47,21 @@ export class NapCatHttpEndpoint {
|
|
|
46
47
|
this.#unregisterAgent = undefined;
|
|
47
48
|
this.#inboundDeduper.clear();
|
|
48
49
|
this.#started = false;
|
|
49
|
-
logger.debug(formatCompact({ op: 'disconnect'
|
|
50
|
+
this.#logger.debug(formatCompact({ op: 'disconnect' }));
|
|
50
51
|
}
|
|
51
|
-
async send({
|
|
52
|
+
async send({ conversation, payload }) {
|
|
52
53
|
const message = formatOutboundSegments(payload);
|
|
53
|
-
const { action, params } = buildSendAction(
|
|
54
|
+
const { action, params } = buildSendAction(napcatOutboundTarget(conversation), message);
|
|
54
55
|
const resp = await this.#callHttpAction({
|
|
55
56
|
http_url: this.#options.config.http_url,
|
|
56
57
|
access_token: this.#options.config.access_token,
|
|
57
58
|
}, action, params);
|
|
58
59
|
const data = resp.data;
|
|
59
60
|
const messageId = data?.message_id != null ? String(data.message_id) : '';
|
|
60
|
-
logger.debug(formatCompact({
|
|
61
|
+
this.#logger.debug(formatCompact({
|
|
61
62
|
op: 'napcat_send',
|
|
62
|
-
endpoint: this.#options.config.
|
|
63
|
-
target
|
|
63
|
+
endpoint: this.#options.config.id,
|
|
64
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
64
65
|
messageId,
|
|
65
66
|
}));
|
|
66
67
|
return messageId;
|
|
@@ -87,30 +88,33 @@ export class NapCatHttpEndpoint {
|
|
|
87
88
|
if (Array.isArray(ev.message) || typeof ev.message === 'string') {
|
|
88
89
|
ev = { ...ev, message: normalizeMessage(ev.message) };
|
|
89
90
|
}
|
|
90
|
-
const
|
|
91
|
+
const conversation = napcatInboundConversation(String(this.#options.id), ev);
|
|
91
92
|
const nickname = senderNickname(ev);
|
|
92
93
|
const mentioned = isNapCatBotMentioned(ev);
|
|
93
94
|
void this.#options.gateway.receive({
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
conversation,
|
|
96
|
+
message: { conversation, id: msgId },
|
|
96
97
|
content: formatInboundContent(ev),
|
|
97
|
-
sender:
|
|
98
|
-
|
|
98
|
+
sender: {
|
|
99
|
+
id: senderUserId(ev),
|
|
100
|
+
name: nickname,
|
|
101
|
+
...(ev.sender?.role ? { roles: [ev.sender.role] } : {}),
|
|
102
|
+
},
|
|
103
|
+
endpointId: this.#options.config.id,
|
|
104
|
+
...(mentioned ? { mentioned: true } : {}),
|
|
99
105
|
metadata: Object.freeze({
|
|
100
106
|
message_type: ev.message_type,
|
|
101
107
|
user_id: ev.user_id != null ? String(ev.user_id) : undefined,
|
|
102
108
|
group_id: ev.group_id != null ? String(ev.group_id) : undefined,
|
|
103
|
-
endpoint: this.#options.config.name,
|
|
104
109
|
time: ev.time,
|
|
105
110
|
self_id: ev.self_id != null ? String(ev.self_id) : undefined,
|
|
106
111
|
role: ev.sender?.role,
|
|
107
112
|
...(nickname ? { nickname } : {}),
|
|
108
|
-
...(mentioned ? { mentioned: true } : {}),
|
|
109
113
|
}),
|
|
110
114
|
}).catch((err) => {
|
|
111
|
-
logger.warn(formatCompact({
|
|
115
|
+
this.#logger.warn(formatCompact({
|
|
112
116
|
op: 'napcat_gateway_receive_failed',
|
|
113
|
-
target
|
|
117
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
114
118
|
error: err instanceof Error ? err.message : String(err),
|
|
115
119
|
}));
|
|
116
120
|
});
|
|
@@ -144,7 +148,7 @@ export class NapCatHttpEndpoint {
|
|
|
144
148
|
response.end(JSON.stringify({ status: 'ok' }));
|
|
145
149
|
}
|
|
146
150
|
catch (error) {
|
|
147
|
-
logger.error('NapCat HTTP webhook error:', error);
|
|
151
|
+
this.#logger.error('NapCat HTTP webhook error:', error);
|
|
148
152
|
if (!response.headersSent) {
|
|
149
153
|
response.writeHead(500, { 'Content-Type': 'application/json' });
|
|
150
154
|
response.end(JSON.stringify({ message: 'Internal Server Error' }));
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { buildSendAction, buildWsConnectOptions, callNapCatHttpAction, formatInboundContent,
|
|
1
|
+
export { buildSendAction, buildWsConnectOptions, callNapCatHttpAction, formatInboundContent, formatOutboundSegments, getChannelId, isMessageEvent, mediaRefToOneBotFile, napcatInboundConversation, napcatOutboundTarget, resolveNapCatConfig, senderNickname, senderUserId, type MessageSegment, type NapCatActionRequest, type NapCatActionResponse, type NapCatAdapterConfig, type NapCatConfigBase, type NapCatEndpointConfig, type NapCatEvent, type NapCatHttpConfig, type NapCatMessageEvent, type NapCatSender, type NapCatWireSegment, type NapCatWsConfig, type NapCatWssConfig, type ParsedSendTarget, type ResolvedNapCatConfig, } from './protocol.js';
|
|
2
2
|
export { InboundMessageDeduper, isNapCatBotMentioned, isSelfMessage, normalizeMessage, } from './napcat-inbound.js';
|
|
3
3
|
export { getEndpoint, getNapcatAgentDeps, registerNapcatAgentEndpoint, setNapcatAgentDeps, type NapcatAgentDeps, type NapcatAgentEndpoint, } from './napcat-agent-deps.js';
|
|
4
4
|
export { parseOneBotGetMsgResponse } from './onebot-get-msg.js';
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { buildSendAction, buildWsConnectOptions, callNapCatHttpAction, formatInboundContent,
|
|
1
|
+
export { buildSendAction, buildWsConnectOptions, callNapCatHttpAction, formatInboundContent, formatOutboundSegments, getChannelId, isMessageEvent, mediaRefToOneBotFile, napcatInboundConversation, napcatOutboundTarget, resolveNapCatConfig, senderNickname, senderUserId, } from './protocol.js';
|
|
2
2
|
export { InboundMessageDeduper, isNapCatBotMentioned, isSelfMessage, normalizeMessage, } from './napcat-inbound.js';
|
|
3
3
|
export { getEndpoint, getNapcatAgentDeps, registerNapcatAgentEndpoint, setNapcatAgentDeps, } from './napcat-agent-deps.js';
|
|
4
4
|
export { parseOneBotGetMsgResponse } from './onebot-get-msg.js';
|
|
@@ -41,11 +41,11 @@ export interface NapcatAgentEndpoint {
|
|
|
41
41
|
sendGroupAiRecord(groupId: number, characterId: string, text: string): Promise<unknown>;
|
|
42
42
|
}
|
|
43
43
|
export interface NapcatAgentDeps {
|
|
44
|
-
getEndpoint: (
|
|
44
|
+
getEndpoint: (endpointKey: string) => NapcatAgentEndpoint;
|
|
45
45
|
}
|
|
46
|
-
export declare function registerNapcatAgentEndpoint(
|
|
46
|
+
export declare function registerNapcatAgentEndpoint(endpointKey: string, endpoint: NapcatAgentEndpoint): () => void;
|
|
47
47
|
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
48
48
|
export declare function setNapcatAgentDeps(deps: NapcatAgentDeps | null): void;
|
|
49
49
|
export declare function getNapcatAgentDeps(): NapcatAgentDeps;
|
|
50
50
|
/** Convenience for agent/tools (unchanged call sites). */
|
|
51
|
-
export declare function getEndpoint(
|
|
51
|
+
export declare function getEndpoint(endpointKey: string): NapcatAgentEndpoint;
|
package/lib/napcat-agent-deps.js
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
const endpoints = new Map();
|
|
6
6
|
let override = null;
|
|
7
|
-
export function registerNapcatAgentEndpoint(
|
|
8
|
-
endpoints.set(
|
|
7
|
+
export function registerNapcatAgentEndpoint(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
|
}
|
|
@@ -16,10 +16,10 @@ export function registerNapcatAgentEndpoint(endpointId, endpoint) {
|
|
|
16
16
|
export function setNapcatAgentDeps(deps) {
|
|
17
17
|
override = deps;
|
|
18
18
|
}
|
|
19
|
-
function lookup(
|
|
20
|
-
const registered = endpoints.get(
|
|
19
|
+
function lookup(endpointKey) {
|
|
20
|
+
const registered = endpoints.get(endpointKey);
|
|
21
21
|
if (!registered)
|
|
22
|
-
throw new Error(`Endpoint ${
|
|
22
|
+
throw new Error(`Endpoint ${endpointKey} not found`);
|
|
23
23
|
return registered;
|
|
24
24
|
}
|
|
25
25
|
export function getNapcatAgentDeps() {
|
|
@@ -28,6 +28,6 @@ export function getNapcatAgentDeps() {
|
|
|
28
28
|
return { getEndpoint: lookup };
|
|
29
29
|
}
|
|
30
30
|
/** Convenience for agent/tools (unchanged call sites). */
|
|
31
|
-
export function getEndpoint(
|
|
32
|
-
return getNapcatAgentDeps().getEndpoint(
|
|
31
|
+
export function getEndpoint(endpointKey) {
|
|
32
|
+
return getNapcatAgentDeps().getEndpoint(endpointKey);
|
|
33
33
|
}
|
package/lib/protocol.d.ts
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
5
5
|
*/
|
|
6
6
|
import { type MediaRef } from '@zhin.js/core';
|
|
7
|
+
import type { ConversationRef } from '@zhin.js/im-contract';
|
|
7
8
|
/** Transitional legacy endpoint row (`endpoints[]` with `context: napcat`). */
|
|
8
9
|
export interface NapCatLegacyEndpointRow {
|
|
9
10
|
readonly context?: string;
|
|
10
11
|
readonly connection?: 'ws' | 'wss' | 'http';
|
|
11
|
-
readonly
|
|
12
|
+
readonly id?: string;
|
|
12
13
|
readonly access_token?: string;
|
|
13
14
|
readonly url?: string;
|
|
14
15
|
readonly path?: string;
|
|
@@ -21,7 +22,7 @@ export interface NapCatLegacyEndpointRow {
|
|
|
21
22
|
/** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
|
|
22
23
|
export interface NapCatAdapterConfig {
|
|
23
24
|
readonly connection?: 'ws' | 'wss' | 'http';
|
|
24
|
-
readonly
|
|
25
|
+
readonly id?: string;
|
|
25
26
|
readonly access_token?: string;
|
|
26
27
|
readonly url?: string;
|
|
27
28
|
readonly path?: string;
|
|
@@ -35,7 +36,7 @@ export interface NapCatAdapterConfig {
|
|
|
35
36
|
}
|
|
36
37
|
export interface NapCatConfigBase {
|
|
37
38
|
readonly context: 'napcat';
|
|
38
|
-
readonly
|
|
39
|
+
readonly id: string;
|
|
39
40
|
readonly access_token?: string;
|
|
40
41
|
}
|
|
41
42
|
/** 正向 WebSocket:应用连 NapCat WS */
|
|
@@ -116,8 +117,13 @@ export interface ParsedSendTarget {
|
|
|
116
117
|
export declare function resolveNapCatConfig(config?: NapCatAdapterConfig): ResolvedNapCatConfig;
|
|
117
118
|
export declare function isMessageEvent(ev: NapCatEvent): ev is NapCatMessageEvent;
|
|
118
119
|
export declare function getChannelId(ev: NapCatEvent): string;
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
/**
|
|
121
|
+
* 入站归一化 → ConversationRef:群消息 → kind 'group';私聊临时会话
|
|
122
|
+
* (sub_type 'group')→ kind 'private' + 群容器进 `parent`;其余私聊 → 'private'。
|
|
123
|
+
*/
|
|
124
|
+
export declare function napcatInboundConversation(endpointKey: string, ev: NapCatEvent): ConversationRef;
|
|
125
|
+
/** 出站:ConversationRef → OneBot 私聊/群聊目标。 */
|
|
126
|
+
export declare function napcatOutboundTarget(conversation: ConversationRef): ParsedSendTarget;
|
|
121
127
|
export declare function formatInboundContent(ev: NapCatEvent): string;
|
|
122
128
|
/**
|
|
123
129
|
* 入站 sender 语义:必须是用户 ID(Runtime Message contract)。
|
|
@@ -138,7 +144,7 @@ export declare function mediaRefToOneBotFile(media: MediaRef): string;
|
|
|
138
144
|
* 非媒体的 wire 段(at 等)原样透传。
|
|
139
145
|
*/
|
|
140
146
|
export declare function formatOutboundSegments(payload: unknown): MessageSegment[];
|
|
141
|
-
export declare function buildSendAction(target:
|
|
147
|
+
export declare function buildSendAction(target: ParsedSendTarget, message: MessageSegment[]): {
|
|
142
148
|
action: string;
|
|
143
149
|
params: Record<string, unknown>;
|
|
144
150
|
};
|
package/lib/protocol.js
CHANGED
|
@@ -14,8 +14,8 @@ function normalizeConnection(connection) {
|
|
|
14
14
|
export function resolveNapCatConfig(config = {}) {
|
|
15
15
|
const entry = config.endpoints?.find((item) => item.context === 'napcat');
|
|
16
16
|
const connection = normalizeConnection(config.connection ?? entry?.connection);
|
|
17
|
-
const
|
|
18
|
-
|| (typeof entry?.
|
|
17
|
+
const id = (typeof config.id === 'string' && config.id)
|
|
18
|
+
|| (typeof entry?.id === 'string' && entry.id)
|
|
19
19
|
|| process.env.NAPCAT_BOT_NAME
|
|
20
20
|
|| 'napcat-bot';
|
|
21
21
|
const access_token = config.access_token ?? entry?.access_token;
|
|
@@ -27,7 +27,7 @@ export function resolveNapCatConfig(config = {}) {
|
|
|
27
27
|
return {
|
|
28
28
|
context: 'napcat',
|
|
29
29
|
connection: 'ws',
|
|
30
|
-
|
|
30
|
+
id,
|
|
31
31
|
access_token,
|
|
32
32
|
url,
|
|
33
33
|
reconnect_interval: config.reconnect_interval ?? entry?.reconnect_interval ?? 5000,
|
|
@@ -41,7 +41,7 @@ export function resolveNapCatConfig(config = {}) {
|
|
|
41
41
|
return {
|
|
42
42
|
context: 'napcat',
|
|
43
43
|
connection: 'wss',
|
|
44
|
-
|
|
44
|
+
id,
|
|
45
45
|
access_token,
|
|
46
46
|
path,
|
|
47
47
|
heartbeat_interval: config.heartbeat_interval ?? entry?.heartbeat_interval ?? 30_000,
|
|
@@ -56,7 +56,7 @@ export function resolveNapCatConfig(config = {}) {
|
|
|
56
56
|
return {
|
|
57
57
|
context: 'napcat',
|
|
58
58
|
connection: 'http',
|
|
59
|
-
|
|
59
|
+
id,
|
|
60
60
|
access_token,
|
|
61
61
|
http_url,
|
|
62
62
|
post_path,
|
|
@@ -78,24 +78,32 @@ export function getChannelId(ev) {
|
|
|
78
78
|
return String(ev.user_id);
|
|
79
79
|
return '';
|
|
80
80
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return { message_type: 'private', id: target };
|
|
81
|
+
/**
|
|
82
|
+
* 入站归一化 → ConversationRef:群消息 → kind 'group';私聊临时会话
|
|
83
|
+
* (sub_type 'group')→ kind 'private' + 群容器进 `parent`;其余私聊 → 'private'。
|
|
84
|
+
*/
|
|
85
|
+
export function napcatInboundConversation(endpointKey, ev) {
|
|
86
|
+
const endpoint = { id: endpointKey, adapter: endpointKey.split('\0')[0] ?? endpointKey };
|
|
87
|
+
const isGroup = ev.message_type === 'group' || (ev.group_id != null && ev.message_type !== 'private');
|
|
88
|
+
if (isGroup && ev.group_id != null) {
|
|
89
|
+
return { endpoint, kind: 'group', id: String(ev.group_id) };
|
|
91
90
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
if (ev.sub_type === 'group' && ev.group_id != null) {
|
|
92
|
+
return {
|
|
93
|
+
endpoint,
|
|
94
|
+
kind: 'private',
|
|
95
|
+
id: ev.user_id != null ? String(ev.user_id) : '',
|
|
96
|
+
parent: { kind: 'group', id: String(ev.group_id) },
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return { endpoint, kind: 'private', id: ev.user_id != null ? String(ev.user_id) : '' };
|
|
100
|
+
}
|
|
101
|
+
/** 出站:ConversationRef → OneBot 私聊/群聊目标。 */
|
|
102
|
+
export function napcatOutboundTarget(conversation) {
|
|
103
|
+
return {
|
|
104
|
+
message_type: conversation.kind === 'group' ? 'group' : 'private',
|
|
105
|
+
id: conversation.id,
|
|
106
|
+
};
|
|
99
107
|
}
|
|
100
108
|
export function formatInboundContent(ev) {
|
|
101
109
|
if (typeof ev.raw_message === 'string' && ev.raw_message)
|
|
@@ -231,12 +239,11 @@ export function formatOutboundSegments(payload) {
|
|
|
231
239
|
return segs.length ? segs : [{ type: 'text', data: { text: '' } }];
|
|
232
240
|
}
|
|
233
241
|
export function buildSendAction(target, message) {
|
|
234
|
-
|
|
235
|
-
if (parsed.message_type === 'group') {
|
|
242
|
+
if (target.message_type === 'group') {
|
|
236
243
|
return {
|
|
237
244
|
action: 'send_group_msg',
|
|
238
245
|
params: {
|
|
239
|
-
group_id: Number(
|
|
246
|
+
group_id: Number(target.id) || target.id,
|
|
240
247
|
message,
|
|
241
248
|
},
|
|
242
249
|
};
|
|
@@ -244,7 +251,7 @@ export function buildSendAction(target, message) {
|
|
|
244
251
|
return {
|
|
245
252
|
action: 'send_private_msg',
|
|
246
253
|
params: {
|
|
247
|
-
user_id: Number(
|
|
254
|
+
user_id: Number(target.id) || target.id,
|
|
248
255
|
message,
|
|
249
256
|
},
|
|
250
257
|
};
|
package/lib/ws-endpoint.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type EndpointInstance, type EndpointManagement } from '@zhin.js/adapter';
|
|
1
|
+
import { type EndpointInstance, type EndpointManagement, type EndpointSendRequest } from '@zhin.js/adapter';
|
|
2
2
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
3
3
|
import type { CapabilityId } from '@zhin.js/plugin-runtime';
|
|
4
4
|
import { type NapCatEvent, type NapCatWsConfig } from './protocol.js';
|
|
@@ -17,10 +17,7 @@ export declare class NapCatWsEndpoint implements EndpointInstance {
|
|
|
17
17
|
open(): void;
|
|
18
18
|
close(): void;
|
|
19
19
|
stop(): Promise<void>;
|
|
20
|
-
send({
|
|
21
|
-
readonly target: string;
|
|
22
|
-
readonly payload: unknown;
|
|
23
|
-
}): Promise<string>;
|
|
20
|
+
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
24
21
|
recallMessage(messageId: string): Promise<void>;
|
|
25
22
|
callApi(action: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
26
23
|
setTitle(groupId: number, userId: number, title: string, duration?: number): Promise<boolean>;
|