@zhin.js/adapter-onebot11 6.0.1 → 6.0.3
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 +24 -0
- package/README.md +3 -3
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/protocol.d.ts +6 -8
- package/lib/protocol.js +14 -24
- package/lib/ws-endpoint.d.ts +2 -5
- package/lib/ws-endpoint.js +8 -9
- package/lib/wss-endpoint.d.ts +2 -5
- package/lib/wss-endpoint.js +7 -8
- package/package.json +14 -13
- package/src/index.ts +1 -3
- package/src/protocol.ts +17 -32
- package/src/ws-endpoint.ts +9 -9
- package/src/wss-endpoint.ts +8 -9
- /package/commands/endpoint/add/{[name:string].js → [name].js} +0 -0
- /package/commands/endpoint/add/{[name:string].ts → [name].ts} +0 -0
- /package/commands/endpoint/remove/{[name:string].js → [name].js} +0 -0
- /package/commands/endpoint/remove/{[name:string].ts → [name].ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @zhin.js/adapter-onebot11
|
|
2
2
|
|
|
3
|
+
## 6.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [afc0e66]
|
|
8
|
+
- Updated dependencies [2e41ad5]
|
|
9
|
+
- Updated dependencies [9f57124]
|
|
10
|
+
- @zhin.js/core@1.5.2
|
|
11
|
+
- @zhin.js/adapter@1.1.5
|
|
12
|
+
- @zhin.js/im-contract@1.0.1
|
|
13
|
+
- @zhin.js/plugin-runtime@1.1.3
|
|
14
|
+
- @zhin.js/command@1.0.7
|
|
15
|
+
- @zhin.js/host-http@1.0.6
|
|
16
|
+
- @zhin.js/agent@1.1.3
|
|
17
|
+
- zhin.js@6.0.2
|
|
18
|
+
|
|
19
|
+
## 6.0.2
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [696ab1b]
|
|
24
|
+
- @zhin.js/agent@1.1.2
|
|
25
|
+
- zhin.js@6.0.1
|
|
26
|
+
|
|
3
27
|
## 6.0.1
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Zhin.js [OneBot 11](https://github.com/botuniverse/onebot-11) 适配器(Plugin
|
|
|
8
8
|
- 约定式 `defineAdapter` / `definePlugin`(无需 `usePlugin`)
|
|
9
9
|
- **正向 WebSocket**(`connection: ws`):应用连 OneBot 实现的 WS 服务器
|
|
10
10
|
- `access_token` 鉴权(Bearer + query)
|
|
11
|
-
- 入站经 `messageGatewayToken`;出站 `send({
|
|
11
|
+
- 入站经 `messageGatewayToken`;出站 `send({ conversation, payload })`
|
|
12
12
|
|
|
13
13
|
## 安装
|
|
14
14
|
|
|
@@ -23,8 +23,8 @@ pnpm add @zhin.js/adapter-onebot11
|
|
|
23
23
|
- `@zhin.js/plugin-runtime` — `plugin.ts`(`definePlugin`)
|
|
24
24
|
- 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
|
|
25
25
|
|
|
26
|
-
入站:`gateway.receive({
|
|
27
|
-
出站:`send({
|
|
26
|
+
入站:`gateway.receive({ conversation, message, content, sender, metadata })`(`conversation.kind` 为 `private`/`group`,`id` 为 uid/gid)
|
|
27
|
+
出站:`send({ conversation, payload })` → WS `send_private_msg` / `send_group_msg`(payload 已由 gateway/core 渲染;无 segment-mapper)
|
|
28
28
|
|
|
29
29
|
## 最小配置
|
|
30
30
|
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { buildSendAction, buildWsConnectOptions, extractQuoteId, formatInboundContent, formatInboundMetadata,
|
|
1
|
+
export { buildSendAction, buildWsConnectOptions, extractQuoteId, formatInboundContent, formatInboundMetadata, formatOutboundSegments, getChannelId, isMessageEvent, isOneBot11BotMentioned, mediaRefToOneBotFile, onebot11InboundConversation, resolveOneBot11Config, senderDisplayName, senderNickname, senderUserId, type OneBot11ActionRequest, type OneBot11ActionResponse, type OneBot11AdapterConfig, type OneBot11ConfigBase, type OneBot11EndpointConfig, type OneBot11Event, type OneBot11Segment, type OneBot11Sender, type OneBot11WireSegment, type OneBot11WsConfig, type OneBot11WssConfig, type ResolvedOneBot11Config, } from './protocol.js';
|
|
2
2
|
export { OneBot11WsEndpoint, type OneBot11WsEndpointOptions, } from './ws-endpoint.js';
|
|
3
3
|
export { OneBot11WssEndpoint, type OneBot11WssEndpointOptions, } from './wss-endpoint.js';
|
|
4
4
|
export type { OneBot11WsSocket, OneBot11WsCreateOptions } from './ws-types.js';
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { buildSendAction, buildWsConnectOptions, extractQuoteId, formatInboundContent, formatInboundMetadata,
|
|
1
|
+
export { buildSendAction, buildWsConnectOptions, extractQuoteId, formatInboundContent, formatInboundMetadata, formatOutboundSegments, getChannelId, isMessageEvent, isOneBot11BotMentioned, mediaRefToOneBotFile, onebot11InboundConversation, resolveOneBot11Config, senderDisplayName, senderNickname, senderUserId, } from './protocol.js';
|
|
2
2
|
export { OneBot11WsEndpoint, } from './ws-endpoint.js';
|
|
3
3
|
export { OneBot11WssEndpoint, } from './wss-endpoint.js';
|
|
4
4
|
export { callOneBot11WsAction, decodeWsPayload, handleOneBot11WsMessage, rejectAllPending, startOneBot11Heartbeat, } from './ws-transport.js';
|
package/lib/protocol.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Spec: https://github.com/botuniverse/onebot-11
|
|
5
5
|
*/
|
|
6
6
|
import { type MediaRef } from '@zhin.js/core';
|
|
7
|
+
import type { ConversationRef } from '@zhin.js/im-contract';
|
|
7
8
|
/** Transitional legacy endpoint row (`endpoints[]` with `context: onebot11`). */
|
|
8
9
|
export interface OneBot11LegacyEndpointRow {
|
|
9
10
|
readonly context?: string;
|
|
@@ -90,10 +91,6 @@ export interface OneBot11WireSegment {
|
|
|
90
91
|
readonly type: string;
|
|
91
92
|
readonly data?: Record<string, unknown>;
|
|
92
93
|
}
|
|
93
|
-
export interface ParsedSendTarget {
|
|
94
|
-
readonly message_type: 'private' | 'group';
|
|
95
|
-
readonly id: string;
|
|
96
|
-
}
|
|
97
94
|
export declare function resolveOneBot11Config(config?: OneBot11AdapterConfig): ResolvedOneBot11Config;
|
|
98
95
|
/** 判断是否为消息事件(post_type=message) */
|
|
99
96
|
export declare function isMessageEvent(ev: OneBot11Event): ev is OneBot11Event & {
|
|
@@ -102,10 +99,11 @@ export declare function isMessageEvent(ev: OneBot11Event): ev is OneBot11Event &
|
|
|
102
99
|
/** 从事件得到场景 id:私聊 user_id,群 group_id */
|
|
103
100
|
export declare function getChannelId(ev: OneBot11Event): string;
|
|
104
101
|
/**
|
|
105
|
-
*
|
|
102
|
+
* 入站归一化 → ConversationRef:OneBot 11 `group` 消息 → kind 'group',
|
|
103
|
+
* 其余(private 及带 group_id 的非 private 事件按群处理)→ kind 'private'。
|
|
104
|
+
* OneBot 11 无 guild/temp 容器概念,不填 parent。
|
|
106
105
|
*/
|
|
107
|
-
export declare function
|
|
108
|
-
export declare function parseSendTarget(target: string): ParsedSendTarget;
|
|
106
|
+
export declare function onebot11InboundConversation(endpointId: string, ev: OneBot11Event): ConversationRef;
|
|
109
107
|
/** Build inbound text for MessageGateway.receive */
|
|
110
108
|
export declare function formatInboundContent(ev: OneBot11Event): string;
|
|
111
109
|
export declare function senderDisplayName(ev: OneBot11Event): string;
|
|
@@ -140,7 +138,7 @@ export declare function mediaRefToOneBotFile(media: MediaRef): string;
|
|
|
140
138
|
* 其余 wire 形状段(at / 平台扩展段)原样透传。
|
|
141
139
|
*/
|
|
142
140
|
export declare function formatOutboundSegments(payload: unknown): OneBot11Segment[];
|
|
143
|
-
export declare function buildSendAction(
|
|
141
|
+
export declare function buildSendAction(conversation: ConversationRef, message: OneBot11Segment[]): {
|
|
144
142
|
action: string;
|
|
145
143
|
params: Record<string, unknown>;
|
|
146
144
|
};
|
package/lib/protocol.js
CHANGED
|
@@ -69,28 +69,19 @@ export function getChannelId(ev) {
|
|
|
69
69
|
return '';
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
|
-
*
|
|
72
|
+
* 入站归一化 → ConversationRef:OneBot 11 `group` 消息 → kind 'group',
|
|
73
|
+
* 其余(private 及带 group_id 的非 private 事件按群处理)→ kind 'private'。
|
|
74
|
+
* OneBot 11 无 guild/temp 容器概念,不填 parent。
|
|
73
75
|
*/
|
|
74
|
-
export function
|
|
75
|
-
const
|
|
76
|
+
export function onebot11InboundConversation(endpointId, ev) {
|
|
77
|
+
const kind = ev.message_type === 'group' || (ev.group_id != null && ev.message_type !== 'private')
|
|
76
78
|
? 'group'
|
|
77
79
|
: 'private';
|
|
78
|
-
return
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return { message_type: 'private', id: target };
|
|
84
|
-
}
|
|
85
|
-
const head = target.slice(0, sep);
|
|
86
|
-
const rest = target.slice(sep + 1);
|
|
87
|
-
if (head === 'group') {
|
|
88
|
-
return { message_type: 'group', id: rest };
|
|
89
|
-
}
|
|
90
|
-
if (head === 'private') {
|
|
91
|
-
return { message_type: 'private', id: rest };
|
|
92
|
-
}
|
|
93
|
-
return { message_type: 'private', id: target };
|
|
80
|
+
return {
|
|
81
|
+
endpoint: { id: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId },
|
|
82
|
+
kind,
|
|
83
|
+
id: getChannelId(ev),
|
|
84
|
+
};
|
|
94
85
|
}
|
|
95
86
|
/** Build inbound text for MessageGateway.receive */
|
|
96
87
|
export function formatInboundContent(ev) {
|
|
@@ -289,13 +280,12 @@ export function formatOutboundSegments(payload) {
|
|
|
289
280
|
}
|
|
290
281
|
return segs.length ? segs : [{ type: 'text', data: { text: '' } }];
|
|
291
282
|
}
|
|
292
|
-
export function buildSendAction(
|
|
293
|
-
|
|
294
|
-
if (parsed.message_type === 'group') {
|
|
283
|
+
export function buildSendAction(conversation, message) {
|
|
284
|
+
if (conversation.kind === 'group') {
|
|
295
285
|
return {
|
|
296
286
|
action: 'send_group_msg',
|
|
297
287
|
params: {
|
|
298
|
-
group_id: Number(
|
|
288
|
+
group_id: Number(conversation.id) || conversation.id,
|
|
299
289
|
message,
|
|
300
290
|
},
|
|
301
291
|
};
|
|
@@ -303,7 +293,7 @@ export function buildSendAction(target, message) {
|
|
|
303
293
|
return {
|
|
304
294
|
action: 'send_private_msg',
|
|
305
295
|
params: {
|
|
306
|
-
user_id: Number(
|
|
296
|
+
user_id: Number(conversation.id) || conversation.id,
|
|
307
297
|
message,
|
|
308
298
|
},
|
|
309
299
|
};
|
package/lib/ws-endpoint.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type EndpointInstance, type EndpointManagement } from '@zhin.js/adapter';
|
|
1
|
+
import { type EndpointInstance, type EndpointManagement, type EndpointSendRequest } from '@zhin.js/adapter';
|
|
2
2
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
3
3
|
import type { CapabilityId } from '@zhin.js/plugin-runtime';
|
|
4
4
|
import { type OneBot11Event, type OneBot11WsConfig } from './protocol.js';
|
|
@@ -17,10 +17,7 @@ export declare class OneBot11WsEndpoint implements EndpointInstance {
|
|
|
17
17
|
open(): void;
|
|
18
18
|
close(): void;
|
|
19
19
|
stop(): Promise<void>;
|
|
20
|
-
send({
|
|
21
|
-
readonly target: string;
|
|
22
|
-
readonly payload: unknown;
|
|
23
|
-
}): Promise<string>;
|
|
20
|
+
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
24
21
|
recallMessage(messageId: string): Promise<void>;
|
|
25
22
|
/** Public API for agent tools / callers. */
|
|
26
23
|
callApi(action: string, params?: Record<string, unknown>): Promise<unknown>;
|
package/lib/ws-endpoint.js
CHANGED
|
@@ -6,7 +6,7 @@ import { createEndpointLifecycle, } from '@zhin.js/adapter';
|
|
|
6
6
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
7
7
|
import { createOneBot11EndpointManagement } from './endpoint-management.js';
|
|
8
8
|
import { registerOnebot11AgentEndpoint } from './onebot11-agent-deps.js';
|
|
9
|
-
import { buildSendAction, buildWsConnectOptions, formatInboundContent, formatInboundMetadata,
|
|
9
|
+
import { buildSendAction, buildWsConnectOptions, formatInboundContent, formatInboundMetadata, formatOutboundSegments, isMessageEvent, onebot11InboundConversation, senderUserId, } from './protocol.js';
|
|
10
10
|
import { callOneBot11WsAction, handleOneBot11WsMessage, rejectAllPending, } from './ws-transport.js';
|
|
11
11
|
const logger = getLogger('onebot11');
|
|
12
12
|
export class OneBot11WsEndpoint {
|
|
@@ -72,15 +72,15 @@ export class OneBot11WsEndpoint {
|
|
|
72
72
|
rejectAllPending(this.#pending);
|
|
73
73
|
this.#ws = undefined;
|
|
74
74
|
}
|
|
75
|
-
async send({
|
|
75
|
+
async send({ conversation, payload }) {
|
|
76
76
|
const message = formatOutboundSegments(payload);
|
|
77
|
-
const { action, params } = buildSendAction(
|
|
77
|
+
const { action, params } = buildSendAction(conversation, message);
|
|
78
78
|
const data = await this.callApi(action, params);
|
|
79
79
|
const messageId = data?.message_id != null ? String(data.message_id) : '';
|
|
80
80
|
logger.debug(formatCompact({
|
|
81
81
|
op: 'onebot11_send',
|
|
82
82
|
endpoint: this.#options.config.name,
|
|
83
|
-
target
|
|
83
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
84
84
|
messageId,
|
|
85
85
|
}));
|
|
86
86
|
return messageId;
|
|
@@ -107,19 +107,18 @@ export class OneBot11WsEndpoint {
|
|
|
107
107
|
admit(ev) {
|
|
108
108
|
if (!this.#open || !isMessageEvent(ev))
|
|
109
109
|
return;
|
|
110
|
-
const
|
|
110
|
+
const conversation = onebot11InboundConversation(String(this.#options.id), ev);
|
|
111
111
|
const content = formatInboundContent(ev);
|
|
112
112
|
void this.#options.gateway.receive({
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
conversation,
|
|
114
|
+
message: { conversation, id: String(ev.message_id) },
|
|
115
115
|
content,
|
|
116
116
|
sender: senderUserId(ev),
|
|
117
|
-
id: String(ev.message_id),
|
|
118
117
|
metadata: formatInboundMetadata(ev, this.#options.config.name),
|
|
119
118
|
}).catch((err) => {
|
|
120
119
|
logger.warn(formatCompact({
|
|
121
120
|
op: 'onebot11_gateway_receive_failed',
|
|
122
|
-
target
|
|
121
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
123
122
|
error: err instanceof Error ? err.message : String(err),
|
|
124
123
|
}));
|
|
125
124
|
});
|
package/lib/wss-endpoint.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EndpointInstance, EndpointManagement } from '@zhin.js/adapter';
|
|
1
|
+
import type { EndpointInstance, EndpointManagement, EndpointSendRequest } from '@zhin.js/adapter';
|
|
2
2
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
3
3
|
import type { HttpHost } from '@zhin.js/host-http';
|
|
4
4
|
import type { CapabilityId } from '@zhin.js/plugin-runtime';
|
|
@@ -17,10 +17,7 @@ export declare class OneBot11WssEndpoint implements EndpointInstance {
|
|
|
17
17
|
open(): void;
|
|
18
18
|
close(): void;
|
|
19
19
|
stop(): Promise<void>;
|
|
20
|
-
send({
|
|
21
|
-
readonly target: string;
|
|
22
|
-
readonly payload: unknown;
|
|
23
|
-
}): Promise<string>;
|
|
20
|
+
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
24
21
|
recallMessage(messageId: string): Promise<void>;
|
|
25
22
|
callApi(action: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
26
23
|
setTitle(groupId: number, userId: number, title: string, duration?: number): Promise<boolean>;
|
package/lib/wss-endpoint.js
CHANGED
|
@@ -5,7 +5,7 @@ import { clearInterval } from 'node:timers';
|
|
|
5
5
|
import { formatCompact, getLogger } 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, senderUserId, } from './protocol.js';
|
|
9
9
|
import { verifyOneBotAccessToken } from './wss-auth.js';
|
|
10
10
|
import { callOneBot11WsAction, handleOneBot11WsMessage, rejectAllPending, startOneBot11Heartbeat, } from './ws-transport.js';
|
|
11
11
|
const logger = getLogger('onebot11');
|
|
@@ -76,9 +76,9 @@ export class OneBot11WssEndpoint {
|
|
|
76
76
|
}
|
|
77
77
|
this.#started = false;
|
|
78
78
|
}
|
|
79
|
-
async send({
|
|
79
|
+
async send({ conversation, payload }) {
|
|
80
80
|
const message = formatOutboundSegments(payload);
|
|
81
|
-
const { action, params } = buildSendAction(
|
|
81
|
+
const { action, params } = buildSendAction(conversation, message);
|
|
82
82
|
const data = await this.callApi(action, params);
|
|
83
83
|
return data?.message_id != null ? String(data.message_id) : '';
|
|
84
84
|
}
|
|
@@ -102,18 +102,17 @@ export class OneBot11WssEndpoint {
|
|
|
102
102
|
admit(ev) {
|
|
103
103
|
if (!this.#open || !isMessageEvent(ev))
|
|
104
104
|
return;
|
|
105
|
-
const
|
|
105
|
+
const conversation = onebot11InboundConversation(String(this.#options.id), ev);
|
|
106
106
|
void this.#options.gateway.receive({
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
conversation,
|
|
108
|
+
message: { conversation, id: String(ev.message_id) },
|
|
109
109
|
content: formatInboundContent(ev),
|
|
110
110
|
sender: senderUserId(ev),
|
|
111
|
-
id: String(ev.message_id),
|
|
112
111
|
metadata: formatInboundMetadata(ev, this.#options.config.name),
|
|
113
112
|
}).catch((err) => {
|
|
114
113
|
logger.warn(formatCompact({
|
|
115
114
|
op: 'onebot11_gateway_receive_failed',
|
|
116
|
-
target
|
|
115
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
117
116
|
error: err instanceof Error ? err.message : String(err),
|
|
118
117
|
}));
|
|
119
118
|
});
|
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.3",
|
|
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,13 @@
|
|
|
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.
|
|
44
|
+
"@zhin.js/adapter": "1.1.5",
|
|
45
|
+
"@zhin.js/command": "1.0.7",
|
|
46
|
+
"@zhin.js/core": "1.5.2",
|
|
47
|
+
"@zhin.js/host-http": "1.0.6",
|
|
48
|
+
"@zhin.js/im-contract": "1.0.1",
|
|
48
49
|
"@zhin.js/logger": "1.0.75",
|
|
49
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
50
|
+
"@zhin.js/plugin-runtime": "1.1.3"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@types/node": "^26.1.2",
|
|
@@ -54,16 +55,16 @@
|
|
|
54
55
|
"typescript": "^6.0.3",
|
|
55
56
|
"vitest": "^4.1.10",
|
|
56
57
|
"zod": "^4.4.3",
|
|
57
|
-
"@zhin.js/agent": "1.1.
|
|
58
|
-
"@zhin.js/host-http": "1.0.
|
|
58
|
+
"@zhin.js/agent": "1.1.3",
|
|
59
|
+
"@zhin.js/host-http": "1.0.6"
|
|
59
60
|
},
|
|
60
61
|
"peerDependencies": {
|
|
61
62
|
"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.
|
|
63
|
+
"@zhin.js/adapter": "1.1.5",
|
|
64
|
+
"@zhin.js/agent": "1.1.3",
|
|
65
|
+
"@zhin.js/core": "1.5.2",
|
|
66
|
+
"@zhin.js/plugin-runtime": "1.1.3",
|
|
67
|
+
"zhin.js": "6.0.2"
|
|
67
68
|
},
|
|
68
69
|
"peerDependenciesMeta": {
|
|
69
70
|
"zhin.js": {
|
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
|
|
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');
|
|
@@ -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,
|
|
@@ -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(endpointId: 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: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId },
|
|
194
|
+
kind,
|
|
195
|
+
id: getChannelId(ev),
|
|
196
|
+
};
|
|
211
197
|
}
|
|
212
198
|
|
|
213
199
|
/** Build inbound text for MessageGateway.receive */
|
|
@@ -420,15 +406,14 @@ export function formatOutboundSegments(payload: unknown): OneBot11Segment[] {
|
|
|
420
406
|
}
|
|
421
407
|
|
|
422
408
|
export function buildSendAction(
|
|
423
|
-
|
|
409
|
+
conversation: ConversationRef,
|
|
424
410
|
message: OneBot11Segment[],
|
|
425
411
|
): { action: string; params: Record<string, unknown> } {
|
|
426
|
-
|
|
427
|
-
if (parsed.message_type === 'group') {
|
|
412
|
+
if (conversation.kind === 'group') {
|
|
428
413
|
return {
|
|
429
414
|
action: 'send_group_msg',
|
|
430
415
|
params: {
|
|
431
|
-
group_id: Number(
|
|
416
|
+
group_id: Number(conversation.id) || conversation.id,
|
|
432
417
|
message,
|
|
433
418
|
},
|
|
434
419
|
};
|
|
@@ -436,7 +421,7 @@ export function buildSendAction(
|
|
|
436
421
|
return {
|
|
437
422
|
action: 'send_private_msg',
|
|
438
423
|
params: {
|
|
439
|
-
user_id: Number(
|
|
424
|
+
user_id: Number(conversation.id) || conversation.id,
|
|
440
425
|
message,
|
|
441
426
|
},
|
|
442
427
|
};
|
package/src/ws-endpoint.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type EndpointInstance,
|
|
9
9
|
type EndpointLifecycle,
|
|
10
10
|
type EndpointManagement,
|
|
11
|
+
type EndpointSendRequest,
|
|
11
12
|
} from '@zhin.js/adapter';
|
|
12
13
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
13
14
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
@@ -19,9 +20,9 @@ import {
|
|
|
19
20
|
buildWsConnectOptions,
|
|
20
21
|
formatInboundContent,
|
|
21
22
|
formatInboundMetadata,
|
|
22
|
-
formatInboundTarget,
|
|
23
23
|
formatOutboundSegments,
|
|
24
24
|
isMessageEvent,
|
|
25
|
+
onebot11InboundConversation,
|
|
25
26
|
senderUserId,
|
|
26
27
|
type OneBot11Event,
|
|
27
28
|
type OneBot11WsConfig,
|
|
@@ -115,15 +116,15 @@ export class OneBot11WsEndpoint implements EndpointInstance {
|
|
|
115
116
|
this.#ws = undefined;
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
async send({
|
|
119
|
+
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
119
120
|
const message = formatOutboundSegments(payload);
|
|
120
|
-
const { action, params } = buildSendAction(
|
|
121
|
+
const { action, params } = buildSendAction(conversation, message);
|
|
121
122
|
const data = await this.callApi(action, params) as { message_id?: number | string } | undefined;
|
|
122
123
|
const messageId = data?.message_id != null ? String(data.message_id) : '';
|
|
123
124
|
logger.debug(formatCompact({
|
|
124
125
|
op: 'onebot11_send',
|
|
125
126
|
endpoint: this.#options.config.name,
|
|
126
|
-
target
|
|
127
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
127
128
|
messageId,
|
|
128
129
|
}));
|
|
129
130
|
return messageId;
|
|
@@ -157,19 +158,18 @@ export class OneBot11WsEndpoint implements EndpointInstance {
|
|
|
157
158
|
/** Test / internal: admit a parsed event when the endpoint is open. */
|
|
158
159
|
admit(ev: OneBot11Event): void {
|
|
159
160
|
if (!this.#open || !isMessageEvent(ev)) return;
|
|
160
|
-
const
|
|
161
|
+
const conversation = onebot11InboundConversation(String(this.#options.id), ev);
|
|
161
162
|
const content = formatInboundContent(ev);
|
|
162
163
|
void this.#options.gateway.receive({
|
|
163
|
-
|
|
164
|
-
|
|
164
|
+
conversation,
|
|
165
|
+
message: { conversation, id: String(ev.message_id) },
|
|
165
166
|
content,
|
|
166
167
|
sender: senderUserId(ev),
|
|
167
|
-
id: String(ev.message_id),
|
|
168
168
|
metadata: formatInboundMetadata(ev, this.#options.config.name),
|
|
169
169
|
}).catch((err) => {
|
|
170
170
|
logger.warn(formatCompact({
|
|
171
171
|
op: 'onebot11_gateway_receive_failed',
|
|
172
|
-
target
|
|
172
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
173
173
|
error: err instanceof Error ? err.message : String(err),
|
|
174
174
|
}));
|
|
175
175
|
});
|
package/src/wss-endpoint.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* OneBot11 reverse WSS endpoint — accepts inbound WebSocket from OneBot implementation.
|
|
3
3
|
*/
|
|
4
4
|
import { clearInterval } from 'node:timers';
|
|
5
|
-
import type { EndpointInstance, EndpointManagement } from '@zhin.js/adapter';
|
|
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
8
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
@@ -13,9 +13,9 @@ import {
|
|
|
13
13
|
buildSendAction,
|
|
14
14
|
formatInboundContent,
|
|
15
15
|
formatInboundMetadata,
|
|
16
|
-
formatInboundTarget,
|
|
17
16
|
formatOutboundSegments,
|
|
18
17
|
isMessageEvent,
|
|
18
|
+
onebot11InboundConversation,
|
|
19
19
|
senderUserId,
|
|
20
20
|
type OneBot11Event,
|
|
21
21
|
type OneBot11WssConfig,
|
|
@@ -116,9 +116,9 @@ export class OneBot11WssEndpoint implements EndpointInstance {
|
|
|
116
116
|
this.#started = false;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
async send({
|
|
119
|
+
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
120
120
|
const message = formatOutboundSegments(payload);
|
|
121
|
-
const { action, params } = buildSendAction(
|
|
121
|
+
const { action, params } = buildSendAction(conversation, message);
|
|
122
122
|
const data = await this.callApi(action, params) as { message_id?: number | string } | undefined;
|
|
123
123
|
return data?.message_id != null ? String(data.message_id) : '';
|
|
124
124
|
}
|
|
@@ -144,18 +144,17 @@ export class OneBot11WssEndpoint implements EndpointInstance {
|
|
|
144
144
|
|
|
145
145
|
admit(ev: OneBot11Event): void {
|
|
146
146
|
if (!this.#open || !isMessageEvent(ev)) return;
|
|
147
|
-
const
|
|
147
|
+
const conversation = onebot11InboundConversation(String(this.#options.id), ev);
|
|
148
148
|
void this.#options.gateway.receive({
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
conversation,
|
|
150
|
+
message: { conversation, id: String(ev.message_id) },
|
|
151
151
|
content: formatInboundContent(ev),
|
|
152
152
|
sender: senderUserId(ev),
|
|
153
|
-
id: String(ev.message_id),
|
|
154
153
|
metadata: formatInboundMetadata(ev, this.#options.config.name),
|
|
155
154
|
}).catch((err) => {
|
|
156
155
|
logger.warn(formatCompact({
|
|
157
156
|
op: 'onebot11_gateway_receive_failed',
|
|
158
|
-
target
|
|
157
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
159
158
|
error: err instanceof Error ? err.message : String(err),
|
|
160
159
|
}));
|
|
161
160
|
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|