@zhin.js/adapter-onebot12 5.0.2 → 5.0.4

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 CHANGED
@@ -1,5 +1,45 @@
1
1
  # @zhin.js/adapter-onebot12
2
2
 
3
+ ## 5.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [0de46a8]
8
+ - Updated dependencies [c106ecc]
9
+ - Updated dependencies [ca92e03]
10
+ - Updated dependencies [b0f37ae]
11
+ - Updated dependencies [ba08a2f]
12
+ - Updated dependencies [daffd4c]
13
+ - Updated dependencies [36c7400]
14
+ - Updated dependencies [162fa34]
15
+ - Updated dependencies [e40b048]
16
+ - Updated dependencies [f1708c3]
17
+ - Updated dependencies [e53444f]
18
+ - Updated dependencies [92b0dd7]
19
+ - Updated dependencies [a7df753]
20
+ - @zhin.js/host-http@1.0.8
21
+ - @zhin.js/im-contract@1.0.3
22
+ - @zhin.js/adapter@1.1.7
23
+ - @zhin.js/plugin-runtime@1.1.5
24
+ - @zhin.js/command@1.0.9
25
+ - @zhin.js/core@1.5.4
26
+ - zhin.js@6.0.4
27
+
28
+ ## 5.0.3
29
+
30
+ ### Patch Changes
31
+
32
+ - f8c7a54: fix: im
33
+ - Updated dependencies [f8c7a54]
34
+ - @zhin.js/logger@1.0.76
35
+ - @zhin.js/host-http@1.0.7
36
+ - @zhin.js/adapter@1.1.6
37
+ - @zhin.js/command@1.0.8
38
+ - @zhin.js/core@1.5.3
39
+ - @zhin.js/im-contract@1.0.2
40
+ - @zhin.js/plugin-runtime@1.1.4
41
+ - zhin.js@6.0.3
42
+
3
43
  ## 5.0.2
4
44
 
5
45
  ### Patch Changes
@@ -25,8 +25,8 @@ export default defineAdapter({
25
25
  const config = resolveOneBot12Config(context.config);
26
26
  const gateway = context.use(messageGatewayToken);
27
27
  // 注册到插件运行时状态(onebot12.endpoint list 的"运行中"数据源)
28
- context.use(onebot12RuntimeStateToken).endpoints.set(config.name, {
29
- name: config.name,
28
+ context.use(onebot12RuntimeStateToken).endpoints.set(config.id, {
29
+ id: config.id,
30
30
  mode: config.connection,
31
31
  });
32
32
  if (config.connection === 'webhook') {
@@ -33,8 +33,8 @@ export default defineAdapter<OneBot12AdapterConfig>({
33
33
  const config = resolveOneBot12Config(context.config);
34
34
  const gateway = context.use(messageGatewayToken);
35
35
  // 注册到插件运行时状态(onebot12.endpoint list 的"运行中"数据源)
36
- context.use(onebot12RuntimeStateToken).endpoints.set(config.name, {
37
- name: config.name,
36
+ context.use(onebot12RuntimeStateToken).endpoints.set(config.id, {
37
+ id: config.id,
38
38
  mode: config.connection,
39
39
  });
40
40
  if (config.connection === 'webhook') {
package/lib/protocol.d.ts CHANGED
@@ -9,7 +9,7 @@ import type { ConversationRef } from '@zhin.js/im-contract';
9
9
  export interface OneBot12LegacyEndpointRow {
10
10
  readonly context?: string;
11
11
  readonly connection?: 'ws' | 'webhook' | 'wss';
12
- readonly name?: string;
12
+ readonly id?: string;
13
13
  readonly access_token?: string;
14
14
  readonly url?: string;
15
15
  readonly path?: string;
@@ -20,7 +20,7 @@ export interface OneBot12LegacyEndpointRow {
20
20
  /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
21
21
  export interface OneBot12AdapterConfig {
22
22
  readonly connection?: 'ws' | 'webhook' | 'wss';
23
- readonly name?: string;
23
+ readonly id?: string;
24
24
  readonly access_token?: string;
25
25
  readonly url?: string;
26
26
  readonly path?: string;
@@ -32,7 +32,7 @@ export interface OneBot12AdapterConfig {
32
32
  }
33
33
  export interface OneBot12ConfigBase {
34
34
  readonly context: 'onebot12';
35
- readonly name: string;
35
+ readonly id: string;
36
36
  readonly access_token?: string;
37
37
  }
38
38
  /** 正向 WebSocket:应用连 OneBot 实现的 WS 服务器 */
@@ -114,7 +114,7 @@ export declare function getChannelId(ev: OneBot12Event): string;
114
114
  * 进 `parent`(kind 'channel');私聊临时会话(private 事件携带 group_id)映射为
115
115
  * group 容器内的 private 会话。
116
116
  */
117
- export declare function onebot12InboundConversation(endpointId: string, ev: OneBot12Event): ConversationRef;
117
+ export declare function onebot12InboundConversation(endpointKey: string, ev: OneBot12Event): ConversationRef;
118
118
  /** Build inbound text for MessageGateway.receive */
119
119
  export declare function formatInboundContent(ev: OneBot12Event): string;
120
120
  /**
package/lib/protocol.js CHANGED
@@ -11,8 +11,8 @@ export function resolveOneBot12Config(config = {}) {
11
11
  const connection = config.connection
12
12
  ?? entry?.connection
13
13
  ?? 'ws';
14
- const name = (typeof config.name === 'string' && config.name)
15
- || (typeof entry?.name === 'string' && entry.name)
14
+ const id = (typeof config.id === 'string' && config.id)
15
+ || (typeof entry?.id === 'string' && entry.id)
16
16
  || process.env.ONEBOT12_BOT_NAME
17
17
  || 'onebot12-bot';
18
18
  const access_token = config.access_token ?? entry?.access_token;
@@ -24,7 +24,7 @@ export function resolveOneBot12Config(config = {}) {
24
24
  return {
25
25
  context: 'onebot12',
26
26
  connection: 'ws',
27
- name,
27
+ id,
28
28
  access_token,
29
29
  url,
30
30
  reconnect_interval: config.reconnect_interval ?? entry?.reconnect_interval ?? 5000,
@@ -39,7 +39,7 @@ export function resolveOneBot12Config(config = {}) {
39
39
  return {
40
40
  context: 'onebot12',
41
41
  connection: 'webhook',
42
- name,
42
+ id,
43
43
  access_token,
44
44
  path,
45
45
  api_url: config.api_url ?? entry?.api_url,
@@ -53,7 +53,7 @@ export function resolveOneBot12Config(config = {}) {
53
53
  return {
54
54
  context: 'onebot12',
55
55
  connection: 'wss',
56
- name,
56
+ id,
57
57
  access_token,
58
58
  path,
59
59
  heartbeat_interval: config.heartbeat_interval ?? entry?.heartbeat_interval ?? 30_000,
@@ -81,8 +81,8 @@ export function getChannelId(ev) {
81
81
  * 进 `parent`(kind 'channel');私聊临时会话(private 事件携带 group_id)映射为
82
82
  * group 容器内的 private 会话。
83
83
  */
84
- export function onebot12InboundConversation(endpointId, ev) {
85
- const endpoint = { id: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId };
84
+ export function onebot12InboundConversation(endpointKey, ev) {
85
+ const endpoint = { id: endpointKey, adapter: endpointKey.split('\0')[0] ?? endpointKey };
86
86
  if (ev.detail_type === 'group' && ev.group_id) {
87
87
  return { endpoint, kind: 'group', id: ev.group_id };
88
88
  }
package/lib/webhook.js CHANGED
@@ -21,7 +21,7 @@ export class OneBot12WebhookEndpoint {
21
21
  if (!this.#options.config.access_token) {
22
22
  // webhook 模式未配 access_token 时任何 POST 都会被放行(verifyOneBotAccessToken 直接 return true)
23
23
  logger.warn(formatCompact({
24
- endpoint: this.#options.config.name,
24
+ endpoint: this.#options.config.id,
25
25
  mode: 'webhook',
26
26
  ok: false,
27
27
  error: 'missing access_token',
@@ -30,7 +30,7 @@ export class OneBot12WebhookEndpoint {
30
30
  this.#setupRoutes();
31
31
  logger.info(formatCompact({
32
32
  op: 'listen',
33
- endpoint: this.#options.config.name,
33
+ endpoint: this.#options.config.id,
34
34
  mode: 'webhook',
35
35
  path: this.#options.config.path,
36
36
  }));
@@ -46,13 +46,13 @@ export class OneBot12WebhookEndpoint {
46
46
  for (const release of this.#routeReleases.splice(0))
47
47
  release();
48
48
  this.#started = false;
49
- logger.debug(formatCompact({ op: 'disconnect', endpoint: this.#options.config.name }));
49
+ logger.debug(formatCompact({ op: 'disconnect', endpoint: this.#options.config.id }));
50
50
  }
51
51
  async send({ conversation, payload }) {
52
52
  const materialized = await uploadOneBot12MediaSegments(payload, (action, params) => this.callApi(action, params), (error) => {
53
53
  logger.warn(formatCompact({
54
54
  op: 'onebot12_upload_failed',
55
- endpoint: this.#options.config.name,
55
+ endpoint: this.#options.config.id,
56
56
  error: error instanceof Error ? error.message : String(error),
57
57
  }));
58
58
  });
@@ -62,7 +62,7 @@ export class OneBot12WebhookEndpoint {
62
62
  const messageId = data?.message_id ?? '';
63
63
  logger.debug(formatCompact({
64
64
  op: 'onebot12_send',
65
- endpoint: this.#options.config.name,
65
+ endpoint: this.#options.config.id,
66
66
  kind: conversation.kind,
67
67
  conversationId: conversation.id,
68
68
  messageId,
@@ -89,17 +89,17 @@ export class OneBot12WebhookEndpoint {
89
89
  conversation,
90
90
  message: { conversation, id: ev.message_id },
91
91
  content,
92
- sender: senderUserId(ev),
92
+ sender: { id: senderUserId(ev), ...(nickname ? { name: nickname } : {}) },
93
+ endpointId: this.#options.config.id,
94
+ ...(mentioned ? { mentioned: true } : {}),
93
95
  metadata: Object.freeze({
94
96
  detail_type: ev.detail_type,
95
97
  user_id: ev.user_id,
96
98
  group_id: ev.group_id,
97
99
  channel_id: ev.channel_id,
98
100
  guild_id: ev.guild_id,
99
- endpoint: this.#options.config.name,
100
101
  time: ev.time,
101
102
  ...(nickname ? { nickname } : {}),
102
- ...(mentioned ? { mentioned: true } : {}),
103
103
  }),
104
104
  }).catch((err) => {
105
105
  logger.warn(formatCompact({
@@ -4,12 +4,12 @@
4
4
  import WebSocket from 'ws';
5
5
  import { clearTimeout } from 'node:timers';
6
6
  import { createEndpointLifecycle, } from '@zhin.js/adapter';
7
- import { formatCompact, getLogger } from '@zhin.js/logger';
7
+ import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
8
8
  import { createOneBot12EndpointManagement } from './endpoint-management.js';
9
9
  import { buildSendMessageParams, buildWsConnectOptions, formatInboundContent, formatOutboundSegments, isBotMentioned, isMessageEvent, onebot12InboundConversation, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
10
10
  import { WS_OPEN, } from './ws-types.js';
11
- const logger = getLogger('onebot12');
12
11
  export class OneBot12WsEndpoint {
12
+ #logger;
13
13
  #options;
14
14
  management = createOneBot12EndpointManagement(this);
15
15
  #lifecycle;
@@ -18,10 +18,11 @@ export class OneBot12WsEndpoint {
18
18
  #pending = new Map();
19
19
  #open = false;
20
20
  constructor(options) {
21
+ this.#logger = getAdapterLogger('onebot12', options.config.id);
21
22
  this.#options = options;
22
23
  const { config } = options;
23
24
  this.#lifecycle = createEndpointLifecycle({
24
- name: config.name,
25
+ name: config.id,
25
26
  reconnect: {
26
27
  initialIntervalMs: config.reconnect_interval,
27
28
  // 固定间隔(multiplier 1、无抖动),对齐旧 reconnect_interval 语义
@@ -71,9 +72,9 @@ export class OneBot12WsEndpoint {
71
72
  }
72
73
  async send({ conversation, payload }) {
73
74
  const materialized = await uploadOneBot12MediaSegments(payload, (action, params) => this.callApi(action, params), (error) => {
74
- logger.warn(formatCompact({
75
+ this.#logger.warn(formatCompact({
75
76
  op: 'onebot12_upload_failed',
76
- endpoint: this.#options.config.name,
77
+ endpoint: this.#options.config.id,
77
78
  error: error instanceof Error ? error.message : String(error),
78
79
  }));
79
80
  });
@@ -81,9 +82,9 @@ export class OneBot12WsEndpoint {
81
82
  const params = buildSendMessageParams(conversation, message);
82
83
  const data = await this.#callAction('send_message', params);
83
84
  const messageId = data?.message_id ?? '';
84
- logger.debug(formatCompact({
85
+ this.#logger.debug(formatCompact({
85
86
  op: 'onebot12_send',
86
- endpoint: this.#options.config.name,
87
+ endpoint: this.#options.config.id,
87
88
  kind: conversation.kind,
88
89
  conversationId: conversation.id,
89
90
  messageId,
@@ -111,20 +112,20 @@ export class OneBot12WsEndpoint {
111
112
  conversation,
112
113
  message: { conversation, id: ev.message_id },
113
114
  content,
114
- sender: senderUserId(ev),
115
+ sender: { id: senderUserId(ev), name: senderNickname(ev) },
116
+ endpointId: this.#options.config.id,
117
+ ...(mentioned ? { mentioned: true } : {}),
115
118
  metadata: Object.freeze({
116
119
  detail_type: ev.detail_type,
117
120
  user_id: ev.user_id,
118
121
  group_id: ev.group_id,
119
122
  channel_id: ev.channel_id,
120
123
  guild_id: ev.guild_id,
121
- endpoint: this.#options.config.name,
122
124
  time: ev.time,
123
125
  ...(nickname ? { nickname } : {}),
124
- ...(mentioned ? { mentioned: true } : {}),
125
126
  }),
126
127
  }).catch((err) => {
127
- logger.warn(formatCompact({
128
+ this.#logger.warn(formatCompact({
128
129
  op: 'onebot12_gateway_receive_failed',
129
130
  kind: conversation.kind,
130
131
  conversationId: conversation.id,
@@ -152,8 +153,8 @@ export class OneBot12WsEndpoint {
152
153
  if (settled)
153
154
  return;
154
155
  settled = true;
155
- logger.debug(formatCompact({
156
- endpoint: this.#options.config.name,
156
+ this.#logger.debug(formatCompact({
157
+ endpoint: this.#options.config.id,
157
158
  mode: 'ws',
158
159
  url: safeUrl,
159
160
  }));
@@ -182,9 +183,9 @@ export class OneBot12WsEndpoint {
182
183
  });
183
184
  ws.on('error', (err) => {
184
185
  const error = err instanceof Error ? err : new Error(String(err));
185
- logger.warn(formatCompact({
186
+ this.#logger.warn(formatCompact({
186
187
  op: 'ws_error',
187
- endpoint: this.#options.config.name,
188
+ endpoint: this.#options.config.id,
188
189
  ok: false,
189
190
  error: error.message,
190
191
  }));
@@ -221,9 +222,9 @@ export class OneBot12WsEndpoint {
221
222
  this.admit(msg);
222
223
  }
223
224
  catch (error) {
224
- logger.warn(formatCompact({
225
+ this.#logger.warn(formatCompact({
225
226
  op: 'onebot12_parse_failed',
226
- endpoint: this.#options.config.name,
227
+ endpoint: this.#options.config.id,
227
228
  error: error instanceof Error ? error.message : String(error),
228
229
  }));
229
230
  }
@@ -2,13 +2,13 @@
2
2
  * OneBot12 reverse WSS endpoint — accepts inbound WebSocket from OneBot implementation.
3
3
  */
4
4
  import { clearInterval } from 'node:timers';
5
- import { formatCompact, getLogger } from '@zhin.js/logger';
5
+ import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
6
6
  import { createOneBot12EndpointManagement } from './endpoint-management.js';
7
7
  import { buildSendMessageParams, formatInboundContent, formatOutboundSegments, isBotMentioned, isMessageEvent, onebot12InboundConversation, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
8
8
  import { verifyOneBotAccessToken } from './wss-auth.js';
9
9
  import { WS_OPEN } from './ws-types.js';
10
- const logger = getLogger('onebot12');
11
10
  export class OneBot12WssEndpoint {
11
+ #logger;
12
12
  #options;
13
13
  management = createOneBot12EndpointManagement(this);
14
14
  #ws;
@@ -19,6 +19,7 @@ export class OneBot12WssEndpoint {
19
19
  #open = false;
20
20
  #started = false;
21
21
  constructor(options) {
22
+ this.#logger = getAdapterLogger('onebot12', options.config.id);
22
23
  this.#options = options;
23
24
  }
24
25
  async start() {
@@ -27,8 +28,8 @@ export class OneBot12WssEndpoint {
27
28
  this.#started = true;
28
29
  if (!this.#options.config.access_token) {
29
30
  // wss 模式未配 access_token 时任何连接都会被放行(verifyOneBotAccessToken 直接 return true)
30
- logger.warn(formatCompact({
31
- endpoint: this.#options.config.name,
31
+ this.#logger.warn(formatCompact({
32
+ endpoint: this.#options.config.id,
32
33
  mode: 'wss',
33
34
  ok: false,
34
35
  error: 'missing access_token',
@@ -38,9 +39,9 @@ export class OneBot12WssEndpoint {
38
39
  this.#wsRelease = handle.onConnection((connection) => {
39
40
  this.#acceptConnection(connection);
40
41
  });
41
- logger.info(formatCompact({
42
+ this.#logger.info(formatCompact({
42
43
  op: 'listen',
43
- endpoint: this.#options.config.name,
44
+ endpoint: this.#options.config.id,
44
45
  mode: 'wss',
45
46
  path: this.#options.config.path,
46
47
  }));
@@ -77,9 +78,9 @@ export class OneBot12WssEndpoint {
77
78
  }
78
79
  async send({ conversation, payload }) {
79
80
  const materialized = await uploadOneBot12MediaSegments(payload, (action, params) => this.callApi(action, params), (error) => {
80
- logger.warn(formatCompact({
81
+ this.#logger.warn(formatCompact({
81
82
  op: 'onebot12_upload_failed',
82
- endpoint: this.#options.config.name,
83
+ endpoint: this.#options.config.id,
83
84
  error: error instanceof Error ? error.message : String(error),
84
85
  }));
85
86
  });
@@ -107,20 +108,20 @@ export class OneBot12WssEndpoint {
107
108
  conversation,
108
109
  message: { conversation, id: ev.message_id },
109
110
  content: formatInboundContent(ev),
110
- sender: senderUserId(ev),
111
+ sender: { id: senderUserId(ev), name: senderNickname(ev) },
112
+ endpointId: this.#options.config.id,
113
+ ...(mentioned ? { mentioned: true } : {}),
111
114
  metadata: Object.freeze({
112
115
  detail_type: ev.detail_type,
113
116
  user_id: ev.user_id,
114
117
  group_id: ev.group_id,
115
118
  channel_id: ev.channel_id,
116
119
  guild_id: ev.guild_id,
117
- endpoint: this.#options.config.name,
118
120
  time: ev.time,
119
121
  ...(nickname ? { nickname } : {}),
120
- ...(mentioned ? { mentioned: true } : {}),
121
122
  }),
122
123
  }).catch((err) => {
123
- logger.warn(formatCompact({
124
+ this.#logger.warn(formatCompact({
124
125
  op: 'onebot12_gateway_receive_failed',
125
126
  kind: conversation.kind,
126
127
  conversationId: conversation.id,
@@ -156,8 +157,8 @@ export class OneBot12WssEndpoint {
156
157
  }
157
158
  }
158
159
  });
159
- logger.debug(formatCompact({
160
- endpoint: this.#options.config.name,
160
+ this.#logger.debug(formatCompact({
161
+ endpoint: this.#options.config.id,
161
162
  mode: 'wss',
162
163
  peer: connection.request.socket.remoteAddress,
163
164
  }));
@@ -188,9 +189,9 @@ export class OneBot12WssEndpoint {
188
189
  this.admit(msg);
189
190
  }
190
191
  catch (error) {
191
- logger.warn(formatCompact({
192
+ this.#logger.warn(formatCompact({
192
193
  op: 'onebot12_parse_failed',
193
- endpoint: this.#options.config.name,
194
+ endpoint: this.#options.config.id,
194
195
  error: error instanceof Error ? error.message : String(error),
195
196
  }));
196
197
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-onebot12",
3
- "version": "5.0.2",
3
+ "version": "5.0.4",
4
4
  "description": "Zhin.js OneBot 12 adapter for Plugin Runtime (WebSocket client)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -40,26 +40,26 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "ws": "^8.21.1",
43
- "@zhin.js/adapter": "1.1.5",
44
- "@zhin.js/command": "1.0.7",
45
- "@zhin.js/core": "1.5.2",
46
- "@zhin.js/host-http": "1.0.6",
47
- "@zhin.js/logger": "1.0.75",
48
- "@zhin.js/plugin-runtime": "1.1.3",
49
- "@zhin.js/im-contract": "1.0.1"
43
+ "@zhin.js/adapter": "1.1.7",
44
+ "@zhin.js/command": "1.0.9",
45
+ "@zhin.js/core": "1.5.4",
46
+ "@zhin.js/host-http": "1.0.8",
47
+ "@zhin.js/im-contract": "1.0.3",
48
+ "@zhin.js/logger": "1.0.76",
49
+ "@zhin.js/plugin-runtime": "1.1.5"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/node": "^26.1.2",
53
53
  "@types/ws": "^8.18.1",
54
54
  "typescript": "^6.0.3",
55
55
  "vitest": "^4.1.10",
56
- "@zhin.js/host-http": "1.0.6"
56
+ "@zhin.js/host-http": "1.0.8"
57
57
  },
58
58
  "peerDependencies": {
59
- "@zhin.js/adapter": "1.1.5",
60
- "@zhin.js/core": "1.5.2",
61
- "@zhin.js/plugin-runtime": "1.1.3",
62
- "zhin.js": "6.0.2"
59
+ "@zhin.js/adapter": "1.1.7",
60
+ "@zhin.js/core": "1.5.4",
61
+ "@zhin.js/plugin-runtime": "1.1.5",
62
+ "zhin.js": "6.0.4"
63
63
  },
64
64
  "peerDependenciesMeta": {
65
65
  "zhin.js": {
package/schema.json CHANGED
@@ -21,16 +21,48 @@
21
21
  "type": "number",
22
22
  "default": 30000
23
23
  },
24
+ "master": {
25
+ "type": [
26
+ "string",
27
+ "number"
28
+ ],
29
+ "description": "框架 master(platform user id;AI/工具权限、endpoint 管理)。endpoints[i].master 可逐项覆盖"
30
+ },
31
+ "trusted": {
32
+ "type": "array",
33
+ "items": {
34
+ "type": [
35
+ "string",
36
+ "number"
37
+ ],
38
+ "description": "Trusted platform user id"
39
+ },
40
+ "description": "框架 trusted 用户列表(弱于 master)。endpoints[i].trusted 可逐项追加"
41
+ },
24
42
  "endpoints": {
25
43
  "type": "array",
26
- "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(name 必填,其余覆盖顶层)",
44
+ "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(id 必填,其余覆盖顶层)",
27
45
  "items": {
28
46
  "type": "object",
29
47
  "additionalProperties": true,
30
48
  "properties": {
31
- "name": {
32
- "type": "string",
33
- "description": "OneBot12 bot name"
49
+ "master": {
50
+ "type": [
51
+ "string",
52
+ "number"
53
+ ],
54
+ "description": "本 endpoint 的框架 master(platform user id);覆盖顶层 master"
55
+ },
56
+ "trusted": {
57
+ "type": "array",
58
+ "items": {
59
+ "type": [
60
+ "string",
61
+ "number"
62
+ ],
63
+ "description": "Trusted platform user id"
64
+ },
65
+ "description": "本 endpoint 的 trusted 列表"
34
66
  },
35
67
  "url": {
36
68
  "type": "string",
@@ -47,10 +79,14 @@
47
79
  "access_token": {
48
80
  "type": "string",
49
81
  "description": "OneBot access token"
82
+ },
83
+ "id": {
84
+ "type": "string",
85
+ "description": "OneBot12 bot name"
50
86
  }
51
87
  },
52
88
  "required": [
53
- "name"
89
+ "id"
54
90
  ]
55
91
  }
56
92
  },
package/src/protocol.ts CHANGED
@@ -13,7 +13,7 @@ const logger = getLogger('onebot12');
13
13
  export interface OneBot12LegacyEndpointRow {
14
14
  readonly context?: string;
15
15
  readonly connection?: 'ws' | 'webhook' | 'wss';
16
- readonly name?: string;
16
+ readonly id?: string;
17
17
  readonly access_token?: string;
18
18
  readonly url?: string;
19
19
  readonly path?: string;
@@ -25,7 +25,7 @@ export interface OneBot12LegacyEndpointRow {
25
25
  /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
26
26
  export interface OneBot12AdapterConfig {
27
27
  readonly connection?: 'ws' | 'webhook' | 'wss';
28
- readonly name?: string;
28
+ readonly id?: string;
29
29
  readonly access_token?: string;
30
30
  readonly url?: string;
31
31
  readonly path?: string;
@@ -38,7 +38,7 @@ export interface OneBot12AdapterConfig {
38
38
 
39
39
  export interface OneBot12ConfigBase {
40
40
  readonly context: 'onebot12';
41
- readonly name: string;
41
+ readonly id: string;
42
42
  readonly access_token?: string;
43
43
  }
44
44
 
@@ -124,8 +124,8 @@ export function resolveOneBot12Config(config: OneBot12AdapterConfig = {}): Resol
124
124
  const connection = config.connection
125
125
  ?? entry?.connection
126
126
  ?? 'ws';
127
- const name = (typeof config.name === 'string' && config.name)
128
- || (typeof entry?.name === 'string' && entry.name)
127
+ const id = (typeof config.id === 'string' && config.id)
128
+ || (typeof entry?.id === 'string' && entry.id)
129
129
  || process.env.ONEBOT12_BOT_NAME
130
130
  || 'onebot12-bot';
131
131
  const access_token = config.access_token ?? entry?.access_token;
@@ -140,7 +140,7 @@ export function resolveOneBot12Config(config: OneBot12AdapterConfig = {}): Resol
140
140
  return {
141
141
  context: 'onebot12',
142
142
  connection: 'ws',
143
- name,
143
+ id,
144
144
  access_token,
145
145
  url,
146
146
  reconnect_interval: config.reconnect_interval ?? entry?.reconnect_interval ?? 5000,
@@ -156,7 +156,7 @@ export function resolveOneBot12Config(config: OneBot12AdapterConfig = {}): Resol
156
156
  return {
157
157
  context: 'onebot12',
158
158
  connection: 'webhook',
159
- name,
159
+ id,
160
160
  access_token,
161
161
  path,
162
162
  api_url: config.api_url ?? entry?.api_url,
@@ -171,7 +171,7 @@ export function resolveOneBot12Config(config: OneBot12AdapterConfig = {}): Resol
171
171
  return {
172
172
  context: 'onebot12',
173
173
  connection: 'wss',
174
- name,
174
+ id,
175
175
  access_token,
176
176
  path,
177
177
  heartbeat_interval: config.heartbeat_interval ?? entry?.heartbeat_interval ?? 30_000,
@@ -203,8 +203,8 @@ export function getChannelId(ev: OneBot12Event): string {
203
203
  * 进 `parent`(kind 'channel');私聊临时会话(private 事件携带 group_id)映射为
204
204
  * group 容器内的 private 会话。
205
205
  */
206
- export function onebot12InboundConversation(endpointId: string, ev: OneBot12Event): ConversationRef {
207
- const endpoint = { id: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId };
206
+ export function onebot12InboundConversation(endpointKey: string, ev: OneBot12Event): ConversationRef {
207
+ const endpoint = { id: endpointKey, adapter: endpointKey.split('\0')[0] ?? endpointKey };
208
208
  if (ev.detail_type === 'group' && ev.group_id) {
209
209
  return { endpoint, kind: 'group', id: ev.group_id };
210
210
  }
package/src/webhook.ts CHANGED
@@ -53,7 +53,7 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
53
53
  if (!this.#options.config.access_token) {
54
54
  // webhook 模式未配 access_token 时任何 POST 都会被放行(verifyOneBotAccessToken 直接 return true)
55
55
  logger.warn(formatCompact({
56
- endpoint: this.#options.config.name,
56
+ endpoint: this.#options.config.id,
57
57
  mode: 'webhook',
58
58
  ok: false,
59
59
  error: 'missing access_token',
@@ -62,7 +62,7 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
62
62
  this.#setupRoutes();
63
63
  logger.info(formatCompact({
64
64
  op: 'listen',
65
- endpoint: this.#options.config.name,
65
+ endpoint: this.#options.config.id,
66
66
  mode: 'webhook',
67
67
  path: this.#options.config.path,
68
68
  }));
@@ -80,7 +80,7 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
80
80
  this.#open = false;
81
81
  for (const release of this.#routeReleases.splice(0)) release();
82
82
  this.#started = false;
83
- logger.debug(formatCompact({ op: 'disconnect', endpoint: this.#options.config.name }));
83
+ logger.debug(formatCompact({ op: 'disconnect', endpoint: this.#options.config.id }));
84
84
  }
85
85
 
86
86
  async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
@@ -90,7 +90,7 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
90
90
  (error) => {
91
91
  logger.warn(formatCompact({
92
92
  op: 'onebot12_upload_failed',
93
- endpoint: this.#options.config.name,
93
+ endpoint: this.#options.config.id,
94
94
  error: error instanceof Error ? error.message : String(error),
95
95
  }));
96
96
  },
@@ -101,7 +101,7 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
101
101
  const messageId = data?.message_id ?? '';
102
102
  logger.debug(formatCompact({
103
103
  op: 'onebot12_send',
104
- endpoint: this.#options.config.name,
104
+ endpoint: this.#options.config.id,
105
105
  kind: conversation.kind,
106
106
  conversationId: conversation.id,
107
107
  messageId,
@@ -133,17 +133,17 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
133
133
  conversation,
134
134
  message: { conversation, id: ev.message_id },
135
135
  content,
136
- sender: senderUserId(ev),
136
+ sender: { id: senderUserId(ev), ...(nickname ? { name: nickname } : {}) },
137
+ endpointId: this.#options.config.id,
138
+ ...(mentioned ? { mentioned: true } : {}),
137
139
  metadata: Object.freeze({
138
140
  detail_type: ev.detail_type,
139
141
  user_id: ev.user_id,
140
142
  group_id: ev.group_id,
141
143
  channel_id: ev.channel_id,
142
144
  guild_id: ev.guild_id,
143
- endpoint: this.#options.config.name,
144
145
  time: ev.time,
145
146
  ...(nickname ? { nickname } : {}),
146
- ...(mentioned ? { mentioned: true } : {}),
147
147
  }),
148
148
  }).catch((err) => {
149
149
  logger.warn(formatCompact({
@@ -12,7 +12,7 @@ import {
12
12
  type EndpointSendRequest,
13
13
  } from '@zhin.js/adapter';
14
14
  import type { MessageGateway } from '@zhin.js/core/runtime';
15
- import { formatCompact, getLogger } from '@zhin.js/logger';
15
+ import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
16
16
  import type { CapabilityId } from '@zhin.js/plugin-runtime';
17
17
  import { createOneBot12EndpointManagement } from './endpoint-management.js';
18
18
  import {
@@ -37,8 +37,6 @@ import {
37
37
  WS_OPEN,
38
38
  } from './ws-types.js';
39
39
 
40
- const logger = getLogger('onebot12');
41
-
42
40
  export interface OneBot12WsEndpointOptions {
43
41
  readonly id: CapabilityId;
44
42
  readonly gateway: MessageGateway;
@@ -50,6 +48,8 @@ export interface OneBot12WsEndpointOptions {
50
48
  }
51
49
 
52
50
  export class OneBot12WsEndpoint implements EndpointInstance {
51
+ readonly #logger!: ReturnType<typeof getAdapterLogger>;
52
+
53
53
  readonly #options: OneBot12WsEndpointOptions;
54
54
  readonly management: EndpointManagement = createOneBot12EndpointManagement(this);
55
55
  readonly #lifecycle: EndpointLifecycle;
@@ -63,10 +63,11 @@ export class OneBot12WsEndpoint implements EndpointInstance {
63
63
  #open = false;
64
64
 
65
65
  constructor(options: OneBot12WsEndpointOptions) {
66
+ this.#logger = getAdapterLogger('onebot12', options.config.id);
66
67
  this.#options = options;
67
68
  const { config } = options;
68
69
  this.#lifecycle = createEndpointLifecycle({
69
- name: config.name,
70
+ name: config.id,
70
71
  reconnect: {
71
72
  initialIntervalMs: config.reconnect_interval,
72
73
  // 固定间隔(multiplier 1、无抖动),对齐旧 reconnect_interval 语义
@@ -121,9 +122,9 @@ export class OneBot12WsEndpoint implements EndpointInstance {
121
122
  payload,
122
123
  (action, params) => this.callApi(action, params),
123
124
  (error) => {
124
- logger.warn(formatCompact({
125
+ this.#logger.warn(formatCompact({
125
126
  op: 'onebot12_upload_failed',
126
- endpoint: this.#options.config.name,
127
+ endpoint: this.#options.config.id,
127
128
  error: error instanceof Error ? error.message : String(error),
128
129
  }));
129
130
  },
@@ -132,9 +133,9 @@ export class OneBot12WsEndpoint implements EndpointInstance {
132
133
  const params = buildSendMessageParams(conversation, message);
133
134
  const data = await this.#callAction('send_message', params) as { message_id?: string } | undefined;
134
135
  const messageId = data?.message_id ?? '';
135
- logger.debug(formatCompact({
136
+ this.#logger.debug(formatCompact({
136
137
  op: 'onebot12_send',
137
- endpoint: this.#options.config.name,
138
+ endpoint: this.#options.config.id,
138
139
  kind: conversation.kind,
139
140
  conversationId: conversation.id,
140
141
  messageId,
@@ -163,20 +164,20 @@ export class OneBot12WsEndpoint implements EndpointInstance {
163
164
  conversation,
164
165
  message: { conversation, id: ev.message_id },
165
166
  content,
166
- sender: senderUserId(ev),
167
+ sender: { id: senderUserId(ev), name: senderNickname(ev) },
168
+ endpointId: this.#options.config.id,
169
+ ...(mentioned ? { mentioned: true } : {}),
167
170
  metadata: Object.freeze({
168
171
  detail_type: ev.detail_type,
169
172
  user_id: ev.user_id,
170
173
  group_id: ev.group_id,
171
174
  channel_id: ev.channel_id,
172
175
  guild_id: ev.guild_id,
173
- endpoint: this.#options.config.name,
174
176
  time: ev.time,
175
177
  ...(nickname ? { nickname } : {}),
176
- ...(mentioned ? { mentioned: true } : {}),
177
178
  }),
178
179
  }).catch((err) => {
179
- logger.warn(formatCompact({
180
+ this.#logger.warn(formatCompact({
180
181
  op: 'onebot12_gateway_receive_failed',
181
182
  kind: conversation.kind,
182
183
  conversationId: conversation.id,
@@ -206,8 +207,8 @@ export class OneBot12WsEndpoint implements EndpointInstance {
206
207
  ws.on('open', () => {
207
208
  if (settled) return;
208
209
  settled = true;
209
- logger.debug(formatCompact({
210
- endpoint: this.#options.config.name,
210
+ this.#logger.debug(formatCompact({
211
+ endpoint: this.#options.config.id,
211
212
  mode: 'ws',
212
213
  url: safeUrl,
213
214
  }));
@@ -239,9 +240,9 @@ export class OneBot12WsEndpoint implements EndpointInstance {
239
240
 
240
241
  ws.on('error', (err) => {
241
242
  const error = err instanceof Error ? err : new Error(String(err));
242
- logger.warn(formatCompact({
243
+ this.#logger.warn(formatCompact({
243
244
  op: 'ws_error',
244
- endpoint: this.#options.config.name,
245
+ endpoint: this.#options.config.id,
245
246
  ok: false,
246
247
  error: error.message,
247
248
  }));
@@ -276,9 +277,9 @@ export class OneBot12WsEndpoint implements EndpointInstance {
276
277
  }
277
278
  this.admit(msg as OneBot12Event);
278
279
  } catch (error) {
279
- logger.warn(formatCompact({
280
+ this.#logger.warn(formatCompact({
280
281
  op: 'onebot12_parse_failed',
281
- endpoint: this.#options.config.name,
282
+ endpoint: this.#options.config.id,
282
283
  error: error instanceof Error ? error.message : String(error),
283
284
  }));
284
285
  }
@@ -5,7 +5,7 @@ import { clearInterval } from 'node:timers';
5
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, getLogger } from '@zhin.js/logger';
8
+ import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
9
9
  import type { CapabilityId } from '@zhin.js/plugin-runtime';
10
10
  import { createOneBot12EndpointManagement } from './endpoint-management.js';
11
11
  import {
@@ -26,8 +26,6 @@ import {
26
26
  import { verifyOneBotAccessToken } from './wss-auth.js';
27
27
  import { type OneBot12WsSocket, WS_OPEN } from './ws-types.js';
28
28
 
29
- const logger = getLogger('onebot12');
30
-
31
29
  export interface OneBot12WssEndpointOptions {
32
30
  readonly id: CapabilityId;
33
31
  readonly gateway: MessageGateway;
@@ -36,6 +34,8 @@ export interface OneBot12WssEndpointOptions {
36
34
  }
37
35
 
38
36
  export class OneBot12WssEndpoint implements EndpointInstance {
37
+ readonly #logger!: ReturnType<typeof getAdapterLogger>;
38
+
39
39
  readonly #options: OneBot12WssEndpointOptions;
40
40
  readonly management: EndpointManagement = createOneBot12EndpointManagement(this);
41
41
  #ws?: OneBot12WsSocket;
@@ -51,6 +51,7 @@ export class OneBot12WssEndpoint implements EndpointInstance {
51
51
  #started = false;
52
52
 
53
53
  constructor(options: OneBot12WssEndpointOptions) {
54
+ this.#logger = getAdapterLogger('onebot12', options.config.id);
54
55
  this.#options = options;
55
56
  }
56
57
 
@@ -59,8 +60,8 @@ export class OneBot12WssEndpoint implements EndpointInstance {
59
60
  this.#started = true;
60
61
  if (!this.#options.config.access_token) {
61
62
  // wss 模式未配 access_token 时任何连接都会被放行(verifyOneBotAccessToken 直接 return true)
62
- logger.warn(formatCompact({
63
- endpoint: this.#options.config.name,
63
+ this.#logger.warn(formatCompact({
64
+ endpoint: this.#options.config.id,
64
65
  mode: 'wss',
65
66
  ok: false,
66
67
  error: 'missing access_token',
@@ -70,9 +71,9 @@ export class OneBot12WssEndpoint implements EndpointInstance {
70
71
  this.#wsRelease = handle.onConnection((connection) => {
71
72
  this.#acceptConnection(connection);
72
73
  });
73
- logger.info(formatCompact({
74
+ this.#logger.info(formatCompact({
74
75
  op: 'listen',
75
- endpoint: this.#options.config.name,
76
+ endpoint: this.#options.config.id,
76
77
  mode: 'wss',
77
78
  path: this.#options.config.path,
78
79
  }));
@@ -115,9 +116,9 @@ export class OneBot12WssEndpoint implements EndpointInstance {
115
116
  payload,
116
117
  (action, params) => this.callApi(action, params),
117
118
  (error) => {
118
- logger.warn(formatCompact({
119
+ this.#logger.warn(formatCompact({
119
120
  op: 'onebot12_upload_failed',
120
- endpoint: this.#options.config.name,
121
+ endpoint: this.#options.config.id,
121
122
  error: error instanceof Error ? error.message : String(error),
122
123
  }));
123
124
  },
@@ -147,20 +148,20 @@ export class OneBot12WssEndpoint implements EndpointInstance {
147
148
  conversation,
148
149
  message: { conversation, id: ev.message_id },
149
150
  content: formatInboundContent(ev),
150
- sender: senderUserId(ev),
151
+ sender: { id: senderUserId(ev), name: senderNickname(ev) },
152
+ endpointId: this.#options.config.id,
153
+ ...(mentioned ? { mentioned: true } : {}),
151
154
  metadata: Object.freeze({
152
155
  detail_type: ev.detail_type,
153
156
  user_id: ev.user_id,
154
157
  group_id: ev.group_id,
155
158
  channel_id: ev.channel_id,
156
159
  guild_id: ev.guild_id,
157
- endpoint: this.#options.config.name,
158
160
  time: ev.time,
159
161
  ...(nickname ? { nickname } : {}),
160
- ...(mentioned ? { mentioned: true } : {}),
161
162
  }),
162
163
  }).catch((err) => {
163
- logger.warn(formatCompact({
164
+ this.#logger.warn(formatCompact({
164
165
  op: 'onebot12_gateway_receive_failed',
165
166
  kind: conversation.kind,
166
167
  conversationId: conversation.id,
@@ -196,8 +197,8 @@ export class OneBot12WssEndpoint implements EndpointInstance {
196
197
  }
197
198
  }
198
199
  });
199
- logger.debug(formatCompact({
200
- endpoint: this.#options.config.name,
200
+ this.#logger.debug(formatCompact({
201
+ endpoint: this.#options.config.id,
201
202
  mode: 'wss',
202
203
  peer: connection.request.socket.remoteAddress,
203
204
  }));
@@ -226,9 +227,9 @@ export class OneBot12WssEndpoint implements EndpointInstance {
226
227
  }
227
228
  this.admit(msg as OneBot12Event);
228
229
  } catch (error) {
229
- logger.warn(formatCompact({
230
+ this.#logger.warn(formatCompact({
230
231
  op: 'onebot12_parse_failed',
231
- endpoint: this.#options.config.name,
232
+ endpoint: this.#options.config.id,
232
233
  error: error instanceof Error ? error.message : String(error),
233
234
  }));
234
235
  }
File without changes
File without changes
File without changes
File without changes