@zhin.js/adapter-onebot12 1.0.0 → 1.1.0

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 (90) hide show
  1. package/CHANGELOG.md +855 -0
  2. package/README.md +59 -69
  3. package/adapters/onebot12.js +50 -0
  4. package/adapters/onebot12.ts +64 -0
  5. package/{skills/onebot12/SKILL.md → agent/skills/onebot12.md} +1 -1
  6. package/commands/endpoint/add/[id].js +3 -0
  7. package/commands/endpoint/add/[id].ts +3 -0
  8. package/commands/endpoint/list.js +3 -0
  9. package/commands/endpoint/list.ts +3 -0
  10. package/commands/endpoint/remove/[id].js +3 -0
  11. package/commands/endpoint/remove/[id].ts +3 -0
  12. package/lib/client.d.ts +20 -0
  13. package/lib/client.js +33 -0
  14. package/lib/content-port.d.ts +4 -0
  15. package/lib/content-port.js +45 -0
  16. package/lib/endpoint-management.d.ts +16 -0
  17. package/lib/endpoint-management.js +47 -0
  18. package/lib/index.d.ts +10 -19
  19. package/lib/index.js +7 -27
  20. package/lib/onebot12-endpoint-commands.d.ts +1 -0
  21. package/lib/onebot12-endpoint-commands.js +25 -0
  22. package/lib/onebot12-runtime-state.d.ts +1 -0
  23. package/lib/onebot12-runtime-state.js +6 -0
  24. package/lib/protocol.d.ts +173 -0
  25. package/lib/protocol.js +415 -0
  26. package/lib/side-event-dispatch.d.ts +7 -0
  27. package/lib/side-event-dispatch.js +36 -0
  28. package/lib/webhook.d.ts +23 -0
  29. package/lib/webhook.js +161 -0
  30. package/lib/ws-endpoint.d.ts +22 -0
  31. package/lib/ws-endpoint.js +255 -0
  32. package/lib/ws-types.d.ts +16 -0
  33. package/lib/ws-types.js +1 -0
  34. package/lib/wss-auth.d.ts +2 -0
  35. package/lib/wss-auth.js +16 -0
  36. package/lib/wss-endpoint.d.ts +25 -0
  37. package/lib/wss-endpoint.js +222 -0
  38. package/package.json +63 -16
  39. package/plugin.js +14 -0
  40. package/schema.json +102 -0
  41. package/src/client.ts +81 -0
  42. package/src/content-port.ts +49 -0
  43. package/src/endpoint-management.ts +73 -0
  44. package/src/index.ts +64 -37
  45. package/src/onebot12-endpoint-commands.ts +24 -0
  46. package/src/onebot12-runtime-state.ts +7 -0
  47. package/src/protocol.ts +574 -0
  48. package/src/side-event-dispatch.ts +48 -0
  49. package/src/webhook.ts +223 -0
  50. package/src/ws-endpoint.ts +321 -0
  51. package/src/ws-types.ts +19 -0
  52. package/src/wss-auth.ts +17 -0
  53. package/src/wss-endpoint.ts +278 -0
  54. package/lib/adapter.d.ts +0 -17
  55. package/lib/adapter.d.ts.map +0 -1
  56. package/lib/adapter.js +0 -40
  57. package/lib/adapter.js.map +0 -1
  58. package/lib/api.d.ts +0 -14
  59. package/lib/api.d.ts.map +0 -1
  60. package/lib/api.js +0 -34
  61. package/lib/api.js.map +0 -1
  62. package/lib/bot-webhook.d.ts +0 -25
  63. package/lib/bot-webhook.d.ts.map +0 -1
  64. package/lib/bot-webhook.js +0 -118
  65. package/lib/bot-webhook.js.map +0 -1
  66. package/lib/bot-ws.d.ts +0 -26
  67. package/lib/bot-ws.d.ts.map +0 -1
  68. package/lib/bot-ws.js +0 -210
  69. package/lib/bot-ws.js.map +0 -1
  70. package/lib/bot-wss.d.ts +0 -26
  71. package/lib/bot-wss.d.ts.map +0 -1
  72. package/lib/bot-wss.js +0 -187
  73. package/lib/bot-wss.js.map +0 -1
  74. package/lib/index.d.ts.map +0 -1
  75. package/lib/index.js.map +0 -1
  76. package/lib/types.d.ts +0 -77
  77. package/lib/types.d.ts.map +0 -1
  78. package/lib/types.js +0 -5
  79. package/lib/types.js.map +0 -1
  80. package/lib/utils.d.ts +0 -45
  81. package/lib/utils.d.ts.map +0 -1
  82. package/lib/utils.js +0 -60
  83. package/lib/utils.js.map +0 -1
  84. package/src/adapter.ts +0 -52
  85. package/src/api.ts +0 -48
  86. package/src/bot-webhook.ts +0 -130
  87. package/src/bot-ws.ts +0 -222
  88. package/src/bot-wss.ts +0 -202
  89. package/src/types.ts +0 -86
  90. package/src/utils.ts +0 -87
package/README.md CHANGED
@@ -1,105 +1,95 @@
1
1
  # @zhin.js/adapter-onebot12
2
2
 
3
- Zhin.js [OneBot 12](https://12.onebot.dev/) 协议适配器,**一个适配器**支持正向 WebSocket、HTTP Webhook、反向 WebSocket 三种连接方式,由配置项 `connection` 区分。
3
+ Zhin.js [OneBot 12](https://12.onebot.dev/) 适配器(Plugin Runtime)。默认 **正向 WebSocket 客户端**(`connection: ws`);亦支持 **HTTP Webhook** 与 **反向 WS**(经 `httpHostToken` 注册路由)。
4
4
 
5
5
  ## 功能特性
6
6
 
7
- - 🔌 [OneBot 12 标准](https://12.onebot.dev/) 兼容(OneBot Connect + 接口定义)
8
- - 📦 **单一适配器**:`context: onebot12`,通过 `connection` 选择连接方式
9
- - 🌐 **正向 WebSocket**(`connection: ws`):应用连 OneBot 实现的 WS 服务器
10
- - 📮 **HTTP Webhook**(`connection: webhook`):OneBot 实现 POST 事件到应用提供的 path,可选 `api_url` 用于发消息/撤回
11
- - 🔄 **反向 WebSocket**(`connection: wss`):应用开 WS 服务端,OneBot 实现连上来
12
- - 🔐 `access_token` 鉴权(Bearer)
13
- - 📨 私聊 / 群聊 / 频道消息收发,消息段与 OneBot 12 标准一致
7
+ - [OneBot 12 标准](https://12.onebot.dev/) 兼容(事件 + 动作)
8
+ - 约定式 `defineAdapter` / `definePlugin`(无需 `usePlugin`)
9
+ - **正向 WebSocket**(`connection: ws`):应用连 OneBot 实现的 WS 服务器
10
+ - `access_token` 鉴权(Bearer + query)
11
+ - 入站经 `Endpoint.emit(...)`;出站 `send({ conversation, payload })`
14
12
 
15
13
  ## 安装
16
14
 
17
15
  ```bash
18
- pnpm add @zhin.js/adapter-onebot12 ws
16
+ pnpm add @zhin.js/adapter-onebot12
19
17
  ```
20
18
 
21
- Webhook / 反向 WS 需启用 `@zhin.js/host-router`:
19
+ ## Plugin Runtime
22
20
 
23
- ```bash
24
- pnpm add @zhin.js/host-router
25
- ```
21
+ - `@zhin.js/adapter` — 约定式 `adapters/onebot12.ts`(`defineAdapter`)
22
+ - `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
23
+ - `zhin.js` — `plugin.ts`(`definePlugin`)
24
+ - 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
25
+
26
+ 入站:`gateway.receive({ conversation: ConversationRef, message: { conversation, id }, content, sender, metadata })`
27
+ 出站:`send({ conversation, payload })` → WS `send_message`(payload 已由 gateway/core 渲染;无 segment-mapper)
26
28
 
27
- ## 配置
29
+ 每个 Endpoint 的 `$client` 是 `@imhelper/onebot-v12` 的 `OneBotV12Client`。业务代码直接调用
30
+ `$client.call(action, params)` 和 Client 的公开平台能力;Webhook 使用 Client 的
31
+ `acceptHttp()`,双工 WS 则由 Endpoint 分离 `echo` 响应后把事件交给 `ingest()`。
28
32
 
29
- 所有 Bot 使用 **同一 context:`onebot12`**,通过 **`connection`** 区分连接方式。
33
+ ## 前置条件
30
34
 
31
- ### 正向 WebSocket
35
+ 1. 启动兼容 OneBot 12 的实现,并确认其支持所选 WS 或 Webhook 模式。
36
+ 2. Webhook 出站还需要可用的 `api_url`;反向连接需要实现端可达 Zhin HTTP Host。
37
+ 3. 两端配置相同的 `access_token`,生产环境必须启用鉴权。
38
+
39
+ ## 最小配置
32
40
 
33
41
  ```yaml
42
+ # zhin.config.yml(Plugin Runtime)
34
43
  plugins:
35
- - "@zhin.js/adapter-onebot12"
36
-
37
- bots:
38
- - context: onebot12
44
+ onebot12:
39
45
  connection: ws
40
- name: ob12-bot
41
- url: "ws://127.0.0.1:6700"
42
- access_token: "${ONEBOT12_ACCESS_TOKEN}"
43
46
  reconnect_interval: 5000
44
47
  heartbeat_interval: 30000
48
+ endpoints:
49
+ - name: ob12-bot
50
+ url: "ws://127.0.0.1:6700"
51
+ access_token: "${ONEBOT12_ACCESS_TOKEN}"
45
52
  ```
46
53
 
47
- ### HTTP Webhook
54
+ 根插件 `zhin.plugins`(或项目图)需引用 `@zhin.js/adapter-onebot12`(`instanceKey: onebot12`)。
48
55
 
49
- OneBot 实现会向你的 `path` 发送 POST 事件;若需发消息/撤回,请配置实现提供的 HTTP 端点 `api_url`。
56
+ ## 连接方式
50
57
 
51
- ```yaml
52
- plugins:
53
- - "@zhin.js/host-router"
54
- - "@zhin.js/adapter-onebot12"
55
-
56
- bots:
57
- - context: onebot12
58
- connection: webhook
59
- name: ob12-webhook-bot
60
- path: "/onebot12/webhook"
61
- api_url: "http://127.0.0.1:6700" # 可选,用于 send_message / delete_message
62
- access_token: "${ONEBOT12_ACCESS_TOKEN}"
63
- ```
58
+ | connection | 状态 |
59
+ |------------|------|
60
+ | `ws` | 已实现(推荐) |
61
+ | `webhook` | 已实现:POST 入站 + `api_url` HTTP 出站 |
62
+ | `wss` | 已实现:反向 WS(httpHostToken) |
64
63
 
65
- ### 反向 WebSocket
64
+ ## 鉴权
66
65
 
67
- ```yaml
68
- plugins:
69
- - "@zhin.js/host-router"
70
- - "@zhin.js/adapter-onebot12"
71
-
72
- bots:
73
- - context: onebot12
74
- connection: wss
75
- name: ob12-wss-bot
76
- path: "/onebot12/event"
77
- access_token: "${ONEBOT12_ACCESS_TOKEN}"
78
- heartbeat_interval: 30000
79
- ```
66
+ - **Bearer**:`Authorization: Bearer <access_token>`
67
+ - 正向 WS 在 Upgrade 时附带请求头,并在 URL query 写入 `access_token`
80
68
 
81
- ## 鉴权
69
+ ## 动作与事件
82
70
 
83
- - **Bearer**:请求头 `Authorization: Bearer <access_token>`
84
- - 正向 WS 在建立连接时通过 HTTP Upgrade 头鉴权;Webhook / 反向 WS 同上
71
+ - 事件:`type`(meta/message/notice/request)、`detail_type`、`message` 等,见 [事件](https://12.onebot.dev/connect/data-protocol/event/)。
72
+ - 动作:`send_message`、`delete_message`、`get_status` 等,见 [动作请求](https://12.onebot.dev/connect/data-protocol/action-request/)。
85
73
 
86
- 配置 `access_token` 并与 OneBot 实现端一致即可。
74
+ ## AI 工具
87
75
 
88
- ## 连接方式对比
76
+ 技能说明见 `agent/skills/onebot12.md`。
89
77
 
90
- | connection | 说明 |
91
- |------------|------|
92
- | `ws` | 应用连实现的 WebSocket 服务器 |
93
- | `webhook` | 实现 POST 事件到应用 path;发消息需配置 `api_url` |
94
- | `wss` | 应用开 WS 服务端,实现连上来 |
78
+ ## 文档链接
95
79
 
96
- ## 动作与事件
80
+ - [OneBot 12 标准](https://12.onebot.dev/)
81
+ - [OneBot Connect WebSocket](https://12.onebot.dev/connect/communication/websocket/)
82
+ - [适配器概览](https://zhin.js.org/essentials/adapters)
97
83
 
98
- - 事件:`type`(meta/message/notice/request)、`detail_type`、`message`(消息段数组)等,见 [事件](https://12.onebot.dev/connect/data-protocol/event/)。
99
- - 动作:`send_message`(params: detail_type, user_id/group_id/channel_id, message)、`delete_message` 等,见 [动作请求](https://12.onebot.dev/connect/data-protocol/action-request/)。
84
+ ## 故障排查
100
85
 
101
- ## 协议文档
86
+ | 现象 | 排查 |
87
+ | --- | --- |
88
+ | WS 连接失败 | 核对 OneBot 版本、连接方向、URL 与端口 |
89
+ | Webhook 能收不能发 | 检查 `api_url` 可达性与 `send_message` 支持 |
90
+ | 401 或握手失败 | 确认 Header/query token 与实现端一致 |
91
+ | 事件字段无法识别 | 确认实现端发送的是 OneBot 12 而非 v11 结构 |
102
92
 
103
- - [OneBot 12 标准](https://12.onebot.dev/)
104
- - [OneBot Connect 通信方式](https://12.onebot.dev/connect/communication/websocket/)
105
- - [数据协议(事件 / 动作)](https://12.onebot.dev/connect/data-protocol/event/)
93
+ ## 许可证
94
+
95
+ MIT License
@@ -0,0 +1,50 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ /**
3
+ * Convention entry: discover `adapters/onebot12.ts` → defineAdapter.
4
+ */
5
+ import { defineAdapter } from 'zhin.js/adapter';
6
+ import { httpHostToken } from '@zhin.js/host-http';
7
+ import { OneBot12WebhookEndpoint } from "../lib/webhook.js";
8
+ import { OneBot12WsEndpoint } from "../lib/ws-endpoint.js";
9
+ import { OneBot12WssEndpoint } from "../lib/wss-endpoint.js";
10
+ import { resolveOneBot12Config, } from "../lib/protocol.js";
11
+ import { onebot12RuntimeStateToken } from "../lib/onebot12-runtime-state.js";
12
+ export { OneBot12WebhookEndpoint } from "../lib/webhook.js";
13
+ export { OneBot12WsEndpoint } from "../lib/ws-endpoint.js";
14
+ export { OneBot12WssEndpoint } from "../lib/wss-endpoint.js";
15
+ export default defineAdapter({
16
+ capabilities: ['inbound', 'outbound'],
17
+ operations: ['recall'],
18
+ // 媒体段经 upload_file 物化为 file_id(spec 正式投递);上传失败降级扩展字段透传。
19
+ // 无卡片交互面,交互段降级纯文本。
20
+ segments: {
21
+ outboundMedia: ['url', 'path', 'base64', 'upload'],
22
+ interactive: 'text',
23
+ },
24
+ create(context) {
25
+ const config = resolveOneBot12Config(context.config);
26
+ // 注册到插件运行时状态(onebot12.endpoint list 的"运行中"数据源)
27
+ context.use(onebot12RuntimeStateToken).endpoints.set(config.id, {
28
+ id: config.id,
29
+ mode: config.connection,
30
+ });
31
+ if (config.connection === 'webhook') {
32
+ return new OneBot12WebhookEndpoint({
33
+ id: context.id,
34
+ http: context.use(httpHostToken),
35
+ config,
36
+ });
37
+ }
38
+ if (config.connection === 'wss') {
39
+ return new OneBot12WssEndpoint({
40
+ id: context.id,
41
+ http: context.use(httpHostToken),
42
+ config,
43
+ });
44
+ }
45
+ return new OneBot12WsEndpoint({
46
+ id: context.id,
47
+ config,
48
+ });
49
+ },
50
+ });
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Convention entry: discover `adapters/onebot12.ts` → defineAdapter.
3
+ */
4
+ import { defineAdapter } from 'zhin.js/adapter';
5
+ import { httpHostToken } from '@zhin.js/host-http';
6
+ import { OneBot12WebhookEndpoint } from '../src/webhook.js';
7
+ import { OneBot12WsEndpoint } from '../src/ws-endpoint.js';
8
+ import { OneBot12WssEndpoint } from '../src/wss-endpoint.js';
9
+ import {
10
+ resolveOneBot12Config,
11
+ type OneBot12AdapterConfig,
12
+ } from '../src/protocol.js';
13
+ import { onebot12RuntimeStateToken } from '../src/onebot12-runtime-state.js';
14
+
15
+ export { OneBot12WebhookEndpoint } from '../src/webhook.js';
16
+ export type { OneBot12WebhookEndpointOptions } from '../src/webhook.js';
17
+ export { OneBot12WsEndpoint } from '../src/ws-endpoint.js';
18
+ export type { OneBot12WsEndpointOptions } from '../src/ws-endpoint.js';
19
+ export { OneBot12WssEndpoint } from '../src/wss-endpoint.js';
20
+ export type { OneBot12WssEndpointOptions } from '../src/wss-endpoint.js';
21
+ export type { OneBot12WsSocket, OneBot12WsCreateOptions } from '../src/ws-types.js';
22
+
23
+ declare module '@zhin.js/core' {
24
+ interface AdapterEndpoints {
25
+ onebot12: import('../src/ws-endpoint.js').OneBot12WsEndpoint;
26
+ }
27
+ }
28
+
29
+ export default defineAdapter<OneBot12AdapterConfig>({
30
+ capabilities: ['inbound', 'outbound'],
31
+ operations: ['recall'],
32
+ // 媒体段经 upload_file 物化为 file_id(spec 正式投递);上传失败降级扩展字段透传。
33
+ // 无卡片交互面,交互段降级纯文本。
34
+ segments: {
35
+ outboundMedia: ['url', 'path', 'base64', 'upload'],
36
+ interactive: 'text',
37
+ },
38
+ create(context) {
39
+ const config = resolveOneBot12Config(context.config);
40
+ // 注册到插件运行时状态(onebot12.endpoint list 的"运行中"数据源)
41
+ context.use(onebot12RuntimeStateToken).endpoints.set(config.id, {
42
+ id: config.id,
43
+ mode: config.connection,
44
+ });
45
+ if (config.connection === 'webhook') {
46
+ return new OneBot12WebhookEndpoint({
47
+ id: context.id,
48
+ http: context.use(httpHostToken),
49
+ config,
50
+ });
51
+ }
52
+ if (config.connection === 'wss') {
53
+ return new OneBot12WssEndpoint({
54
+ id: context.id,
55
+ http: context.use(httpHostToken),
56
+ config,
57
+ });
58
+ }
59
+ return new OneBot12WsEndpoint({
60
+ id: context.id,
61
+ config,
62
+ });
63
+ },
64
+ });
@@ -29,7 +29,7 @@ tools: []
29
29
 
30
30
  - **WS 正向**:Bot 主动连接 OneBot 12 服务端
31
31
  - **Webhook**:OneBot 12 向配置的 URL 推送事件
32
- - **WS 反向**:OneBot 12 主动连接 Bot 的 WS 服务端
32
+ - **WS 反向**:OneBot 12 主动连接 Endpoint 的 WS 服务端
33
33
 
34
34
  ## 与 OneBot11 的区别
35
35
 
@@ -0,0 +1,3 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { onebot12EndpointCommands } from "../../../lib/onebot12-endpoint-commands.js";
3
+ export default onebot12EndpointCommands.add;
@@ -0,0 +1,3 @@
1
+ import { onebot12EndpointCommands } from '../../../src/onebot12-endpoint-commands.js';
2
+
3
+ export default onebot12EndpointCommands.add;
@@ -0,0 +1,3 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { onebot12EndpointCommands } from "../../lib/onebot12-endpoint-commands.js";
3
+ export default onebot12EndpointCommands.list;
@@ -0,0 +1,3 @@
1
+ import { onebot12EndpointCommands } from '../../src/onebot12-endpoint-commands.js';
2
+
3
+ export default onebot12EndpointCommands.list;
@@ -0,0 +1,3 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { onebot12EndpointCommands } from "../../../lib/onebot12-endpoint-commands.js";
3
+ export default onebot12EndpointCommands.remove;
@@ -0,0 +1,3 @@
1
+ import { onebot12EndpointCommands } from '../../../src/onebot12-endpoint-commands.js';
2
+
3
+ export default onebot12EndpointCommands.remove;
@@ -0,0 +1,20 @@
1
+ import { OneBotV12Client, type OneBotV12Event as ImHelperOneBot12Event, type OneBotV12Response } from '@imhelper/onebot-v12';
2
+ import { type EventMap, type ImHelperEventMap } from 'imhelper';
3
+ import { type ClientEventPayloads } from 'zhin.js/adapter';
4
+ import type { ResolvedOneBot12Config } from './protocol.js';
5
+ export { OneBotV12Client as Onebot12Client } from '@imhelper/onebot-v12';
6
+ export type Onebot12ApiCall = (action: string, params?: Record<string, unknown>) => Promise<OneBotV12Response>;
7
+ type Onebot12ClientEvents = ImHelperEventMap<string, ImHelperOneBot12Event, EventMap<string>>;
8
+ export type Onebot12ClientEventMap = ClientEventPayloads<Onebot12ClientEvents>;
9
+ export declare function createOnebot12EndpointClient(config: ResolvedOneBot12Config, request: Onebot12ApiCall): OneBotV12Client;
10
+ export declare function callOnebot12Client<T = unknown>(client: OneBotV12Client, action: string, params?: Record<string, unknown>): Promise<T | undefined>;
11
+ export declare function forwardOnebot12ClientEvents(client: OneBotV12Client, receive: (name: string, payload: unknown) => void): () => void;
12
+ declare module '@zhin.js/feature-kit' {
13
+ interface AdapterClientRegistry {
14
+ readonly onebot12: {
15
+ readonly client: OneBotV12Client;
16
+ readonly events: Onebot12ClientEventMap;
17
+ };
18
+ }
19
+ }
20
+ export declare const onebot12Client: import("@zhin.js/adapter").EndpointClientToken<OneBotV12Client, ClientEventPayloads<Onebot12ClientEvents>>;
package/lib/client.js ADDED
@@ -0,0 +1,33 @@
1
+ import { OneBotV12Client, } from '@imhelper/onebot-v12';
2
+ import { EventFactory } from 'imhelper';
3
+ import { defineEndpointClient, forwardEndpointClientEvents, } from 'zhin.js/adapter';
4
+ export { OneBotV12Client as Onebot12Client } from '@imhelper/onebot-v12';
5
+ export function createOnebot12EndpointClient(config, request) {
6
+ const baseUrl = config.connection === 'ws'
7
+ ? config.url.replace(/^ws(s?):/, 'http$1:')
8
+ : config.connection === 'webhook' && config.api_url
9
+ ? config.api_url
10
+ : 'http://localhost';
11
+ return new OneBotV12Client({
12
+ baseUrl,
13
+ selfId: config.id,
14
+ accessToken: config.access_token,
15
+ receiveMode: 'manual',
16
+ call: request,
17
+ });
18
+ }
19
+ export async function callOnebot12Client(client, action, params) {
20
+ const response = await client.call(action, params);
21
+ if (response.status !== 'ok') {
22
+ throw new Error(`OneBot 12 API ${action}: retcode=${response.retcode}${response.message ? ` ${response.message}` : ''}`);
23
+ }
24
+ return response.data;
25
+ }
26
+ const onebot12ClientEventNames = Object.freeze([
27
+ ...EventFactory.getSupportedEventTypes(),
28
+ 'event',
29
+ ]);
30
+ export function forwardOnebot12ClientEvents(client, receive) {
31
+ return forwardEndpointClientEvents(client, onebot12ClientEventNames, receive);
32
+ }
33
+ export const onebot12Client = defineEndpointClient('onebot12');
@@ -0,0 +1,4 @@
1
+ import type { EndpointContentPort } from 'zhin.js/adapter';
2
+ type CallApi = (action: string, params?: Record<string, unknown>) => Promise<unknown>;
3
+ export declare function createOneBot12ContentPort(callApi: CallApi): EndpointContentPort;
4
+ export {};
@@ -0,0 +1,45 @@
1
+ export function createOneBot12ContentPort(callApi) {
2
+ return Object.freeze({
3
+ async resolve(reference, context) {
4
+ try {
5
+ context.signal.throwIfAborted();
6
+ if (reference.kind === 'forward') {
7
+ return Object.freeze({ status: 'unsupported', code: 'onebot12_forward_lookup_not_standardized' });
8
+ }
9
+ if (reference.kind === 'media') {
10
+ return reference.media.kind === 'file'
11
+ ? Object.freeze({ status: 'unsupported', code: 'onebot12_opaque_media' })
12
+ : Object.freeze({ status: 'resolved', reference, value: reference.media });
13
+ }
14
+ const row = await callApi('get_message', { message_id: reference.message.id });
15
+ context.signal.throwIfAborted();
16
+ const message = (row.message && typeof row.message === 'object' ? row.message : row);
17
+ const segments = normalizeSegments(message.message ?? message.content);
18
+ const value = Object.freeze({
19
+ ref: reference.message,
20
+ ...(message.user_id != null ? { actor: Object.freeze({ id: String(message.user_id) }) } : {}),
21
+ segments,
22
+ timestamp: toMillis(message.time),
23
+ });
24
+ return Object.freeze({ status: 'resolved', reference, value });
25
+ }
26
+ catch (error) {
27
+ if (context.signal.aborted)
28
+ return Object.freeze({ status: 'expired', code: 'turn_aborted' });
29
+ return Object.freeze({ status: 'failed', code: 'onebot12_content_resolution_failed', message: error instanceof Error ? error.message : String(error) });
30
+ }
31
+ },
32
+ });
33
+ }
34
+ function normalizeSegments(value) {
35
+ if (!Array.isArray(value))
36
+ return Object.freeze([{ type: 'text', data: Object.freeze({ text: String(value ?? '') }) }]);
37
+ return Object.freeze(value.map((item) => {
38
+ const row = item;
39
+ return Object.freeze({ type: String(row.type ?? 'text'), data: Object.freeze((row.data ?? {})) });
40
+ }));
41
+ }
42
+ function toMillis(value) {
43
+ const time = Number(value);
44
+ return Number.isFinite(time) ? (time < 10_000_000_000 ? time * 1000 : time) : Date.now();
45
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * OneBot12 endpoint management 语义端口(Console 社交面 RPC 消费,见
3
+ * packages/im/adapter/src/endpoint-management.ts)。
4
+ *
5
+ * 动作名对齐 OB12 规范:get_friend_list / get_group_list / get_group_member_list。
6
+ * 归一化取舍(OB12 id 为字符串,收敛为数字):
7
+ * - friend → {user_id:number, nickname: user_name, remark: user_displayname ?? ''}
8
+ * - group → {group_id:number, name: group_name ?? name}
9
+ * - 群成员列表保持 OB12 原生形状,仅保证数组
10
+ */
11
+ import type { EndpointManagement } from 'zhin.js/adapter';
12
+ /** 管理面只依赖 endpoint 的 callApi(ws/wss/webhook 三种传输各自实现)。 */
13
+ export interface OneBot12ManagementCaller {
14
+ callApi(action: string, params?: Record<string, unknown>): Promise<unknown>;
15
+ }
16
+ export declare function createOneBot12EndpointManagement(endpoint: OneBot12ManagementCaller): EndpointManagement;
@@ -0,0 +1,47 @@
1
+ export function createOneBot12EndpointManagement(endpoint) {
2
+ return Object.freeze({
3
+ async listFriends() {
4
+ const data = await endpoint.callApi('get_friend_list');
5
+ return toArray(data).map((value) => {
6
+ const friend = asRecord(value);
7
+ return {
8
+ user_id: toNumberId(friend.user_id, 'user_id'),
9
+ nickname: String(friend.user_name ?? friend.nickname ?? ''),
10
+ remark: String(friend.user_displayname ?? friend.remark ?? ''),
11
+ };
12
+ });
13
+ },
14
+ async listGroups() {
15
+ const data = await endpoint.callApi('get_group_list');
16
+ return toArray(data).map((value) => {
17
+ const group = asRecord(value);
18
+ return {
19
+ group_id: toNumberId(group.group_id, 'group_id'),
20
+ name: String(group.group_name ?? group.name ?? ''),
21
+ };
22
+ });
23
+ },
24
+ async listGroupMembers(groupId) {
25
+ const data = await endpoint.callApi('get_group_member_list', {
26
+ group_id: groupId,
27
+ });
28
+ return toArray(data);
29
+ },
30
+ });
31
+ }
32
+ function asRecord(value) {
33
+ return value !== null && typeof value === 'object'
34
+ ? value
35
+ : {};
36
+ }
37
+ function toArray(value) {
38
+ return Array.isArray(value) ? value : [];
39
+ }
40
+ /** OB12 id 是字符串;QQ 系实现均为数字串,统一收敛为数字。 */
41
+ function toNumberId(value, label) {
42
+ const n = Number(value);
43
+ if (!Number.isFinite(n) || String(value ?? '').trim() === '') {
44
+ throw new TypeError(`onebot12 ${label} 必须是数字: ${String(value)}`);
45
+ }
46
+ return n;
47
+ }
package/lib/index.d.ts CHANGED
@@ -1,19 +1,10 @@
1
- import { OneBot12Adapter } from './adapter.js';
2
- export * from './types.js';
3
- export { callOneBot12Action } from './api.js';
4
- export * from './utils.js';
5
- export { OneBot12WsClient } from './bot-ws.js';
6
- export { OneBot12WebhookBot } from './bot-webhook.js';
7
- export { OneBot12WssServer } from './bot-wss.js';
8
- export { OneBot12Adapter, type OneBot12Bot } from './adapter.js';
9
- declare module 'zhin.js' {
10
- namespace Plugin {
11
- interface Contexts {
12
- router: import('@zhin.js/host-router').Router;
13
- }
14
- }
15
- interface Adapters {
16
- onebot12: OneBot12Adapter;
17
- }
18
- }
19
- //# sourceMappingURL=index.d.ts.map
1
+ export { buildSendMessageParams, buildWsConnectOptions, callOneBot12Action, formatInboundContent, formatOutboundSegments, getChannelId, isBotMentioned, isMessageEvent, mediaRefToOneBot12Fields, mediaRefToOneBot12UploadParams, onebot12InboundConversation, resolveOneBot12Config, senderNickname, senderUserId, uploadOneBot12MediaSegments, type OneBot12ActionRequest, type OneBot12ActionResponse, type OneBot12AdapterConfig, type OneBot12CallAction, type OneBot12ConfigBase, type OneBot12EndpointConfig, type OneBot12Event, type OneBot12HttpOptions, type OneBot12Segment, type OneBot12Self, type OneBot12WebhookConfig, type OneBot12WireSegment, type OneBot12WsConfig, type OneBot12WssConfig, type ResolvedOneBot12Config, } from './protocol.js';
2
+ export { OneBot12WebhookEndpoint, type OneBot12WebhookEndpointOptions, } from './webhook.js';
3
+ export { OneBot12WsEndpoint, type OneBot12WsEndpointOptions, } from './ws-endpoint.js';
4
+ export { OneBot12WssEndpoint, type OneBot12WssEndpointOptions, } from './wss-endpoint.js';
5
+ export type { OneBot12WsSocket, OneBot12WsCreateOptions } from './ws-types.js';
6
+ export { verifyOneBotAccessToken } from './wss-auth.js';
7
+ export { Onebot12Client, onebot12Client, type Onebot12ClientEventMap, } from './client.js';
8
+ export type { OneBotV12ActionUrlResolver, OneBotV12AdapterConfig as ImHelperOneBotV12AdapterConfig, OneBotV12Call, OneBotV12ClientConfig, OneBotV12Event as ImHelperOneBotV12Event, OneBotV12Response, } from '@imhelper/onebot-v12';
9
+ export { ProtocolError } from '@imhelper/onebot-v12';
10
+ export type { ProtocolErrorKind, ProtocolErrorOptions } from 'imhelper';
package/lib/index.js CHANGED
@@ -1,27 +1,7 @@
1
- /**
2
- * OneBot 12 适配器入口:单一适配器,支持正向 WS / Webhook / 反向 WS
3
- * 协议文档 https://12.onebot.dev/
4
- */
5
- import { usePlugin } from 'zhin.js';
6
- import { OneBot12Adapter } from './adapter.js';
7
- export * from './types.js';
8
- export { callOneBot12Action } from './api.js';
9
- export * from './utils.js';
10
- export { OneBot12WsClient } from './bot-ws.js';
11
- export { OneBot12WebhookBot } from './bot-webhook.js';
12
- export { OneBot12WssServer } from './bot-wss.js';
13
- export { OneBot12Adapter } from './adapter.js';
14
- const { provide } = usePlugin();
15
- provide({
16
- name: 'onebot12',
17
- description: 'OneBot 12 协议适配器(正向 WS / Webhook / 反向 WS)',
18
- mounted: async (p) => {
19
- const adapter = new OneBot12Adapter(p);
20
- await adapter.start();
21
- return adapter;
22
- },
23
- dispose: async (adapter) => {
24
- await adapter.stop();
25
- },
26
- });
27
- //# sourceMappingURL=index.js.map
1
+ export { buildSendMessageParams, buildWsConnectOptions, callOneBot12Action, formatInboundContent, formatOutboundSegments, getChannelId, isBotMentioned, isMessageEvent, mediaRefToOneBot12Fields, mediaRefToOneBot12UploadParams, onebot12InboundConversation, resolveOneBot12Config, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
2
+ export { OneBot12WebhookEndpoint, } from './webhook.js';
3
+ export { OneBot12WsEndpoint, } from './ws-endpoint.js';
4
+ export { OneBot12WssEndpoint, } from './wss-endpoint.js';
5
+ export { verifyOneBotAccessToken } from './wss-auth.js';
6
+ export { Onebot12Client, onebot12Client, } from './client.js';
7
+ export { ProtocolError } from '@imhelper/onebot-v12';
@@ -0,0 +1 @@
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>>>;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `onebot12.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
+ * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
+ */
5
+ import { createEndpointCommands } from 'zhin.js/adapter';
6
+ import { defineCommand } from 'zhin.js/command';
7
+ import { onebot12RuntimeStateToken } from './onebot12-runtime-state.js';
8
+ export const onebot12EndpointCommands = createEndpointCommands({
9
+ adapterKey: 'onebot12',
10
+ adapterDisplayName: 'OneBot 12',
11
+ fields: [
12
+ { key: 'url', description: 'OneBot 实现 WebSocket URL(connection: ws 必填)' },
13
+ { key: 'path', description: 'HTTP/WS 路径(webhook / reverse-wss)' },
14
+ { key: 'api_url', description: 'HTTP action 端点(connection: webhook 出站必填)' },
15
+ { key: 'access_token', env: true, description: 'OneBot access token' },
16
+ ],
17
+ running: (use) => use(onebot12RuntimeStateToken).endpoints.values(),
18
+ describeEntry: (entry) => {
19
+ if (entry.url)
20
+ return `url: ${String(entry.url)}`;
21
+ if (entry.path)
22
+ return `path: ${String(entry.path)}`;
23
+ return '';
24
+ },
25
+ }, defineCommand);
@@ -0,0 +1 @@
1
+ export declare const onebot12RuntimeStateToken: import("zhin.js").Token<import("@zhin.js/adapter").EndpointRuntimeState>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * OneBot12 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `onebot12.endpoint` 命令共享(同一 owner generation)。
4
+ */
5
+ import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
+ export const onebot12RuntimeStateToken = defineEndpointRuntimeStateToken('onebot12');