@zhin.js/adapter-onebot12 5.0.1 → 5.0.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.
- package/CHANGELOG.md +15 -0
- package/README.md +3 -3
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/protocol.d.ts +10 -9
- package/lib/protocol.js +36 -38
- package/lib/webhook.d.ts +2 -5
- package/lib/webhook.js +10 -9
- package/lib/ws-endpoint.d.ts +2 -5
- package/lib/ws-endpoint.js +10 -9
- package/lib/wss-endpoint.d.ts +2 -5
- package/lib/wss-endpoint.js +8 -8
- package/package.json +12 -11
- package/src/index.ts +1 -3
- package/src/protocol.ts +35 -43
- package/src/webhook.ts +11 -10
- package/src/ws-endpoint.ts +11 -9
- package/src/wss-endpoint.ts +9 -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,20 @@
|
|
|
1
1
|
# @zhin.js/adapter-onebot12
|
|
2
2
|
|
|
3
|
+
## 5.0.2
|
|
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@6.0.2
|
|
17
|
+
|
|
3
18
|
## 5.0.1
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Zhin.js [OneBot 12](https://12.onebot.dev/) 适配器(Plugin Runtime)。默
|
|
|
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-onebot12
|
|
|
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: ConversationRef, message: { conversation, id }, content, sender, metadata })`
|
|
27
|
+
出站:`send({ conversation, payload })` → WS `send_message`(payload 已由 gateway/core 渲染;无 segment-mapper)
|
|
28
28
|
|
|
29
29
|
## 最小配置
|
|
30
30
|
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { buildSendMessageParams, buildWsConnectOptions, callOneBot12Action, formatInboundContent,
|
|
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
2
|
export { OneBot12WebhookEndpoint, type OneBot12WebhookEndpointOptions, } from './webhook.js';
|
|
3
3
|
export { OneBot12WsEndpoint, type OneBot12WsEndpointOptions, } from './ws-endpoint.js';
|
|
4
4
|
export { OneBot12WssEndpoint, type OneBot12WssEndpointOptions, } from './wss-endpoint.js';
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { buildSendMessageParams, buildWsConnectOptions, callOneBot12Action, formatInboundContent,
|
|
1
|
+
export { buildSendMessageParams, buildWsConnectOptions, callOneBot12Action, formatInboundContent, formatOutboundSegments, getChannelId, isBotMentioned, isMessageEvent, mediaRefToOneBot12Fields, mediaRefToOneBot12UploadParams, onebot12InboundConversation, resolveOneBot12Config, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
|
|
2
2
|
export { OneBot12WebhookEndpoint, } from './webhook.js';
|
|
3
3
|
export { OneBot12WsEndpoint, } from './ws-endpoint.js';
|
|
4
4
|
export { OneBot12WssEndpoint, } from './wss-endpoint.js';
|
package/lib/protocol.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Spec: https://12.onebot.dev/
|
|
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: onebot12`). */
|
|
8
9
|
export interface OneBot12LegacyEndpointRow {
|
|
9
10
|
readonly context?: string;
|
|
@@ -100,11 +101,6 @@ export interface OneBot12WireSegment {
|
|
|
100
101
|
readonly type: string;
|
|
101
102
|
readonly data?: Record<string, unknown>;
|
|
102
103
|
}
|
|
103
|
-
export interface ParsedSendTarget {
|
|
104
|
-
readonly detail_type: 'private' | 'group' | 'channel';
|
|
105
|
-
readonly id: string;
|
|
106
|
-
readonly guild_id?: string;
|
|
107
|
-
}
|
|
108
104
|
export declare function resolveOneBot12Config(config?: OneBot12AdapterConfig): ResolvedOneBot12Config;
|
|
109
105
|
/** 判断是否为消息事件(type=message) */
|
|
110
106
|
export declare function isMessageEvent(ev: OneBot12Event): ev is OneBot12Event & {
|
|
@@ -114,10 +110,11 @@ export declare function isMessageEvent(ev: OneBot12Event): ev is OneBot12Event &
|
|
|
114
110
|
/** 从事件得到场景 id:私聊 user_id,群 group_id,频道 channel_id 或 guild_id:channel_id */
|
|
115
111
|
export declare function getChannelId(ev: OneBot12Event): string;
|
|
116
112
|
/**
|
|
117
|
-
*
|
|
113
|
+
* 入站归一化 → ConversationRef:`detail_type` 直映射 kind;channel 的 guild 容器
|
|
114
|
+
* 进 `parent`(kind 'channel');私聊临时会话(private 事件携带 group_id)映射为
|
|
115
|
+
* group 容器内的 private 会话。
|
|
118
116
|
*/
|
|
119
|
-
export declare function
|
|
120
|
-
export declare function parseSendTarget(target: string): ParsedSendTarget;
|
|
117
|
+
export declare function onebot12InboundConversation(endpointId: string, ev: OneBot12Event): ConversationRef;
|
|
121
118
|
/** Build inbound text for MessageGateway.receive */
|
|
122
119
|
export declare function formatInboundContent(ev: OneBot12Event): string;
|
|
123
120
|
/**
|
|
@@ -158,7 +155,11 @@ export declare function mediaRefToOneBot12UploadParams(segmentType: string, data
|
|
|
158
155
|
* 上传失败保留原段(降级扩展字段透传)并回调 onUploadFailed。
|
|
159
156
|
*/
|
|
160
157
|
export declare function uploadOneBot12MediaSegments(payload: unknown, callAction: OneBot12CallAction, onUploadFailed?: (error: unknown) => void): Promise<unknown>;
|
|
161
|
-
|
|
158
|
+
/**
|
|
159
|
+
* 结构化会话 → OB12 `send_message` 动作参数:kind 直映射 detail_type;
|
|
160
|
+
* channel 的 guild 容器取自 `conversation.parent`(kind 'channel')。
|
|
161
|
+
*/
|
|
162
|
+
export declare function buildSendMessageParams(conversation: ConversationRef, message: OneBot12Segment[]): Record<string, unknown>;
|
|
162
163
|
/**
|
|
163
164
|
* 向 OneBot 实现发送动作请求(HTTP POST),返回动作响应。
|
|
164
165
|
* 供 webhook 出站与纯协议测试使用;WS 路径走 WebSocket echo 请求。
|
package/lib/protocol.js
CHANGED
|
@@ -77,36 +77,31 @@ export function getChannelId(ev) {
|
|
|
77
77
|
return ev.user_id ?? ev.group_id ?? '';
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
|
-
*
|
|
80
|
+
* 入站归一化 → ConversationRef:`detail_type` 直映射 kind;channel 的 guild 容器
|
|
81
|
+
* 进 `parent`(kind 'channel');私聊临时会话(private 事件携带 group_id)映射为
|
|
82
|
+
* group 容器内的 private 会话。
|
|
81
83
|
*/
|
|
82
|
-
export function
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
: '
|
|
86
|
-
return `${detail}:${getChannelId(ev)}`;
|
|
87
|
-
}
|
|
88
|
-
export function parseSendTarget(target) {
|
|
89
|
-
const sep = target.indexOf(':');
|
|
90
|
-
if (sep <= 0) {
|
|
91
|
-
return { detail_type: 'private', id: target };
|
|
92
|
-
}
|
|
93
|
-
const head = target.slice(0, sep);
|
|
94
|
-
const rest = target.slice(sep + 1);
|
|
95
|
-
if (head === 'private' || head === 'group') {
|
|
96
|
-
return { detail_type: head, id: rest };
|
|
97
|
-
}
|
|
98
|
-
if (head === 'channel') {
|
|
99
|
-
const guildSep = rest.indexOf(':');
|
|
100
|
-
if (guildSep > 0) {
|
|
101
|
-
return {
|
|
102
|
-
detail_type: 'channel',
|
|
103
|
-
guild_id: rest.slice(0, guildSep),
|
|
104
|
-
id: rest.slice(guildSep + 1),
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
return { detail_type: 'channel', id: rest };
|
|
84
|
+
export function onebot12InboundConversation(endpointId, ev) {
|
|
85
|
+
const endpoint = { id: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId };
|
|
86
|
+
if (ev.detail_type === 'group' && ev.group_id) {
|
|
87
|
+
return { endpoint, kind: 'group', id: ev.group_id };
|
|
108
88
|
}
|
|
109
|
-
|
|
89
|
+
if (ev.detail_type === 'channel' && ev.channel_id) {
|
|
90
|
+
return {
|
|
91
|
+
endpoint,
|
|
92
|
+
kind: 'channel',
|
|
93
|
+
id: ev.channel_id,
|
|
94
|
+
...(ev.guild_id ? { parent: { kind: 'channel', id: ev.guild_id } } : {}),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
endpoint,
|
|
99
|
+
kind: 'private',
|
|
100
|
+
id: ev.user_id ?? ev.group_id ?? '',
|
|
101
|
+
...(ev.detail_type === 'private' && ev.group_id
|
|
102
|
+
? { parent: { kind: 'group', id: ev.group_id } }
|
|
103
|
+
: {}),
|
|
104
|
+
};
|
|
110
105
|
}
|
|
111
106
|
/** Build inbound text for MessageGateway.receive */
|
|
112
107
|
export function formatInboundContent(ev) {
|
|
@@ -347,22 +342,25 @@ export async function uploadOneBot12MediaSegments(payload, callAction, onUploadF
|
|
|
347
342
|
}
|
|
348
343
|
return uploadOneMediaSegment(payload, callAction, onUploadFailed);
|
|
349
344
|
}
|
|
350
|
-
|
|
351
|
-
|
|
345
|
+
/**
|
|
346
|
+
* 结构化会话 → OB12 `send_message` 动作参数:kind 直映射 detail_type;
|
|
347
|
+
* channel 的 guild 容器取自 `conversation.parent`(kind 'channel')。
|
|
348
|
+
*/
|
|
349
|
+
export function buildSendMessageParams(conversation, message) {
|
|
352
350
|
const params = {
|
|
353
351
|
message,
|
|
354
|
-
detail_type:
|
|
352
|
+
detail_type: conversation.kind,
|
|
355
353
|
};
|
|
356
|
-
if (
|
|
357
|
-
params.user_id =
|
|
354
|
+
if (conversation.kind === 'private') {
|
|
355
|
+
params.user_id = conversation.id;
|
|
358
356
|
}
|
|
359
|
-
else if (
|
|
360
|
-
params.group_id =
|
|
357
|
+
else if (conversation.kind === 'group') {
|
|
358
|
+
params.group_id = conversation.id;
|
|
361
359
|
}
|
|
362
360
|
else {
|
|
363
|
-
params.channel_id =
|
|
364
|
-
if (
|
|
365
|
-
params.guild_id =
|
|
361
|
+
params.channel_id = conversation.id;
|
|
362
|
+
if (conversation.parent?.kind === 'channel')
|
|
363
|
+
params.guild_id = conversation.parent.id;
|
|
366
364
|
}
|
|
367
365
|
return params;
|
|
368
366
|
}
|
package/lib/webhook.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';
|
|
@@ -18,10 +18,7 @@ export declare class OneBot12WebhookEndpoint implements EndpointInstance {
|
|
|
18
18
|
open(): void;
|
|
19
19
|
close(): void;
|
|
20
20
|
stop(): Promise<void>;
|
|
21
|
-
send({
|
|
22
|
-
readonly target: string;
|
|
23
|
-
readonly payload: unknown;
|
|
24
|
-
}): Promise<string>;
|
|
21
|
+
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
25
22
|
/** Public API for management surface / callers;webhook 模式走 api_url。 */
|
|
26
23
|
callApi(action: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
27
24
|
admit(ev: OneBot12Event): void;
|
package/lib/webhook.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
2
2
|
import { createOneBot12EndpointManagement } from './endpoint-management.js';
|
|
3
|
-
import { buildSendMessageParams, callOneBot12Action, formatInboundContent,
|
|
3
|
+
import { buildSendMessageParams, callOneBot12Action, formatInboundContent, formatOutboundSegments, isBotMentioned, isMessageEvent, onebot12InboundConversation, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
|
|
4
4
|
import { verifyOneBotAccessToken } from './wss-auth.js';
|
|
5
5
|
const logger = getLogger('onebot12');
|
|
6
6
|
export class OneBot12WebhookEndpoint {
|
|
@@ -48,7 +48,7 @@ export class OneBot12WebhookEndpoint {
|
|
|
48
48
|
this.#started = false;
|
|
49
49
|
logger.debug(formatCompact({ op: 'disconnect', endpoint: this.#options.config.name }));
|
|
50
50
|
}
|
|
51
|
-
async send({
|
|
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',
|
|
@@ -57,13 +57,14 @@ export class OneBot12WebhookEndpoint {
|
|
|
57
57
|
}));
|
|
58
58
|
});
|
|
59
59
|
const message = formatOutboundSegments(materialized);
|
|
60
|
-
const params = buildSendMessageParams(
|
|
60
|
+
const params = buildSendMessageParams(conversation, message);
|
|
61
61
|
const data = await this.callApi('send_message', params);
|
|
62
62
|
const messageId = data?.message_id ?? '';
|
|
63
63
|
logger.debug(formatCompact({
|
|
64
64
|
op: 'onebot12_send',
|
|
65
65
|
endpoint: this.#options.config.name,
|
|
66
|
-
|
|
66
|
+
kind: conversation.kind,
|
|
67
|
+
conversationId: conversation.id,
|
|
67
68
|
messageId,
|
|
68
69
|
}));
|
|
69
70
|
return messageId;
|
|
@@ -80,16 +81,15 @@ export class OneBot12WebhookEndpoint {
|
|
|
80
81
|
admit(ev) {
|
|
81
82
|
if (!this.#open || !isMessageEvent(ev))
|
|
82
83
|
return;
|
|
83
|
-
const
|
|
84
|
+
const conversation = onebot12InboundConversation(String(this.#options.id), ev);
|
|
84
85
|
const content = formatInboundContent(ev);
|
|
85
86
|
const nickname = senderNickname(ev);
|
|
86
87
|
const mentioned = isBotMentioned(ev);
|
|
87
88
|
void this.#options.gateway.receive({
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
conversation,
|
|
90
|
+
message: { conversation, id: ev.message_id },
|
|
90
91
|
content,
|
|
91
92
|
sender: senderUserId(ev),
|
|
92
|
-
id: ev.message_id,
|
|
93
93
|
metadata: Object.freeze({
|
|
94
94
|
detail_type: ev.detail_type,
|
|
95
95
|
user_id: ev.user_id,
|
|
@@ -104,7 +104,8 @@ export class OneBot12WebhookEndpoint {
|
|
|
104
104
|
}).catch((err) => {
|
|
105
105
|
logger.warn(formatCompact({
|
|
106
106
|
op: 'onebot12_gateway_receive_failed',
|
|
107
|
-
|
|
107
|
+
kind: conversation.kind,
|
|
108
|
+
conversationId: conversation.id,
|
|
108
109
|
error: err instanceof Error ? err.message : String(err),
|
|
109
110
|
}));
|
|
110
111
|
});
|
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 OneBot12Event, type OneBot12WsConfig } from './protocol.js';
|
|
@@ -17,10 +17,7 @@ export declare class OneBot12WsEndpoint 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 management surface / callers. */
|
|
26
23
|
callApi(action: string, params?: Record<string, unknown>): Promise<unknown>;
|
package/lib/ws-endpoint.js
CHANGED
|
@@ -6,7 +6,7 @@ import { clearTimeout } from 'node:timers';
|
|
|
6
6
|
import { createEndpointLifecycle, } from '@zhin.js/adapter';
|
|
7
7
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
8
8
|
import { createOneBot12EndpointManagement } from './endpoint-management.js';
|
|
9
|
-
import { buildSendMessageParams, buildWsConnectOptions, formatInboundContent,
|
|
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
11
|
const logger = getLogger('onebot12');
|
|
12
12
|
export class OneBot12WsEndpoint {
|
|
@@ -69,7 +69,7 @@ export class OneBot12WsEndpoint {
|
|
|
69
69
|
this.#pending.clear();
|
|
70
70
|
this.#ws = undefined;
|
|
71
71
|
}
|
|
72
|
-
async send({
|
|
72
|
+
async send({ conversation, payload }) {
|
|
73
73
|
const materialized = await uploadOneBot12MediaSegments(payload, (action, params) => this.callApi(action, params), (error) => {
|
|
74
74
|
logger.warn(formatCompact({
|
|
75
75
|
op: 'onebot12_upload_failed',
|
|
@@ -78,13 +78,14 @@ export class OneBot12WsEndpoint {
|
|
|
78
78
|
}));
|
|
79
79
|
});
|
|
80
80
|
const message = formatOutboundSegments(materialized);
|
|
81
|
-
const params = buildSendMessageParams(
|
|
81
|
+
const params = buildSendMessageParams(conversation, message);
|
|
82
82
|
const data = await this.#callAction('send_message', params);
|
|
83
83
|
const messageId = data?.message_id ?? '';
|
|
84
84
|
logger.debug(formatCompact({
|
|
85
85
|
op: 'onebot12_send',
|
|
86
86
|
endpoint: this.#options.config.name,
|
|
87
|
-
|
|
87
|
+
kind: conversation.kind,
|
|
88
|
+
conversationId: conversation.id,
|
|
88
89
|
messageId,
|
|
89
90
|
}));
|
|
90
91
|
return messageId;
|
|
@@ -102,16 +103,15 @@ export class OneBot12WsEndpoint {
|
|
|
102
103
|
admit(ev) {
|
|
103
104
|
if (!this.#open || !isMessageEvent(ev))
|
|
104
105
|
return;
|
|
105
|
-
const
|
|
106
|
+
const conversation = onebot12InboundConversation(String(this.#options.id), ev);
|
|
106
107
|
const content = formatInboundContent(ev);
|
|
107
108
|
const nickname = senderNickname(ev);
|
|
108
109
|
const mentioned = isBotMentioned(ev);
|
|
109
110
|
void this.#options.gateway.receive({
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
conversation,
|
|
112
|
+
message: { conversation, id: ev.message_id },
|
|
112
113
|
content,
|
|
113
114
|
sender: senderUserId(ev),
|
|
114
|
-
id: ev.message_id,
|
|
115
115
|
metadata: Object.freeze({
|
|
116
116
|
detail_type: ev.detail_type,
|
|
117
117
|
user_id: ev.user_id,
|
|
@@ -126,7 +126,8 @@ export class OneBot12WsEndpoint {
|
|
|
126
126
|
}).catch((err) => {
|
|
127
127
|
logger.warn(formatCompact({
|
|
128
128
|
op: 'onebot12_gateway_receive_failed',
|
|
129
|
-
|
|
129
|
+
kind: conversation.kind,
|
|
130
|
+
conversationId: conversation.id,
|
|
130
131
|
error: err instanceof Error ? err.message : String(err),
|
|
131
132
|
}));
|
|
132
133
|
});
|
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 OneBot12WssEndpoint 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 management surface / callers. */
|
|
26
23
|
callApi(action: string, params?: Record<string, unknown>): Promise<unknown>;
|
package/lib/wss-endpoint.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { clearInterval } from 'node:timers';
|
|
5
5
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
6
6
|
import { createOneBot12EndpointManagement } from './endpoint-management.js';
|
|
7
|
-
import { buildSendMessageParams, formatInboundContent,
|
|
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
10
|
const logger = getLogger('onebot12');
|
|
@@ -75,7 +75,7 @@ export class OneBot12WssEndpoint {
|
|
|
75
75
|
}
|
|
76
76
|
this.#started = false;
|
|
77
77
|
}
|
|
78
|
-
async send({
|
|
78
|
+
async send({ conversation, payload }) {
|
|
79
79
|
const materialized = await uploadOneBot12MediaSegments(payload, (action, params) => this.callApi(action, params), (error) => {
|
|
80
80
|
logger.warn(formatCompact({
|
|
81
81
|
op: 'onebot12_upload_failed',
|
|
@@ -84,7 +84,7 @@ export class OneBot12WssEndpoint {
|
|
|
84
84
|
}));
|
|
85
85
|
});
|
|
86
86
|
const message = formatOutboundSegments(materialized);
|
|
87
|
-
const params = buildSendMessageParams(
|
|
87
|
+
const params = buildSendMessageParams(conversation, message);
|
|
88
88
|
const data = await this.#callAction('send_message', params);
|
|
89
89
|
return data?.message_id ?? '';
|
|
90
90
|
}
|
|
@@ -100,15 +100,14 @@ export class OneBot12WssEndpoint {
|
|
|
100
100
|
admit(ev) {
|
|
101
101
|
if (!this.#open || !isMessageEvent(ev))
|
|
102
102
|
return;
|
|
103
|
-
const
|
|
103
|
+
const conversation = onebot12InboundConversation(String(this.#options.id), ev);
|
|
104
104
|
const nickname = senderNickname(ev);
|
|
105
105
|
const mentioned = isBotMentioned(ev);
|
|
106
106
|
void this.#options.gateway.receive({
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
conversation,
|
|
108
|
+
message: { conversation, id: ev.message_id },
|
|
109
109
|
content: formatInboundContent(ev),
|
|
110
110
|
sender: senderUserId(ev),
|
|
111
|
-
id: ev.message_id,
|
|
112
111
|
metadata: Object.freeze({
|
|
113
112
|
detail_type: ev.detail_type,
|
|
114
113
|
user_id: ev.user_id,
|
|
@@ -123,7 +122,8 @@ export class OneBot12WssEndpoint {
|
|
|
123
122
|
}).catch((err) => {
|
|
124
123
|
logger.warn(formatCompact({
|
|
125
124
|
op: 'onebot12_gateway_receive_failed',
|
|
126
|
-
|
|
125
|
+
kind: conversation.kind,
|
|
126
|
+
conversationId: conversation.id,
|
|
127
127
|
error: err instanceof Error ? err.message : String(err),
|
|
128
128
|
}));
|
|
129
129
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-onebot12",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"description": "Zhin.js OneBot 12 adapter for Plugin Runtime (WebSocket client)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -40,25 +40,26 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"ws": "^8.21.1",
|
|
43
|
-
"@zhin.js/adapter": "1.1.
|
|
44
|
-
"@zhin.js/command": "1.0.
|
|
45
|
-
"@zhin.js/core": "1.5.
|
|
46
|
-
"@zhin.js/host-http": "1.0.
|
|
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
47
|
"@zhin.js/logger": "1.0.75",
|
|
48
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
48
|
+
"@zhin.js/plugin-runtime": "1.1.3",
|
|
49
|
+
"@zhin.js/im-contract": "1.0.1"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@types/node": "^26.1.2",
|
|
52
53
|
"@types/ws": "^8.18.1",
|
|
53
54
|
"typescript": "^6.0.3",
|
|
54
55
|
"vitest": "^4.1.10",
|
|
55
|
-
"@zhin.js/host-http": "1.0.
|
|
56
|
+
"@zhin.js/host-http": "1.0.6"
|
|
56
57
|
},
|
|
57
58
|
"peerDependencies": {
|
|
58
|
-
"@zhin.js/adapter": "1.1.
|
|
59
|
-
"@zhin.js/core": "1.5.
|
|
60
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
61
|
-
"zhin.js": "6.0.
|
|
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"
|
|
62
63
|
},
|
|
63
64
|
"peerDependenciesMeta": {
|
|
64
65
|
"zhin.js": {
|
package/src/index.ts
CHANGED
|
@@ -3,14 +3,13 @@ export {
|
|
|
3
3
|
buildWsConnectOptions,
|
|
4
4
|
callOneBot12Action,
|
|
5
5
|
formatInboundContent,
|
|
6
|
-
formatInboundTarget,
|
|
7
6
|
formatOutboundSegments,
|
|
8
7
|
getChannelId,
|
|
9
8
|
isBotMentioned,
|
|
10
9
|
isMessageEvent,
|
|
11
10
|
mediaRefToOneBot12Fields,
|
|
12
11
|
mediaRefToOneBot12UploadParams,
|
|
13
|
-
|
|
12
|
+
onebot12InboundConversation,
|
|
14
13
|
resolveOneBot12Config,
|
|
15
14
|
senderNickname,
|
|
16
15
|
senderUserId,
|
|
@@ -29,7 +28,6 @@ export {
|
|
|
29
28
|
type OneBot12WireSegment,
|
|
30
29
|
type OneBot12WsConfig,
|
|
31
30
|
type OneBot12WssConfig,
|
|
32
|
-
type ParsedSendTarget,
|
|
33
31
|
type ResolvedOneBot12Config,
|
|
34
32
|
} from './protocol.js';
|
|
35
33
|
|
package/src/protocol.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Spec: https://12.onebot.dev/
|
|
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('onebot12');
|
|
@@ -118,12 +119,6 @@ export interface OneBot12WireSegment {
|
|
|
118
119
|
readonly data?: Record<string, unknown>;
|
|
119
120
|
}
|
|
120
121
|
|
|
121
|
-
export interface ParsedSendTarget {
|
|
122
|
-
readonly detail_type: 'private' | 'group' | 'channel';
|
|
123
|
-
readonly id: string;
|
|
124
|
-
readonly guild_id?: string;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
122
|
export function resolveOneBot12Config(config: OneBot12AdapterConfig = {}): ResolvedOneBot12Config {
|
|
128
123
|
const entry = config.endpoints?.find((item) => item.context === 'onebot12');
|
|
129
124
|
const connection = config.connection
|
|
@@ -204,37 +199,31 @@ export function getChannelId(ev: OneBot12Event): string {
|
|
|
204
199
|
}
|
|
205
200
|
|
|
206
201
|
/**
|
|
207
|
-
*
|
|
202
|
+
* 入站归一化 → ConversationRef:`detail_type` 直映射 kind;channel 的 guild 容器
|
|
203
|
+
* 进 `parent`(kind 'channel');私聊临时会话(private 事件携带 group_id)映射为
|
|
204
|
+
* group 容器内的 private 会话。
|
|
208
205
|
*/
|
|
209
|
-
export function
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
: '
|
|
213
|
-
return `${detail}:${getChannelId(ev)}`;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
export function parseSendTarget(target: string): ParsedSendTarget {
|
|
217
|
-
const sep = target.indexOf(':');
|
|
218
|
-
if (sep <= 0) {
|
|
219
|
-
return { detail_type: 'private', id: target };
|
|
220
|
-
}
|
|
221
|
-
const head = target.slice(0, sep);
|
|
222
|
-
const rest = target.slice(sep + 1);
|
|
223
|
-
if (head === 'private' || head === 'group') {
|
|
224
|
-
return { detail_type: head, id: rest };
|
|
206
|
+
export function onebot12InboundConversation(endpointId: string, ev: OneBot12Event): ConversationRef {
|
|
207
|
+
const endpoint = { id: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId };
|
|
208
|
+
if (ev.detail_type === 'group' && ev.group_id) {
|
|
209
|
+
return { endpoint, kind: 'group', id: ev.group_id };
|
|
225
210
|
}
|
|
226
|
-
if (
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
return { detail_type: 'channel', id: rest };
|
|
211
|
+
if (ev.detail_type === 'channel' && ev.channel_id) {
|
|
212
|
+
return {
|
|
213
|
+
endpoint,
|
|
214
|
+
kind: 'channel',
|
|
215
|
+
id: ev.channel_id,
|
|
216
|
+
...(ev.guild_id ? { parent: { kind: 'channel' as const, id: ev.guild_id } } : {}),
|
|
217
|
+
};
|
|
236
218
|
}
|
|
237
|
-
return {
|
|
219
|
+
return {
|
|
220
|
+
endpoint,
|
|
221
|
+
kind: 'private',
|
|
222
|
+
id: ev.user_id ?? ev.group_id ?? '',
|
|
223
|
+
...(ev.detail_type === 'private' && ev.group_id
|
|
224
|
+
? { parent: { kind: 'group' as const, id: ev.group_id } }
|
|
225
|
+
: {}),
|
|
226
|
+
};
|
|
238
227
|
}
|
|
239
228
|
|
|
240
229
|
/** Build inbound text for MessageGateway.receive */
|
|
@@ -501,22 +490,25 @@ export async function uploadOneBot12MediaSegments(
|
|
|
501
490
|
return uploadOneMediaSegment(payload, callAction, onUploadFailed);
|
|
502
491
|
}
|
|
503
492
|
|
|
493
|
+
/**
|
|
494
|
+
* 结构化会话 → OB12 `send_message` 动作参数:kind 直映射 detail_type;
|
|
495
|
+
* channel 的 guild 容器取自 `conversation.parent`(kind 'channel')。
|
|
496
|
+
*/
|
|
504
497
|
export function buildSendMessageParams(
|
|
505
|
-
|
|
498
|
+
conversation: ConversationRef,
|
|
506
499
|
message: OneBot12Segment[],
|
|
507
500
|
): Record<string, unknown> {
|
|
508
|
-
const parsed = parseSendTarget(target);
|
|
509
501
|
const params: Record<string, unknown> = {
|
|
510
502
|
message,
|
|
511
|
-
detail_type:
|
|
503
|
+
detail_type: conversation.kind,
|
|
512
504
|
};
|
|
513
|
-
if (
|
|
514
|
-
params.user_id =
|
|
515
|
-
} else if (
|
|
516
|
-
params.group_id =
|
|
505
|
+
if (conversation.kind === 'private') {
|
|
506
|
+
params.user_id = conversation.id;
|
|
507
|
+
} else if (conversation.kind === 'group') {
|
|
508
|
+
params.group_id = conversation.id;
|
|
517
509
|
} else {
|
|
518
|
-
params.channel_id =
|
|
519
|
-
if (
|
|
510
|
+
params.channel_id = conversation.id;
|
|
511
|
+
if (conversation.parent?.kind === 'channel') params.guild_id = conversation.parent.id;
|
|
520
512
|
}
|
|
521
513
|
return params;
|
|
522
514
|
}
|
package/src/webhook.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* OneBot12 HTTP webhook endpoint — POST inbound + api_url outbound.
|
|
3
3
|
*/
|
|
4
4
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
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, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
8
8
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
buildSendMessageParams,
|
|
13
13
|
callOneBot12Action,
|
|
14
14
|
formatInboundContent,
|
|
15
|
-
formatInboundTarget,
|
|
16
15
|
formatOutboundSegments,
|
|
17
16
|
isBotMentioned,
|
|
18
17
|
isMessageEvent,
|
|
18
|
+
onebot12InboundConversation,
|
|
19
19
|
senderNickname,
|
|
20
20
|
senderUserId,
|
|
21
21
|
uploadOneBot12MediaSegments,
|
|
@@ -83,7 +83,7 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
|
|
|
83
83
|
logger.debug(formatCompact({ op: 'disconnect', endpoint: this.#options.config.name }));
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
async send({
|
|
86
|
+
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
87
87
|
const materialized = await uploadOneBot12MediaSegments(
|
|
88
88
|
payload,
|
|
89
89
|
(action, params) => this.callApi(action, params),
|
|
@@ -96,13 +96,14 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
|
|
|
96
96
|
},
|
|
97
97
|
);
|
|
98
98
|
const message = formatOutboundSegments(materialized);
|
|
99
|
-
const params = buildSendMessageParams(
|
|
99
|
+
const params = buildSendMessageParams(conversation, message);
|
|
100
100
|
const data = await this.callApi('send_message', params) as { message_id?: string } | undefined;
|
|
101
101
|
const messageId = data?.message_id ?? '';
|
|
102
102
|
logger.debug(formatCompact({
|
|
103
103
|
op: 'onebot12_send',
|
|
104
104
|
endpoint: this.#options.config.name,
|
|
105
|
-
|
|
105
|
+
kind: conversation.kind,
|
|
106
|
+
conversationId: conversation.id,
|
|
106
107
|
messageId,
|
|
107
108
|
}));
|
|
108
109
|
return messageId;
|
|
@@ -124,16 +125,15 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
|
|
|
124
125
|
|
|
125
126
|
admit(ev: OneBot12Event): void {
|
|
126
127
|
if (!this.#open || !isMessageEvent(ev)) return;
|
|
127
|
-
const
|
|
128
|
+
const conversation = onebot12InboundConversation(String(this.#options.id), ev);
|
|
128
129
|
const content = formatInboundContent(ev);
|
|
129
130
|
const nickname = senderNickname(ev);
|
|
130
131
|
const mentioned = isBotMentioned(ev);
|
|
131
132
|
void this.#options.gateway.receive({
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
conversation,
|
|
134
|
+
message: { conversation, id: ev.message_id },
|
|
134
135
|
content,
|
|
135
136
|
sender: senderUserId(ev),
|
|
136
|
-
id: ev.message_id,
|
|
137
137
|
metadata: Object.freeze({
|
|
138
138
|
detail_type: ev.detail_type,
|
|
139
139
|
user_id: ev.user_id,
|
|
@@ -148,7 +148,8 @@ export class OneBot12WebhookEndpoint implements EndpointInstance {
|
|
|
148
148
|
}).catch((err) => {
|
|
149
149
|
logger.warn(formatCompact({
|
|
150
150
|
op: 'onebot12_gateway_receive_failed',
|
|
151
|
-
|
|
151
|
+
kind: conversation.kind,
|
|
152
|
+
conversationId: conversation.id,
|
|
152
153
|
error: err instanceof Error ? err.message : String(err),
|
|
153
154
|
}));
|
|
154
155
|
});
|
package/src/ws-endpoint.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type EndpointInstance,
|
|
10
10
|
type EndpointLifecycle,
|
|
11
11
|
type EndpointManagement,
|
|
12
|
+
type EndpointSendRequest,
|
|
12
13
|
} from '@zhin.js/adapter';
|
|
13
14
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
14
15
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
@@ -18,10 +19,10 @@ import {
|
|
|
18
19
|
buildSendMessageParams,
|
|
19
20
|
buildWsConnectOptions,
|
|
20
21
|
formatInboundContent,
|
|
21
|
-
formatInboundTarget,
|
|
22
22
|
formatOutboundSegments,
|
|
23
23
|
isBotMentioned,
|
|
24
24
|
isMessageEvent,
|
|
25
|
+
onebot12InboundConversation,
|
|
25
26
|
senderNickname,
|
|
26
27
|
senderUserId,
|
|
27
28
|
uploadOneBot12MediaSegments,
|
|
@@ -115,7 +116,7 @@ export class OneBot12WsEndpoint 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 materialized = await uploadOneBot12MediaSegments(
|
|
120
121
|
payload,
|
|
121
122
|
(action, params) => this.callApi(action, params),
|
|
@@ -128,13 +129,14 @@ export class OneBot12WsEndpoint implements EndpointInstance {
|
|
|
128
129
|
},
|
|
129
130
|
);
|
|
130
131
|
const message = formatOutboundSegments(materialized);
|
|
131
|
-
const params = buildSendMessageParams(
|
|
132
|
+
const params = buildSendMessageParams(conversation, message);
|
|
132
133
|
const data = await this.#callAction('send_message', params) as { message_id?: string } | undefined;
|
|
133
134
|
const messageId = data?.message_id ?? '';
|
|
134
135
|
logger.debug(formatCompact({
|
|
135
136
|
op: 'onebot12_send',
|
|
136
137
|
endpoint: this.#options.config.name,
|
|
137
|
-
|
|
138
|
+
kind: conversation.kind,
|
|
139
|
+
conversationId: conversation.id,
|
|
138
140
|
messageId,
|
|
139
141
|
}));
|
|
140
142
|
return messageId;
|
|
@@ -153,16 +155,15 @@ export class OneBot12WsEndpoint implements EndpointInstance {
|
|
|
153
155
|
/** Test / internal: admit a parsed event when the endpoint is open. */
|
|
154
156
|
admit(ev: OneBot12Event): void {
|
|
155
157
|
if (!this.#open || !isMessageEvent(ev)) return;
|
|
156
|
-
const
|
|
158
|
+
const conversation = onebot12InboundConversation(String(this.#options.id), ev);
|
|
157
159
|
const content = formatInboundContent(ev);
|
|
158
160
|
const nickname = senderNickname(ev);
|
|
159
161
|
const mentioned = isBotMentioned(ev);
|
|
160
162
|
void this.#options.gateway.receive({
|
|
161
|
-
|
|
162
|
-
|
|
163
|
+
conversation,
|
|
164
|
+
message: { conversation, id: ev.message_id },
|
|
163
165
|
content,
|
|
164
166
|
sender: senderUserId(ev),
|
|
165
|
-
id: ev.message_id,
|
|
166
167
|
metadata: Object.freeze({
|
|
167
168
|
detail_type: ev.detail_type,
|
|
168
169
|
user_id: ev.user_id,
|
|
@@ -177,7 +178,8 @@ export class OneBot12WsEndpoint implements EndpointInstance {
|
|
|
177
178
|
}).catch((err) => {
|
|
178
179
|
logger.warn(formatCompact({
|
|
179
180
|
op: 'onebot12_gateway_receive_failed',
|
|
180
|
-
|
|
181
|
+
kind: conversation.kind,
|
|
182
|
+
conversationId: conversation.id,
|
|
181
183
|
error: err instanceof Error ? err.message : String(err),
|
|
182
184
|
}));
|
|
183
185
|
});
|
package/src/wss-endpoint.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* OneBot12 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';
|
|
@@ -11,10 +11,10 @@ import { createOneBot12EndpointManagement } from './endpoint-management.js';
|
|
|
11
11
|
import {
|
|
12
12
|
buildSendMessageParams,
|
|
13
13
|
formatInboundContent,
|
|
14
|
-
formatInboundTarget,
|
|
15
14
|
formatOutboundSegments,
|
|
16
15
|
isBotMentioned,
|
|
17
16
|
isMessageEvent,
|
|
17
|
+
onebot12InboundConversation,
|
|
18
18
|
senderNickname,
|
|
19
19
|
senderUserId,
|
|
20
20
|
uploadOneBot12MediaSegments,
|
|
@@ -110,7 +110,7 @@ export class OneBot12WssEndpoint implements EndpointInstance {
|
|
|
110
110
|
this.#started = false;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
async send({
|
|
113
|
+
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
114
114
|
const materialized = await uploadOneBot12MediaSegments(
|
|
115
115
|
payload,
|
|
116
116
|
(action, params) => this.callApi(action, params),
|
|
@@ -123,7 +123,7 @@ export class OneBot12WssEndpoint implements EndpointInstance {
|
|
|
123
123
|
},
|
|
124
124
|
);
|
|
125
125
|
const message = formatOutboundSegments(materialized);
|
|
126
|
-
const params = buildSendMessageParams(
|
|
126
|
+
const params = buildSendMessageParams(conversation, message);
|
|
127
127
|
const data = await this.#callAction('send_message', params) as { message_id?: string } | undefined;
|
|
128
128
|
return data?.message_id ?? '';
|
|
129
129
|
}
|
|
@@ -140,15 +140,14 @@ export class OneBot12WssEndpoint implements EndpointInstance {
|
|
|
140
140
|
|
|
141
141
|
admit(ev: OneBot12Event): void {
|
|
142
142
|
if (!this.#open || !isMessageEvent(ev)) return;
|
|
143
|
-
const
|
|
143
|
+
const conversation = onebot12InboundConversation(String(this.#options.id), ev);
|
|
144
144
|
const nickname = senderNickname(ev);
|
|
145
145
|
const mentioned = isBotMentioned(ev);
|
|
146
146
|
void this.#options.gateway.receive({
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
conversation,
|
|
148
|
+
message: { conversation, id: ev.message_id },
|
|
149
149
|
content: formatInboundContent(ev),
|
|
150
150
|
sender: senderUserId(ev),
|
|
151
|
-
id: ev.message_id,
|
|
152
151
|
metadata: Object.freeze({
|
|
153
152
|
detail_type: ev.detail_type,
|
|
154
153
|
user_id: ev.user_id,
|
|
@@ -163,7 +162,8 @@ export class OneBot12WssEndpoint implements EndpointInstance {
|
|
|
163
162
|
}).catch((err) => {
|
|
164
163
|
logger.warn(formatCompact({
|
|
165
164
|
op: 'onebot12_gateway_receive_failed',
|
|
166
|
-
|
|
165
|
+
kind: conversation.kind,
|
|
166
|
+
conversationId: conversation.id,
|
|
167
167
|
error: err instanceof Error ? err.message : String(err),
|
|
168
168
|
}));
|
|
169
169
|
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|