@zhin.js/adapter-onebot11 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/onebot11.js +2 -2
- package/adapters/onebot11.ts +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/onebot11-agent-deps.d.ts +2 -2
- package/lib/onebot11-agent-deps.js +7 -7
- package/lib/protocol.d.ts +20 -13
- package/lib/protocol.js +33 -41
- package/lib/ws-endpoint.d.ts +2 -5
- package/lib/ws-endpoint.js +33 -25
- 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 +29 -21
- package/package.json +16 -14
- package/plugin.js +5 -4
- package/schema.json +41 -5
- package/src/index.ts +1 -3
- package/src/onebot11-agent-deps.ts +8 -8
- package/src/protocol.ts +48 -53
- package/src/ws-endpoint.ts +36 -26
- package/src/ws-transport.ts +2 -2
- package/src/wss-endpoint.ts +32 -23
- /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/lib/wss-endpoint.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* OneBot11 reverse WSS endpoint — accepts inbound WebSocket from OneBot implementation.
|
|
3
3
|
*/
|
|
4
4
|
import { clearInterval } from 'node:timers';
|
|
5
|
-
import { formatCompact,
|
|
5
|
+
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
6
6
|
import { createOneBot11EndpointManagement } from './endpoint-management.js';
|
|
7
7
|
import { registerOnebot11AgentEndpoint } from './onebot11-agent-deps.js';
|
|
8
|
-
import { buildSendAction, formatInboundContent, formatInboundMetadata,
|
|
8
|
+
import { buildSendAction, formatInboundContent, formatInboundMetadata, formatOutboundSegments, isMessageEvent, onebot11InboundConversation, senderDisplayName, senderUserId, } from './protocol.js';
|
|
9
9
|
import { verifyOneBotAccessToken } from './wss-auth.js';
|
|
10
10
|
import { callOneBot11WsAction, handleOneBot11WsMessage, rejectAllPending, startOneBot11Heartbeat, } from './ws-transport.js';
|
|
11
|
-
const logger = getLogger('onebot11');
|
|
12
11
|
export class OneBot11WssEndpoint {
|
|
12
|
+
#logger;
|
|
13
13
|
#options;
|
|
14
14
|
management = createOneBot11EndpointManagement(this);
|
|
15
15
|
#ws;
|
|
@@ -21,6 +21,7 @@ export class OneBot11WssEndpoint {
|
|
|
21
21
|
#started = false;
|
|
22
22
|
#unregisterAgent;
|
|
23
23
|
constructor(options) {
|
|
24
|
+
this.#logger = getAdapterLogger('onebot11', options.config.id);
|
|
24
25
|
this.#options = options;
|
|
25
26
|
}
|
|
26
27
|
async start() {
|
|
@@ -29,21 +30,21 @@ export class OneBot11WssEndpoint {
|
|
|
29
30
|
this.#started = true;
|
|
30
31
|
if (!this.#options.config.access_token) {
|
|
31
32
|
// wss 模式未配 access_token 时任何连接都会被放行(verifyOneBotAccessToken 直接 return true)
|
|
32
|
-
logger.warn(formatCompact({
|
|
33
|
-
endpoint: this.#options.config.
|
|
33
|
+
this.#logger.warn(formatCompact({
|
|
34
|
+
endpoint: this.#options.config.id,
|
|
34
35
|
mode: 'wss',
|
|
35
36
|
ok: false,
|
|
36
37
|
error: 'missing access_token',
|
|
37
38
|
}));
|
|
38
39
|
}
|
|
39
|
-
this.#unregisterAgent = registerOnebot11AgentEndpoint(this.#options.config.
|
|
40
|
+
this.#unregisterAgent = registerOnebot11AgentEndpoint(this.#options.config.id, this);
|
|
40
41
|
const handle = this.#options.http.ws(this.#options.config.path);
|
|
41
42
|
this.#wsRelease = handle.onConnection((connection) => {
|
|
42
43
|
this.#acceptConnection(connection);
|
|
43
44
|
});
|
|
44
|
-
logger.info(formatCompact({
|
|
45
|
+
this.#logger.info(formatCompact({
|
|
45
46
|
op: 'listen',
|
|
46
|
-
endpoint: this.#options.config.
|
|
47
|
+
endpoint: this.#options.config.id,
|
|
47
48
|
mode: 'wss',
|
|
48
49
|
path: this.#options.config.path,
|
|
49
50
|
}));
|
|
@@ -76,9 +77,9 @@ export class OneBot11WssEndpoint {
|
|
|
76
77
|
}
|
|
77
78
|
this.#started = false;
|
|
78
79
|
}
|
|
79
|
-
async send({
|
|
80
|
+
async send({ conversation, payload }) {
|
|
80
81
|
const message = formatOutboundSegments(payload);
|
|
81
|
-
const { action, params } = buildSendAction(
|
|
82
|
+
const { action, params } = buildSendAction(conversation, message);
|
|
82
83
|
const data = await this.callApi(action, params);
|
|
83
84
|
return data?.message_id != null ? String(data.message_id) : '';
|
|
84
85
|
}
|
|
@@ -102,18 +103,25 @@ export class OneBot11WssEndpoint {
|
|
|
102
103
|
admit(ev) {
|
|
103
104
|
if (!this.#open || !isMessageEvent(ev))
|
|
104
105
|
return;
|
|
105
|
-
const
|
|
106
|
+
const conversation = onebot11InboundConversation(String(this.#options.id), ev);
|
|
107
|
+
const inbound = formatInboundMetadata(ev, this.#options.config.id);
|
|
106
108
|
void this.#options.gateway.receive({
|
|
107
|
-
|
|
108
|
-
|
|
109
|
+
conversation,
|
|
110
|
+
message: { conversation, id: String(ev.message_id) },
|
|
109
111
|
content: formatInboundContent(ev),
|
|
110
|
-
sender:
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
sender: {
|
|
113
|
+
id: senderUserId(ev),
|
|
114
|
+
name: senderDisplayName(ev) || undefined,
|
|
115
|
+
...(ev.sender?.role ? { roles: [ev.sender.role] } : {}),
|
|
116
|
+
},
|
|
117
|
+
endpointId: inbound.endpointId,
|
|
118
|
+
...(inbound.mentioned ? { mentioned: true } : {}),
|
|
119
|
+
...(inbound.replyTo ? { replyTo: inbound.replyTo } : {}),
|
|
120
|
+
metadata: inbound.metadata,
|
|
113
121
|
}).catch((err) => {
|
|
114
|
-
logger.warn(formatCompact({
|
|
122
|
+
this.#logger.warn(formatCompact({
|
|
115
123
|
op: 'onebot11_gateway_receive_failed',
|
|
116
|
-
target
|
|
124
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
117
125
|
error: err instanceof Error ? err.message : String(err),
|
|
118
126
|
}));
|
|
119
127
|
});
|
|
@@ -136,7 +144,7 @@ export class OneBot11WssEndpoint {
|
|
|
136
144
|
this.#heartbeatTimer = startOneBot11Heartbeat(this.#ws, this.#options.config.heartbeat_interval, this.#heartbeatTimer);
|
|
137
145
|
socket.on('message', (data) => {
|
|
138
146
|
handleOneBot11WsMessage(data, {
|
|
139
|
-
|
|
147
|
+
endpointId: this.#options.config.id,
|
|
140
148
|
pending: this.#pending,
|
|
141
149
|
admit: (ev) => this.admit(ev),
|
|
142
150
|
});
|
|
@@ -150,8 +158,8 @@ export class OneBot11WssEndpoint {
|
|
|
150
158
|
}
|
|
151
159
|
}
|
|
152
160
|
});
|
|
153
|
-
logger.debug(formatCompact({
|
|
154
|
-
endpoint: this.#options.config.
|
|
161
|
+
this.#logger.debug(formatCompact({
|
|
162
|
+
endpoint: this.#options.config.id,
|
|
155
163
|
mode: 'wss',
|
|
156
164
|
peer: connection.request.socket.remoteAddress,
|
|
157
165
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-onebot11",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.5",
|
|
4
4
|
"description": "Zhin.js OneBot 11 adapter for Plugin Runtime (WebSocket client)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -41,12 +41,14 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"ws": "^8.21.1",
|
|
44
|
-
"@zhin.js/adapter": "1.1.
|
|
45
|
-
"@zhin.js/command": "1.0.
|
|
46
|
-
"@zhin.js/core": "1.5.
|
|
47
|
-
"@zhin.js/host-http": "1.0.
|
|
48
|
-
"@zhin.js/
|
|
49
|
-
"@zhin.js/
|
|
44
|
+
"@zhin.js/adapter": "1.1.7",
|
|
45
|
+
"@zhin.js/command": "1.0.9",
|
|
46
|
+
"@zhin.js/core": "1.5.4",
|
|
47
|
+
"@zhin.js/host-http": "1.0.8",
|
|
48
|
+
"@zhin.js/im-contract": "1.0.3",
|
|
49
|
+
"@zhin.js/logger": "1.0.76",
|
|
50
|
+
"@zhin.js/permission": "1.0.1",
|
|
51
|
+
"@zhin.js/plugin-runtime": "1.1.5"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"@types/node": "^26.1.2",
|
|
@@ -54,16 +56,16 @@
|
|
|
54
56
|
"typescript": "^6.0.3",
|
|
55
57
|
"vitest": "^4.1.10",
|
|
56
58
|
"zod": "^4.4.3",
|
|
57
|
-
"@zhin.js/agent": "1.1.
|
|
58
|
-
"@zhin.js/host-http": "1.0.
|
|
59
|
+
"@zhin.js/agent": "1.1.5",
|
|
60
|
+
"@zhin.js/host-http": "1.0.8"
|
|
59
61
|
},
|
|
60
62
|
"peerDependencies": {
|
|
61
63
|
"zod": "^4.0.0",
|
|
62
|
-
"@zhin.js/adapter": "1.1.
|
|
63
|
-
"@zhin.js/agent": "1.1.
|
|
64
|
-
"@zhin.js/core": "1.5.
|
|
65
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
66
|
-
"zhin.js": "6.0.
|
|
64
|
+
"@zhin.js/adapter": "1.1.7",
|
|
65
|
+
"@zhin.js/agent": "1.1.5",
|
|
66
|
+
"@zhin.js/core": "1.5.4",
|
|
67
|
+
"@zhin.js/plugin-runtime": "1.1.5",
|
|
68
|
+
"zhin.js": "6.0.4"
|
|
67
69
|
},
|
|
68
70
|
"peerDependenciesMeta": {
|
|
69
71
|
"zhin.js": {
|
package/plugin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { createEndpointRuntimeState } from '@zhin.js/adapter';
|
|
3
3
|
import { definePlugin } from '@zhin.js/plugin-runtime';
|
|
4
|
-
import {
|
|
4
|
+
import { permissionHostToken, createSceneRolePlatformChecker } from '@zhin.js/permission';
|
|
5
5
|
import { onebot11RuntimeStateToken } from "./lib/onebot11-runtime-state.js";
|
|
6
6
|
export default definePlugin({
|
|
7
7
|
name: 'onebot11',
|
|
@@ -9,9 +9,10 @@ export default definePlugin({
|
|
|
9
9
|
displayName: 'OneBot 11 Adapter',
|
|
10
10
|
},
|
|
11
11
|
setup(context) {
|
|
12
|
-
// 运行中 endpoint 注册表(onebot11.endpoint list 的"运行中"数据源)
|
|
13
12
|
context.resources.provide(onebot11RuntimeStateToken, createEndpointRuntimeState());
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
if (context.resources.has(permissionHostToken)) {
|
|
14
|
+
const host = context.resources.use(permissionHostToken);
|
|
15
|
+
return host.registerPlatform('onebot11', createSceneRolePlatformChecker());
|
|
16
|
+
}
|
|
16
17
|
},
|
|
17
18
|
});
|
package/schema.json
CHANGED
|
@@ -20,16 +20,48 @@
|
|
|
20
20
|
"type": "number",
|
|
21
21
|
"default": 30000
|
|
22
22
|
},
|
|
23
|
+
"master": {
|
|
24
|
+
"type": [
|
|
25
|
+
"string",
|
|
26
|
+
"number"
|
|
27
|
+
],
|
|
28
|
+
"description": "框架 master(platform user id;AI/工具权限、endpoint 管理)。endpoints[i].master 可逐项覆盖"
|
|
29
|
+
},
|
|
30
|
+
"trusted": {
|
|
31
|
+
"type": "array",
|
|
32
|
+
"items": {
|
|
33
|
+
"type": [
|
|
34
|
+
"string",
|
|
35
|
+
"number"
|
|
36
|
+
],
|
|
37
|
+
"description": "Trusted platform user id"
|
|
38
|
+
},
|
|
39
|
+
"description": "框架 trusted 用户列表(弱于 master)。endpoints[i].trusted 可逐项追加"
|
|
40
|
+
},
|
|
23
41
|
"endpoints": {
|
|
24
42
|
"type": "array",
|
|
25
|
-
"description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(
|
|
43
|
+
"description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(id 必填,其余覆盖顶层)",
|
|
26
44
|
"items": {
|
|
27
45
|
"type": "object",
|
|
28
46
|
"additionalProperties": true,
|
|
29
47
|
"properties": {
|
|
30
|
-
"
|
|
31
|
-
"type":
|
|
32
|
-
|
|
48
|
+
"master": {
|
|
49
|
+
"type": [
|
|
50
|
+
"string",
|
|
51
|
+
"number"
|
|
52
|
+
],
|
|
53
|
+
"description": "本 endpoint 的框架 master(platform user id);覆盖顶层 master"
|
|
54
|
+
},
|
|
55
|
+
"trusted": {
|
|
56
|
+
"type": "array",
|
|
57
|
+
"items": {
|
|
58
|
+
"type": [
|
|
59
|
+
"string",
|
|
60
|
+
"number"
|
|
61
|
+
],
|
|
62
|
+
"description": "Trusted platform user id"
|
|
63
|
+
},
|
|
64
|
+
"description": "本 endpoint 的 trusted 列表"
|
|
33
65
|
},
|
|
34
66
|
"url": {
|
|
35
67
|
"type": "string",
|
|
@@ -42,10 +74,14 @@
|
|
|
42
74
|
"access_token": {
|
|
43
75
|
"type": "string",
|
|
44
76
|
"description": "OneBot access token"
|
|
77
|
+
},
|
|
78
|
+
"id": {
|
|
79
|
+
"type": "string",
|
|
80
|
+
"description": "OneBot11 bot name"
|
|
45
81
|
}
|
|
46
82
|
},
|
|
47
83
|
"required": [
|
|
48
|
-
"
|
|
84
|
+
"id"
|
|
49
85
|
]
|
|
50
86
|
}
|
|
51
87
|
},
|
package/src/index.ts
CHANGED
|
@@ -4,13 +4,12 @@ export {
|
|
|
4
4
|
extractQuoteId,
|
|
5
5
|
formatInboundContent,
|
|
6
6
|
formatInboundMetadata,
|
|
7
|
-
formatInboundTarget,
|
|
8
7
|
formatOutboundSegments,
|
|
9
8
|
getChannelId,
|
|
10
9
|
isMessageEvent,
|
|
11
10
|
isOneBot11BotMentioned,
|
|
12
11
|
mediaRefToOneBotFile,
|
|
13
|
-
|
|
12
|
+
onebot11InboundConversation,
|
|
14
13
|
resolveOneBot11Config,
|
|
15
14
|
senderDisplayName,
|
|
16
15
|
senderNickname,
|
|
@@ -26,7 +25,6 @@ export {
|
|
|
26
25
|
type OneBot11WireSegment,
|
|
27
26
|
type OneBot11WsConfig,
|
|
28
27
|
type OneBot11WssConfig,
|
|
29
|
-
type ParsedSendTarget,
|
|
30
28
|
type ResolvedOneBot11Config,
|
|
31
29
|
} from './protocol.js';
|
|
32
30
|
|
|
@@ -14,20 +14,20 @@ export interface Onebot11AgentEndpoint {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export interface Onebot11AgentDeps {
|
|
17
|
-
getEndpoint: (
|
|
17
|
+
getEndpoint: (endpointKey: string) => Onebot11AgentEndpoint;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const endpoints = new Map<string, Onebot11AgentEndpoint>();
|
|
21
21
|
let override: Onebot11AgentDeps | null = null;
|
|
22
22
|
|
|
23
23
|
export function registerOnebot11AgentEndpoint(
|
|
24
|
-
|
|
24
|
+
endpointKey: string,
|
|
25
25
|
endpoint: Onebot11AgentEndpoint,
|
|
26
26
|
): () => void {
|
|
27
|
-
endpoints.set(
|
|
27
|
+
endpoints.set(endpointKey, endpoint);
|
|
28
28
|
return () => {
|
|
29
|
-
if (endpoints.get(
|
|
30
|
-
endpoints.delete(
|
|
29
|
+
if (endpoints.get(endpointKey) === endpoint) {
|
|
30
|
+
endpoints.delete(endpointKey);
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
}
|
|
@@ -40,9 +40,9 @@ export function setOnebot11AgentDeps(deps: Onebot11AgentDeps): void {
|
|
|
40
40
|
export function getOnebot11AgentDeps(): Onebot11AgentDeps {
|
|
41
41
|
if (override) return override;
|
|
42
42
|
return {
|
|
43
|
-
getEndpoint(
|
|
44
|
-
const registered = endpoints.get(
|
|
45
|
-
if (!registered) throw new Error(`Endpoint ${
|
|
43
|
+
getEndpoint(endpointKey: string): Onebot11AgentEndpoint {
|
|
44
|
+
const registered = endpoints.get(endpointKey);
|
|
45
|
+
if (!registered) throw new Error(`Endpoint ${endpointKey} 不存在`);
|
|
46
46
|
return registered;
|
|
47
47
|
},
|
|
48
48
|
};
|
package/src/protocol.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Spec: https://github.com/botuniverse/onebot-11
|
|
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('onebot11');
|
|
@@ -14,7 +15,7 @@ export interface OneBot11LegacyEndpointRow {
|
|
|
14
15
|
readonly connection?: 'ws' | 'wss';
|
|
15
16
|
/** Legacy alias: `type: 'ws' | 'ws_reverse'` */
|
|
16
17
|
readonly type?: string;
|
|
17
|
-
readonly
|
|
18
|
+
readonly id?: string;
|
|
18
19
|
readonly access_token?: string;
|
|
19
20
|
readonly url?: string;
|
|
20
21
|
readonly path?: string;
|
|
@@ -25,7 +26,7 @@ export interface OneBot11LegacyEndpointRow {
|
|
|
25
26
|
/** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
|
|
26
27
|
export interface OneBot11AdapterConfig {
|
|
27
28
|
readonly connection?: 'ws' | 'wss';
|
|
28
|
-
readonly
|
|
29
|
+
readonly id?: string;
|
|
29
30
|
readonly access_token?: string;
|
|
30
31
|
readonly url?: string;
|
|
31
32
|
readonly path?: string;
|
|
@@ -37,7 +38,7 @@ export interface OneBot11AdapterConfig {
|
|
|
37
38
|
|
|
38
39
|
export interface OneBot11ConfigBase {
|
|
39
40
|
readonly context: 'onebot11';
|
|
40
|
-
readonly
|
|
41
|
+
readonly id: string;
|
|
41
42
|
readonly access_token?: string;
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -106,11 +107,6 @@ export interface OneBot11WireSegment {
|
|
|
106
107
|
readonly data?: Record<string, unknown>;
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
export interface ParsedSendTarget {
|
|
110
|
-
readonly message_type: 'private' | 'group';
|
|
111
|
-
readonly id: string;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
110
|
function normalizeConnection(
|
|
115
111
|
connection: string | undefined,
|
|
116
112
|
legacyType: string | undefined,
|
|
@@ -127,8 +123,8 @@ export function resolveOneBot11Config(config: OneBot11AdapterConfig = {}): Resol
|
|
|
127
123
|
config.connection ?? entry?.connection,
|
|
128
124
|
entry?.type,
|
|
129
125
|
);
|
|
130
|
-
const
|
|
131
|
-
|| (typeof entry?.
|
|
126
|
+
const id = (typeof config.id === 'string' && config.id)
|
|
127
|
+
|| (typeof entry?.id === 'string' && entry.id)
|
|
132
128
|
|| process.env.ONEBOT11_BOT_NAME
|
|
133
129
|
|| 'onebot11-bot';
|
|
134
130
|
const access_token = config.access_token ?? entry?.access_token;
|
|
@@ -143,7 +139,7 @@ export function resolveOneBot11Config(config: OneBot11AdapterConfig = {}): Resol
|
|
|
143
139
|
return {
|
|
144
140
|
context: 'onebot11',
|
|
145
141
|
connection: 'ws',
|
|
146
|
-
|
|
142
|
+
id,
|
|
147
143
|
access_token,
|
|
148
144
|
url,
|
|
149
145
|
reconnect_interval: config.reconnect_interval ?? entry?.reconnect_interval ?? 5000,
|
|
@@ -159,7 +155,7 @@ export function resolveOneBot11Config(config: OneBot11AdapterConfig = {}): Resol
|
|
|
159
155
|
return {
|
|
160
156
|
context: 'onebot11',
|
|
161
157
|
connection: 'wss',
|
|
162
|
-
|
|
158
|
+
id,
|
|
163
159
|
access_token,
|
|
164
160
|
path,
|
|
165
161
|
heartbeat_interval: config.heartbeat_interval ?? entry?.heartbeat_interval ?? 30_000,
|
|
@@ -185,29 +181,19 @@ export function getChannelId(ev: OneBot11Event): string {
|
|
|
185
181
|
}
|
|
186
182
|
|
|
187
183
|
/**
|
|
188
|
-
*
|
|
184
|
+
* 入站归一化 → ConversationRef:OneBot 11 `group` 消息 → kind 'group',
|
|
185
|
+
* 其余(private 及带 group_id 的非 private 事件按群处理)→ kind 'private'。
|
|
186
|
+
* OneBot 11 无 guild/temp 容器概念,不填 parent。
|
|
189
187
|
*/
|
|
190
|
-
export function
|
|
191
|
-
const
|
|
192
|
-
? 'group'
|
|
193
|
-
: 'private';
|
|
194
|
-
return
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (sep <= 0) {
|
|
200
|
-
return { message_type: 'private', id: target };
|
|
201
|
-
}
|
|
202
|
-
const head = target.slice(0, sep);
|
|
203
|
-
const rest = target.slice(sep + 1);
|
|
204
|
-
if (head === 'group') {
|
|
205
|
-
return { message_type: 'group', id: rest };
|
|
206
|
-
}
|
|
207
|
-
if (head === 'private') {
|
|
208
|
-
return { message_type: 'private', id: rest };
|
|
209
|
-
}
|
|
210
|
-
return { message_type: 'private', id: target };
|
|
188
|
+
export function onebot11InboundConversation(endpointKey: string, ev: OneBot11Event): ConversationRef {
|
|
189
|
+
const kind = ev.message_type === 'group' || (ev.group_id != null && ev.message_type !== 'private')
|
|
190
|
+
? 'group' as const
|
|
191
|
+
: 'private' as const;
|
|
192
|
+
return {
|
|
193
|
+
endpoint: { id: endpointKey, adapter: endpointKey.split('\0')[0] ?? endpointKey },
|
|
194
|
+
kind,
|
|
195
|
+
id: getChannelId(ev),
|
|
196
|
+
};
|
|
211
197
|
}
|
|
212
198
|
|
|
213
199
|
/** Build inbound text for MessageGateway.receive */
|
|
@@ -273,27 +259,37 @@ export function isOneBot11BotMentioned(input: {
|
|
|
273
259
|
});
|
|
274
260
|
}
|
|
275
261
|
|
|
276
|
-
/**
|
|
262
|
+
/** Inbound fields extracted from an event for gateway.receive (ws / wss 两个 endpoint 共用). */
|
|
263
|
+
export interface OneBot11InboundFields {
|
|
264
|
+
readonly metadata: Readonly<Record<string, unknown>>;
|
|
265
|
+
readonly endpointId: string;
|
|
266
|
+
readonly mentioned: boolean;
|
|
267
|
+
readonly replyTo: { readonly id: string } | undefined;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** 构造 gateway.receive 的 metadata 与提升字段(ws / wss 两个 endpoint 共用)。 */
|
|
277
271
|
export function formatInboundMetadata(
|
|
278
272
|
ev: OneBot11Event,
|
|
279
273
|
endpoint: string,
|
|
280
|
-
):
|
|
274
|
+
): OneBot11InboundFields {
|
|
281
275
|
const selfId = ev.self_id != null ? String(ev.self_id) : undefined;
|
|
282
276
|
const nickname = senderNickname(ev);
|
|
283
277
|
const quoteId = extractQuoteId(ev);
|
|
284
278
|
const mentioned = isOneBot11BotMentioned({ selfId, message: ev.message });
|
|
285
|
-
return
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
279
|
+
return {
|
|
280
|
+
metadata: Object.freeze({
|
|
281
|
+
message_type: ev.message_type,
|
|
282
|
+
user_id: ev.user_id != null ? String(ev.user_id) : undefined,
|
|
283
|
+
group_id: ev.group_id != null ? String(ev.group_id) : undefined,
|
|
284
|
+
time: ev.time,
|
|
285
|
+
self_id: selfId,
|
|
286
|
+
role: ev.sender?.role,
|
|
287
|
+
...(nickname ? { nickname } : {}),
|
|
288
|
+
}),
|
|
289
|
+
endpointId: endpoint,
|
|
290
|
+
mentioned,
|
|
291
|
+
replyTo: quoteId ? { id: quoteId } : undefined,
|
|
292
|
+
};
|
|
297
293
|
}
|
|
298
294
|
|
|
299
295
|
/**
|
|
@@ -420,15 +416,14 @@ export function formatOutboundSegments(payload: unknown): OneBot11Segment[] {
|
|
|
420
416
|
}
|
|
421
417
|
|
|
422
418
|
export function buildSendAction(
|
|
423
|
-
|
|
419
|
+
conversation: ConversationRef,
|
|
424
420
|
message: OneBot11Segment[],
|
|
425
421
|
): { action: string; params: Record<string, unknown> } {
|
|
426
|
-
|
|
427
|
-
if (parsed.message_type === 'group') {
|
|
422
|
+
if (conversation.kind === 'group') {
|
|
428
423
|
return {
|
|
429
424
|
action: 'send_group_msg',
|
|
430
425
|
params: {
|
|
431
|
-
group_id: Number(
|
|
426
|
+
group_id: Number(conversation.id) || conversation.id,
|
|
432
427
|
message,
|
|
433
428
|
},
|
|
434
429
|
};
|
|
@@ -436,7 +431,7 @@ export function buildSendAction(
|
|
|
436
431
|
return {
|
|
437
432
|
action: 'send_private_msg',
|
|
438
433
|
params: {
|
|
439
|
-
user_id: Number(
|
|
434
|
+
user_id: Number(conversation.id) || conversation.id,
|
|
440
435
|
message,
|
|
441
436
|
},
|
|
442
437
|
};
|