@zhin.js/adapter-onebot12 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +5 -3
  3. package/adapters/{onebot12.js → onebot12/index.js} +10 -10
  4. package/adapters/{onebot12.ts → onebot12/index.ts} +17 -17
  5. package/commands/{endpoint/add/[id].js → onebot12/endpoint/add/[id]/index.js} +1 -1
  6. package/commands/onebot12/endpoint/add/[id]/index.ts +3 -0
  7. package/{lib/onebot12-endpoint-commands.js → commands/onebot12/endpoint/definition.js} +4 -3
  8. package/{src/onebot12-endpoint-commands.ts → commands/onebot12/endpoint/definition.ts} +3 -3
  9. package/commands/{endpoint/list.js → onebot12/endpoint/list/index.js} +1 -1
  10. package/commands/onebot12/endpoint/list/index.ts +3 -0
  11. package/commands/{endpoint/remove/[id].js → onebot12/endpoint/remove/[id]/index.js} +1 -1
  12. package/commands/onebot12/endpoint/remove/[id]/index.ts +3 -0
  13. package/lib/client.js +1 -1
  14. package/lib/index.d.ts +1 -1
  15. package/lib/onebot12-runtime-state.js +1 -1
  16. package/lib/protocol.d.ts +6 -22
  17. package/lib/protocol.js +44 -28
  18. package/lib/webhook.js +1 -5
  19. package/lib/ws-endpoint.js +16 -52
  20. package/lib/ws-transport.d.ts +12 -0
  21. package/lib/ws-transport.js +58 -0
  22. package/lib/ws-types.d.ts +2 -1
  23. package/lib/wss-endpoint.js +63 -92
  24. package/package.json +19 -14
  25. package/plugin.js +1 -1
  26. package/schema.json +19 -1
  27. package/src/client.ts +1 -1
  28. package/src/index.ts +0 -1
  29. package/src/onebot12-runtime-state.ts +1 -1
  30. package/src/protocol.ts +52 -51
  31. package/src/webhook.ts +1 -5
  32. package/src/ws-endpoint.ts +24 -60
  33. package/src/ws-transport.ts +88 -0
  34. package/src/ws-types.ts +3 -1
  35. package/src/wss-endpoint.ts +69 -99
  36. package/agent/skills/onebot12.md +0 -36
  37. package/commands/endpoint/add/[id].ts +0 -3
  38. package/commands/endpoint/list.ts +0 -3
  39. package/commands/endpoint/remove/[id].ts +0 -3
  40. package/lib/onebot12-endpoint-commands.d.ts +0 -1
@@ -2,7 +2,6 @@
2
2
  * OneBot12 WS client endpoint — outbound connect to OneBot implementation.
3
3
  */
4
4
  import WebSocket from 'ws';
5
- import { clearTimeout } from 'node:timers';
6
5
  import {
7
6
  ClientEndpoint,
8
7
  createRecallEndpointControl,
@@ -27,8 +26,6 @@ import {
27
26
  senderNickname,
28
27
  senderUserId,
29
28
  uploadOneBot12MediaSegments,
30
- type OneBot12ActionRequest,
31
- type OneBot12ActionResponse,
32
29
  type OneBot12Event,
33
30
  type OneBot12WsConfig,
34
31
  } from './protocol.js';
@@ -36,10 +33,15 @@ import { receiveOneBot12SideEvent } from './side-event-dispatch.js';
36
33
  import { createOneBot12ContentPort } from './content-port.js';
37
34
  import { callOnebot12Client, createOnebot12EndpointClient, forwardOnebot12ClientEvents, type Onebot12Client } from './client.js';
38
35
  import {
36
+ type OneBot12PendingAction,
39
37
  type OneBot12WsCreateOptions,
40
38
  type OneBot12WsSocket,
41
- WS_OPEN,
42
39
  } from './ws-types.js';
40
+ import {
41
+ callOneBot12WsAction,
42
+ handleOneBot12WsMessage,
43
+ rejectAllPending,
44
+ } from './ws-transport.js';
43
45
 
44
46
  export interface OneBot12WsEndpointOptions {
45
47
  readonly id: CapabilityId;
@@ -60,12 +62,8 @@ export class OneBot12WsEndpoint extends ClientEndpoint<Onebot12Client> {
60
62
  readonly content;
61
63
  readonly #lifecycle: EndpointLifecycle;
62
64
  #ws?: OneBot12WsSocket;
63
- #requestId = 0;
64
- #pending = new Map<string, {
65
- resolve: (value: OneBot12ActionResponse) => void;
66
- reject: (err: Error) => void;
67
- timeout: NodeJS.Timeout;
68
- }>();
65
+ #requestId = { value: 0 };
66
+ #pending = new Map<string, OneBot12PendingAction>();
69
67
 
70
68
  constructor(options: OneBot12WsEndpointOptions) {
71
69
  super();
@@ -118,11 +116,7 @@ export class OneBot12WsEndpoint extends ClientEndpoint<Onebot12Client> {
118
116
  this.close();
119
117
  // 基座负责:清重连/心跳定时器、强关 ws、唤醒 stop-during-connect 竞态
120
118
  await this.#lifecycle.stop();
121
- for (const [, pending] of this.#pending) {
122
- clearTimeout(pending.timeout);
123
- pending.reject(new Error('连接已关闭'));
124
- }
125
- this.#pending.clear();
119
+ rejectAllPending(this.#pending);
126
120
  this.#ws = undefined;
127
121
  }
128
122
 
@@ -238,7 +232,15 @@ export class OneBot12WsEndpoint extends ClientEndpoint<Onebot12Client> {
238
232
  });
239
233
 
240
234
  ws.on('message', (data) => {
241
- this.#onMessage(data);
235
+ if (this.#ws !== ws) return;
236
+ this.#lifecycle.notifyHeartbeatAck();
237
+ handleOneBot12WsMessage(data, {
238
+ endpointId: this.#options.config.id,
239
+ pending: this.#pending,
240
+ ingest: (event) => this.client.ingest(
241
+ event as Parameters<Onebot12Client['ingest']>[0],
242
+ ),
243
+ });
242
244
  });
243
245
 
244
246
  ws.on('close', (code, reason) => {
@@ -252,6 +254,10 @@ export class OneBot12WsEndpoint extends ClientEndpoint<Onebot12Client> {
252
254
  settled = true;
253
255
  reject(new Error(`OneBot12 WS 关闭: ${codeNum} ${reasonStr}`));
254
256
  }
257
+ if (this.#ws === ws) {
258
+ this.#ws = undefined;
259
+ rejectAllPending(this.#pending);
260
+ }
255
261
  // 断开日志与重连武装均由基座负责;仅曾 open 的连接才会武装重连,
256
262
  // 初始连接失败由 start() 的拒绝路径复位,不产生僵尸重连。
257
263
  handle.notifyClosed(`OneBot12 WS 关闭: ${codeNum} ${reasonStr || 'closed'}`);
@@ -273,49 +279,7 @@ export class OneBot12WsEndpoint extends ClientEndpoint<Onebot12Client> {
273
279
  });
274
280
  }
275
281
 
276
- #onMessage(data: unknown): void {
277
- try {
278
- const raw = typeof data === 'string'
279
- ? data
280
- : Buffer.isBuffer(data)
281
- ? data.toString()
282
- : data instanceof ArrayBuffer
283
- ? new TextDecoder().decode(data)
284
- : String(data ?? '');
285
- const msg = JSON.parse(raw) as OneBot12Event | OneBot12ActionResponse;
286
- if ('echo' in msg && typeof (msg as OneBot12ActionResponse).echo === 'string') {
287
- const resp = msg as OneBot12ActionResponse;
288
- const pending = this.#pending.get(resp.echo!);
289
- if (pending) {
290
- this.#pending.delete(resp.echo!);
291
- clearTimeout(pending.timeout);
292
- pending.resolve(resp);
293
- }
294
- return;
295
- }
296
- this.client.ingest(msg as Parameters<Onebot12Client['ingest']>[0]);
297
- } catch (error) {
298
- this.#logger.warn(formatCompact({
299
- op: 'onebot12_parse_failed',
300
- endpoint: this.#options.config.id,
301
- error: error instanceof Error ? error.message : String(error),
302
- }));
303
- }
304
- }
305
-
306
- #callAction(action: string, params: Record<string, unknown>): Promise<OneBot12ActionResponse> {
307
- if (!this.#ws || this.#ws.readyState !== WS_OPEN) {
308
- return Promise.reject(new Error('WebSocket 未连接'));
309
- }
310
- const echo = `ob12_${++this.#requestId}`;
311
- const req: OneBot12ActionRequest = { action, params, echo };
312
- return new Promise((resolve, reject) => {
313
- const timeout = setTimeout(() => {
314
- this.#pending.delete(echo);
315
- reject(new Error(`OneBot12 动作超时: ${action}`));
316
- }, 30_000);
317
- this.#pending.set(echo, { resolve, reject, timeout });
318
- this.#ws!.send(JSON.stringify(req));
319
- });
282
+ #callAction(action: string, params: Record<string, unknown>) {
283
+ return callOneBot12WsAction(this.#ws, this.#pending, this.#requestId, action, params);
320
284
  }
321
285
  }
@@ -0,0 +1,88 @@
1
+ import { clearTimeout, setTimeout } from 'node:timers';
2
+ import { formatCompact, getLogger } from '@zhin.js/logger';
3
+ import type {
4
+ OneBot12ActionRequest,
5
+ OneBot12ActionResponse,
6
+ OneBot12Event,
7
+ } from './protocol.js';
8
+ import {
9
+ type OneBot12PendingAction,
10
+ type OneBot12WsSocket,
11
+ WS_OPEN,
12
+ } from './ws-types.js';
13
+
14
+ const logger = getLogger('onebot12');
15
+
16
+ export interface OneBot12WsMessageOptions {
17
+ readonly endpointId: string;
18
+ readonly pending: Map<string, OneBot12PendingAction>;
19
+ readonly ingest: (event: OneBot12Event) => void;
20
+ }
21
+
22
+ export function handleOneBot12WsMessage(
23
+ data: unknown,
24
+ options: OneBot12WsMessageOptions,
25
+ ): void {
26
+ try {
27
+ const message = JSON.parse(decodeOneBot12WsPayload(data)) as
28
+ | OneBot12Event
29
+ | OneBot12ActionResponse;
30
+ if ('echo' in message && typeof message.echo === 'string') {
31
+ const response = message as OneBot12ActionResponse;
32
+ const pending = options.pending.get(response.echo!);
33
+ if (pending) {
34
+ options.pending.delete(response.echo!);
35
+ clearTimeout(pending.timeout);
36
+ pending.resolve(response);
37
+ }
38
+ return;
39
+ }
40
+ options.ingest(message as OneBot12Event);
41
+ } catch (error) {
42
+ logger.warn(formatCompact({
43
+ op: 'onebot12_parse_failed',
44
+ endpoint: options.endpointId,
45
+ error: error instanceof Error ? error.message : String(error),
46
+ }));
47
+ }
48
+ }
49
+
50
+ export function callOneBot12WsAction(
51
+ ws: OneBot12WsSocket | undefined,
52
+ pending: Map<string, OneBot12PendingAction>,
53
+ requestId: { value: number },
54
+ action: string,
55
+ params: Record<string, unknown>,
56
+ ): Promise<OneBot12ActionResponse> {
57
+ if (!ws || ws.readyState !== WS_OPEN) {
58
+ return Promise.reject(new Error('WebSocket 未连接'));
59
+ }
60
+ const echo = `ob12_${++requestId.value}`;
61
+ const request: OneBot12ActionRequest = { action, params, echo };
62
+ return new Promise((resolve, reject) => {
63
+ const timeout = setTimeout(() => {
64
+ pending.delete(echo);
65
+ reject(new Error(`OneBot12 动作超时: ${action}`));
66
+ }, 30_000);
67
+ pending.set(echo, { resolve, reject, timeout });
68
+ ws.send(JSON.stringify(request));
69
+ });
70
+ }
71
+
72
+ export function rejectAllPending(
73
+ pending: Map<string, OneBot12PendingAction>,
74
+ message = '连接已关闭',
75
+ ): void {
76
+ for (const [, entry] of pending) {
77
+ clearTimeout(entry.timeout);
78
+ entry.reject(new Error(message));
79
+ }
80
+ pending.clear();
81
+ }
82
+
83
+ function decodeOneBot12WsPayload(data: unknown): string {
84
+ if (typeof data === 'string') return data;
85
+ if (Buffer.isBuffer(data)) return data.toString();
86
+ if (data instanceof ArrayBuffer) return new TextDecoder().decode(data);
87
+ return String(data ?? '');
88
+ }
package/src/ws-types.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { OneBot12ActionResponse } from './protocol.js';
2
+
1
3
  /** Minimal WS surface used by the endpoint (real `ws` or test mock). */
2
4
  export interface OneBot12WsSocket {
3
5
  readonly readyState: number;
@@ -13,7 +15,7 @@ export interface OneBot12WsCreateOptions {
13
15
  export const WS_OPEN = 1;
14
16
 
15
17
  export interface OneBot12PendingAction {
16
- resolve: (value: unknown) => void;
18
+ resolve: (value: OneBot12ActionResponse) => void;
17
19
  reject: (err: Error) => void;
18
20
  timeout: NodeJS.Timeout;
19
21
  }
@@ -24,8 +24,6 @@ import {
24
24
  senderNickname,
25
25
  senderUserId,
26
26
  uploadOneBot12MediaSegments,
27
- type OneBot12ActionRequest,
28
- type OneBot12ActionResponse,
29
27
  type OneBot12Event,
30
28
  type OneBot12WssConfig,
31
29
  } from './protocol.js';
@@ -33,7 +31,12 @@ import { receiveOneBot12SideEvent } from './side-event-dispatch.js';
33
31
  import { createOneBot12ContentPort } from './content-port.js';
34
32
  import { callOnebot12Client, createOnebot12EndpointClient, forwardOnebot12ClientEvents, type Onebot12Client } from './client.js';
35
33
  import { verifyOneBotAccessToken } from './wss-auth.js';
36
- import { type OneBot12WsSocket, WS_OPEN } from './ws-types.js';
34
+ import { type OneBot12PendingAction, type OneBot12WsSocket } from './ws-types.js';
35
+ import {
36
+ callOneBot12WsAction,
37
+ handleOneBot12WsMessage,
38
+ rejectAllPending,
39
+ } from './ws-transport.js';
37
40
 
38
41
  export interface OneBot12WssEndpointOptions {
39
42
  readonly id: CapabilityId;
@@ -51,22 +54,19 @@ export class OneBot12WssEndpoint extends ClientEndpoint<Onebot12Client> {
51
54
  readonly content;
52
55
  #ws?: OneBot12WsSocket;
53
56
  #wsRelease?: () => void;
54
- readonly #lifecycle: EndpointLifecycle;
55
- #requestId = 0;
56
- #pending = new Map<string, {
57
- resolve: (value: OneBot12ActionResponse) => void;
58
- reject: (err: Error) => void;
59
- timeout: NodeJS.Timeout;
60
- }>();
57
+ readonly #connectionLifecycle: EndpointLifecycle;
58
+ #connectionTask = Promise.resolve();
59
+ #requestId = { value: 0 };
60
+ #pending = new Map<string, OneBot12PendingAction>();
61
+ #started = false;
61
62
 
62
63
  constructor(options: OneBot12WssEndpointOptions) {
63
64
  super();
64
65
  this.#logger = getAdapterLogger('onebot12', options.config.id);
65
66
  this.#options = options;
66
- this.#lifecycle = createEndpointLifecycle({
67
- name: options.config.id,
67
+ this.#connectionLifecycle = createEndpointLifecycle({
68
+ name: `${options.config.id}:inbound`,
68
69
  reconnect: false,
69
- heartbeat: { intervalMs: options.config.heartbeat_interval },
70
70
  });
71
71
  this.client = createOnebot12EndpointClient(options.config, (action, params) => this.#callAction(action, params ?? {}));
72
72
  const callApi = (action: string, params?: Record<string, unknown>) => callOnebot12Client(this.client, action, params);
@@ -82,6 +82,7 @@ export class OneBot12WssEndpoint extends ClientEndpoint<Onebot12Client> {
82
82
  }
83
83
 
84
84
  async start(): Promise<void> {
85
+ if (this.#started) return;
85
86
  if (!this.#options.config.access_token) {
86
87
  // wss 模式未配 access_token 时任何连接都会被放行(verifyOneBotAccessToken 直接 return true)
87
88
  this.#logger.warn(formatCompact({
@@ -91,22 +92,19 @@ export class OneBot12WssEndpoint extends ClientEndpoint<Onebot12Client> {
91
92
  error: 'missing access_token',
92
93
  }));
93
94
  }
94
- await this.#lifecycle.start(async (lifecycleHandle) => {
95
- const handle = this.#options.http.ws(this.#options.config.path);
96
- this.#wsRelease = handle.onConnection((connection) => {
97
- this.#acceptConnection(connection);
98
- });
99
- lifecycleHandle.onForceClose(() => {
100
- this.#wsRelease?.();
101
- this.#wsRelease = undefined;
102
- try {
103
- this.#ws?.close();
104
- } catch {
105
- /* ignore */
106
- }
107
- this.#ws = undefined;
108
- });
95
+ const handle = this.#options.http.ws(this.#options.config.path);
96
+ this.#wsRelease = handle.onConnection((connection) => {
97
+ this.#connectionTask = this.#connectionTask
98
+ .then(() => this.#acceptConnection(connection))
99
+ .catch((error) => {
100
+ this.#logger.warn(formatCompact({
101
+ op: 'wss_connection_failed',
102
+ endpoint: this.#options.config.id,
103
+ error: error instanceof Error ? error.message : String(error),
104
+ }));
105
+ });
109
106
  });
107
+ this.#started = true;
110
108
  this.#logger.info(formatCompact({
111
109
  op: 'listen',
112
110
  endpoint: this.#options.config.id,
@@ -117,12 +115,13 @@ export class OneBot12WssEndpoint extends ClientEndpoint<Onebot12Client> {
117
115
 
118
116
  async stop(): Promise<void> {
119
117
  this.close();
120
- await this.#lifecycle.stop();
121
- for (const [, pending] of this.#pending) {
122
- clearTimeout(pending.timeout);
123
- pending.reject(new Error('连接已关闭'));
124
- }
125
- this.#pending.clear();
118
+ this.#wsRelease?.();
119
+ this.#wsRelease = undefined;
120
+ await this.#connectionTask;
121
+ await this.#connectionLifecycle.stop();
122
+ rejectAllPending(this.#pending);
123
+ this.#ws = undefined;
124
+ this.#started = false;
126
125
  }
127
126
 
128
127
  async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
@@ -195,32 +194,45 @@ export class OneBot12WssEndpoint extends ClientEndpoint<Onebot12Client> {
195
194
  }));
196
195
  }
197
196
 
198
- #acceptConnection(connection: WsConnection): void {
197
+ async #acceptConnection(connection: WsConnection): Promise<void> {
199
198
  if (!verifyOneBotAccessToken(this.#options.config.access_token, connection.request)) {
200
199
  connection.socket.close(4003, 'Unauthorized');
201
200
  return;
202
201
  }
203
202
  const socket = connection.socket as unknown as OneBot12WsSocket;
204
- if (this.#ws) {
205
- try {
206
- this.#ws.close();
207
- } catch {
208
- /* ignore */
209
- }
210
- }
211
- this.#ws = socket;
212
- this.#lifecycle.startHeartbeat(() => {
213
- this.#callAction('get_status', {}).catch(() => {});
214
- });
215
- socket.on('message', (data) => {
216
- this.#lifecycle.notifyHeartbeatAck();
217
- this.#onMessage(data);
218
- });
219
- socket.on('close', () => {
220
- if (this.#ws === socket) {
221
- this.#ws = undefined;
222
- this.#lifecycle.stopHeartbeat();
223
- }
203
+ await this.#connectionLifecycle.stop();
204
+ rejectAllPending(this.#pending, '连接已替换');
205
+ await this.#connectionLifecycle.start(async (lifecycleHandle) => {
206
+ this.#ws = socket;
207
+ lifecycleHandle.onForceClose(() => {
208
+ try {
209
+ socket.close();
210
+ } catch {
211
+ /* ignore */
212
+ }
213
+ if (this.#ws === socket) this.#ws = undefined;
214
+ });
215
+ this.#connectionLifecycle.startHeartbeat(() => {
216
+ this.#callAction('get_status', {}).catch(() => {});
217
+ }, this.#options.config.heartbeat_interval);
218
+ socket.on('message', (data) => {
219
+ if (this.#ws !== socket) return;
220
+ this.#connectionLifecycle.notifyHeartbeatAck();
221
+ handleOneBot12WsMessage(data, {
222
+ endpointId: this.#options.config.id,
223
+ pending: this.#pending,
224
+ ingest: (event) => this.client.ingest(
225
+ event as Parameters<Onebot12Client['ingest']>[0],
226
+ ),
227
+ });
228
+ });
229
+ socket.on('close', () => {
230
+ if (this.#ws === socket) {
231
+ this.#ws = undefined;
232
+ rejectAllPending(this.#pending);
233
+ }
234
+ lifecycleHandle.notifyClosed(new Error('OneBot12 reverse WebSocket closed'));
235
+ });
224
236
  });
225
237
  this.#logger.debug(formatCompact({
226
238
  endpoint: this.#options.config.id,
@@ -229,50 +241,8 @@ export class OneBot12WssEndpoint extends ClientEndpoint<Onebot12Client> {
229
241
  }));
230
242
  }
231
243
 
232
- #onMessage(data: unknown): void {
233
- try {
234
- const raw = typeof data === 'string'
235
- ? data
236
- : Buffer.isBuffer(data)
237
- ? data.toString()
238
- : data instanceof ArrayBuffer
239
- ? new TextDecoder().decode(data)
240
- : String(data ?? '');
241
- const msg = JSON.parse(raw) as OneBot12Event | OneBot12ActionResponse;
242
- if ('echo' in msg && typeof (msg as OneBot12ActionResponse).echo === 'string') {
243
- const resp = msg as OneBot12ActionResponse;
244
- const pending = this.#pending.get(resp.echo!);
245
- if (pending) {
246
- this.#pending.delete(resp.echo!);
247
- clearTimeout(pending.timeout);
248
- pending.resolve(resp);
249
- }
250
- return;
251
- }
252
- this.client.ingest(msg as Parameters<Onebot12Client['ingest']>[0]);
253
- } catch (error) {
254
- this.#logger.warn(formatCompact({
255
- op: 'onebot12_parse_failed',
256
- endpoint: this.#options.config.id,
257
- error: error instanceof Error ? error.message : String(error),
258
- }));
259
- }
260
- }
261
-
262
- #callAction(action: string, params: Record<string, unknown>): Promise<OneBot12ActionResponse> {
263
- if (!this.#ws || this.#ws.readyState !== WS_OPEN) {
264
- return Promise.reject(new Error('WebSocket 未连接'));
265
- }
266
- const echo = `ob12_${++this.#requestId}`;
267
- const req: OneBot12ActionRequest = { action, params, echo };
268
- return new Promise((resolve, reject) => {
269
- const timeout = setTimeout(() => {
270
- this.#pending.delete(echo);
271
- reject(new Error(`OneBot12 动作超时: ${action}`));
272
- }, 30_000);
273
- this.#pending.set(echo, { resolve, reject, timeout });
274
- this.#ws!.send(JSON.stringify(req));
275
- });
244
+ #callAction(action: string, params: Record<string, unknown>) {
245
+ return callOneBot12WsAction(this.#ws, this.#pending, this.#requestId, action, params);
276
246
  }
277
247
 
278
248
  }
@@ -1,36 +0,0 @@
1
- ---
2
- name: onebot12
3
- platforms:
4
- - onebot12
5
- description: >-
6
- OneBot 12 协议适配器:支持 WebSocket 正向连接、Webhook 回调和反向 WebSocket
7
- 三种连接模式,兼容 OneBot 12 标准协议。纯消息通道,无额外 AI 工具。
8
- 支持私聊、群聊、频道消息。
9
- keywords:
10
- - onebot12
11
- - onebot
12
- - adapter:onebot12
13
- - protocol
14
- - websocket
15
- - webhook
16
- - 协议
17
- tags:
18
- - onebot12
19
- - protocol
20
- - adapter
21
- tools: []
22
- ---
23
-
24
- # OneBot 12 协议适配器
25
-
26
- 纯协议适配器,收发消息。无 AI 工具可调用。
27
-
28
- ## 连接模式
29
-
30
- - **WS 正向**:Bot 主动连接 OneBot 12 服务端
31
- - **Webhook**:OneBot 12 向配置的 URL 推送事件
32
- - **WS 反向**:OneBot 12 主动连接 Endpoint 的 WS 服务端
33
-
34
- ## 与 OneBot11 的区别
35
-
36
- OneBot 12 标准化了事件格式、消息段类型和 API 响应结构。如果需要群管理等 AI 工具,使用 OneBot11 适配器。
@@ -1,3 +0,0 @@
1
- import { onebot12EndpointCommands } from '../../../src/onebot12-endpoint-commands.js';
2
-
3
- export default onebot12EndpointCommands.add;
@@ -1,3 +0,0 @@
1
- import { onebot12EndpointCommands } from '../../src/onebot12-endpoint-commands.js';
2
-
3
- export default onebot12EndpointCommands.list;
@@ -1,3 +0,0 @@
1
- import { onebot12EndpointCommands } from '../../../src/onebot12-endpoint-commands.js';
2
-
3
- export default onebot12EndpointCommands.remove;
@@ -1 +0,0 @@
1
- export declare const onebot12EndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;