@zhin.js/adapter-onebot12 1.1.22 → 1.1.23
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 +30 -0
- package/lib/protocol.d.ts +2 -0
- package/lib/protocol.js +13 -0
- package/lib/webhook.js +6 -1
- package/lib/ws-endpoint.js +10 -1
- package/lib/ws-types.d.ts +1 -0
- package/lib/wss-endpoint.js +10 -1
- package/package.json +16 -16
- package/src/protocol.ts +12 -0
- package/src/webhook.ts +6 -0
- package/src/ws-endpoint.ts +10 -0
- package/src/ws-types.ts +1 -0
- package/src/wss-endpoint.ts +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @zhin.js/adapter-onebot12
|
|
2
2
|
|
|
3
|
+
## 1.1.23
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- bc6ccb1: Deep audit bug fixes and 7 architectural improvements:
|
|
8
|
+
- Sink Agent Turn ingress pipeline from `@zhin.js/cli` into `@zhin.js/agent/runtime` (`plugin-runtime/ingress/`) and decompose `ingress-route.ts` into modular pipeline stages.
|
|
9
|
+
- Bind Session State Plane (`JsxButtonRegistry`, `InteractionRuntime`, `RuntimeInteractiveRouter`) to `PluginIncarnationRef` so active buttons and interactions survive unrelated-plugin HMR while expiring when the owning plugin reloads, and support per-conversation fallback numbering (`numberingScope: 'conversation'`).
|
|
10
|
+
- Establish `conversation_events` as the canonical message SSOT and reference `conversation_event_id`, `conversation_key`, `platform_message_id`, and `message_key` in `agent_messages` (`AGENT_MESSAGE_QUERY_VERSION = 2`), threading `conversationSequence` across inbound and outbound delivery receipts.
|
|
11
|
+
- Push down `DatabaseContextRepository` and `DatabaseScheduleJobStorage` full-session/full-table memory scans to indexed SQL queries.
|
|
12
|
+
- Add kernel-level inbound `replyTo` and `mentioned` auto-promotion (`promoteInboundMessagePayload`) plus reusable `InboundDeduper` and `TtlLookupCache` primitives in `@zhin.js/adapter`.
|
|
13
|
+
- Add `MiddlewareContext.dispatch` (`InboundDispatchSummary`) and `onAfterDispatch` hooks for `after-dispatch` middlewares, and support incremental rendering of in-place `envelope.payload` array mutations in `OutboundDeliveryRuntime`.
|
|
14
|
+
- Unify `HistoryWindowTracker` and `AgentCompactionRuntime` token/message budgets (`resolveUnifiedHistoryAndCompactionBudget`).
|
|
15
|
+
- Fix schema validation, database transaction connection cleanup and SQLite WAL mode, schedule timer wheel head-of-line blocking, security policy bash read paths and subagent guard propagation, group merge window permission carrier handoff, micro-compact namespaced tool matching, and WebSocket force-close / inbound segment mapping across adapters.
|
|
16
|
+
- Updated dependencies [6163abc]
|
|
17
|
+
- Updated dependencies [fed2c27]
|
|
18
|
+
- Updated dependencies [bc6ccb1]
|
|
19
|
+
- Updated dependencies [72b5a12]
|
|
20
|
+
- Updated dependencies [aa41889]
|
|
21
|
+
- Updated dependencies [4427e72]
|
|
22
|
+
- Updated dependencies [22bd14a]
|
|
23
|
+
- @zhin.js/core@1.1.57
|
|
24
|
+
- @zhin.js/client@1.1.25
|
|
25
|
+
- @zhin.js/page@1.1.15
|
|
26
|
+
- @zhin.js/im-contract@1.1.12
|
|
27
|
+
- @zhin.js/adapter@1.1.29
|
|
28
|
+
- @zhin.js/host-http@1.1.15
|
|
29
|
+
- @zhin.js/feature-kit@1.1.13
|
|
30
|
+
- @zhin.js/adapter-onebot-events@0.0.2
|
|
31
|
+
- @zhin.js/skill@1.1.14
|
|
32
|
+
|
|
3
33
|
## 1.1.22
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
package/lib/protocol.d.ts
CHANGED
|
@@ -121,6 +121,8 @@ export declare function senderNickname(ev: OneBot12Event): string | undefined;
|
|
|
121
121
|
* 新 Plugin Runtime 的 Message.content 为纯文本,mention 信息只能经 metadata.mentioned 传递。
|
|
122
122
|
*/
|
|
123
123
|
export declare function isBotMentioned(ev: OneBot12Event): boolean;
|
|
124
|
+
/** 提取入站消息中的回复引用 message_id。 */
|
|
125
|
+
export declare function extractQuoteId(ev: OneBot12Event): string | undefined;
|
|
124
126
|
/**
|
|
125
127
|
* canonical MediaRef → OneBot 12 媒体字段(扩展字段降级形状)。
|
|
126
128
|
* spec 正式投递形状是 `file_id`(先 upload_file 物化,见
|
package/lib/protocol.js
CHANGED
|
@@ -159,6 +159,19 @@ export function isBotMentioned(ev) {
|
|
|
159
159
|
return false;
|
|
160
160
|
return ev.message.some((seg) => seg.type === 'mention' && String(seg.data?.['user_id'] ?? '') === selfId);
|
|
161
161
|
}
|
|
162
|
+
/** 提取入站消息中的回复引用 message_id。 */
|
|
163
|
+
export function extractQuoteId(ev) {
|
|
164
|
+
if (!Array.isArray(ev.message))
|
|
165
|
+
return undefined;
|
|
166
|
+
for (const seg of ev.message) {
|
|
167
|
+
if (seg?.type === 'reply') {
|
|
168
|
+
const id = seg.data?.['message_id'] ?? seg.data?.['id'];
|
|
169
|
+
if (id != null && String(id).trim() !== '')
|
|
170
|
+
return String(id);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
162
175
|
/** OneBot 12 携带媒体的段类型。 */
|
|
163
176
|
const ONEBOT12_MEDIA_TYPES = new Set(['image', 'voice', 'audio', 'video', 'file']);
|
|
164
177
|
/** 媒体段 data 里的 canonical 字段,归一后不重复进 wire。 */
|
package/lib/webhook.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createOnebot12SelfProfile } from './self-profile.js';
|
|
2
|
+
import { toCanonicalSegments } from '@zhin.js/core';
|
|
2
3
|
import { acceptHttpIngress } from 'imhelper';
|
|
3
4
|
import { createEndpointSpecification, endpointSpec, createRecallEndpointControl, } from 'zhin.js/adapter';
|
|
4
5
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
5
6
|
import { createOneBot12EndpointManagement } from './endpoint-management.js';
|
|
6
|
-
import { buildSendMessageParams, matchesOneBot12Self, callOneBot12Action, formatInboundContent, formatOutboundSegments, isBotMentioned, isMessageEvent, onebot12InboundConversation, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
|
|
7
|
+
import { buildSendMessageParams, matchesOneBot12Self, callOneBot12Action, extractQuoteId, formatInboundContent, formatOutboundSegments, isBotMentioned, isMessageEvent, onebot12InboundConversation, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
|
|
7
8
|
import { receiveOneBot12SideEvent } from './side-event-dispatch.js';
|
|
8
9
|
import { createOneBot12ContentPort } from './content-port.js';
|
|
9
10
|
import { callOnebot12Client, readOnebot12Response, onebot12ClientOptions, forwardOnebot12ClientEvents, Onebot12Client } from './client.js';
|
|
@@ -125,15 +126,19 @@ export class OneBot12WebhookEndpoint extends Onebot12Client {
|
|
|
125
126
|
const content = formatInboundContent(ev);
|
|
126
127
|
const nickname = senderNickname(ev);
|
|
127
128
|
const mentioned = isBotMentioned(ev);
|
|
129
|
+
const quoteId = extractQuoteId(ev);
|
|
130
|
+
const segments = Array.isArray(ev.message) ? toCanonicalSegments(ev.message) : undefined;
|
|
128
131
|
void this[endpointSpec].events.message({
|
|
129
132
|
event: ev,
|
|
130
133
|
...(typeof ev.time === 'number' ? { platformSentAt: ev.time * 1000 } : {}),
|
|
131
134
|
conversation,
|
|
132
135
|
message: { conversation, id: ev.message_id },
|
|
133
136
|
content,
|
|
137
|
+
...(segments?.length ? { segments } : {}),
|
|
134
138
|
sender: { id: senderUserId(ev), ...(nickname ? { name: nickname } : {}) },
|
|
135
139
|
endpointId: this.#options.config.id,
|
|
136
140
|
...(mentioned ? { mentioned: true } : {}),
|
|
141
|
+
...(quoteId ? { replyTo: { id: quoteId } } : {}),
|
|
137
142
|
metadata: Object.freeze({
|
|
138
143
|
detail_type: ev.detail_type,
|
|
139
144
|
user_id: ev.user_id,
|
package/lib/ws-endpoint.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createOnebot12SelfProfile } from './self-profile.js';
|
|
2
|
+
import { toCanonicalSegments } from '@zhin.js/core';
|
|
2
3
|
/**
|
|
3
4
|
* OneBot12 WS client endpoint — outbound connect to OneBot implementation.
|
|
4
5
|
*/
|
|
@@ -6,7 +7,7 @@ import WebSocket from 'ws';
|
|
|
6
7
|
import { createEndpointSpecification, endpointSpec, createRecallEndpointControl, createEndpointLifecycle, } from 'zhin.js/adapter';
|
|
7
8
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
8
9
|
import { createOneBot12EndpointManagement } from './endpoint-management.js';
|
|
9
|
-
import { buildSendMessageParams, matchesOneBot12Self, buildWsConnectOptions, formatInboundContent, formatOutboundSegments, isBotMentioned, isMessageEvent, onebot12InboundConversation, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
|
|
10
|
+
import { buildSendMessageParams, matchesOneBot12Self, buildWsConnectOptions, extractQuoteId, formatInboundContent, formatOutboundSegments, isBotMentioned, isMessageEvent, onebot12InboundConversation, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
|
|
10
11
|
import { receiveOneBot12SideEvent } from './side-event-dispatch.js';
|
|
11
12
|
import { createOneBot12ContentPort } from './content-port.js';
|
|
12
13
|
import { callOnebot12Client, readOnebot12Response, onebot12ClientOptions, forwardOnebot12ClientEvents, Onebot12Client } from './client.js';
|
|
@@ -143,15 +144,19 @@ export class OneBot12WsEndpoint extends Onebot12Client {
|
|
|
143
144
|
const content = formatInboundContent(ev);
|
|
144
145
|
const nickname = senderNickname(ev);
|
|
145
146
|
const mentioned = isBotMentioned(ev);
|
|
147
|
+
const quoteId = extractQuoteId(ev);
|
|
148
|
+
const segments = Array.isArray(ev.message) ? toCanonicalSegments(ev.message) : undefined;
|
|
146
149
|
void this[endpointSpec].events.message({
|
|
147
150
|
event: ev,
|
|
148
151
|
...(typeof ev.time === 'number' ? { platformSentAt: ev.time * 1000 } : {}),
|
|
149
152
|
conversation,
|
|
150
153
|
message: { conversation, id: ev.message_id },
|
|
151
154
|
content,
|
|
155
|
+
...(segments?.length ? { segments } : {}),
|
|
152
156
|
sender: { id: senderUserId(ev), name: senderNickname(ev) },
|
|
153
157
|
endpointId: this.#options.config.id,
|
|
154
158
|
...(mentioned ? { mentioned: true } : {}),
|
|
159
|
+
...(quoteId ? { replyTo: { id: quoteId } } : {}),
|
|
155
160
|
metadata: Object.freeze({
|
|
156
161
|
detail_type: ev.detail_type,
|
|
157
162
|
user_id: ev.user_id,
|
|
@@ -185,8 +190,12 @@ export class OneBot12WsEndpoint extends Onebot12Client {
|
|
|
185
190
|
const ws = create(url, { headers });
|
|
186
191
|
this.#ws = ws;
|
|
187
192
|
handle.onForceClose(() => {
|
|
193
|
+
if (this.#ws === ws) {
|
|
194
|
+
this.#rpc.disconnect();
|
|
195
|
+
}
|
|
188
196
|
try {
|
|
189
197
|
ws.close();
|
|
198
|
+
ws.terminate?.();
|
|
190
199
|
}
|
|
191
200
|
catch {
|
|
192
201
|
/* ignore */
|
package/lib/ws-types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export interface OneBot12WsSocket {
|
|
|
3
3
|
readonly readyState: number;
|
|
4
4
|
send(data: string): void;
|
|
5
5
|
close(code?: number, reason?: string): void;
|
|
6
|
+
terminate?(): void;
|
|
6
7
|
on(event: 'open' | 'message' | 'close' | 'error', listener: (...args: unknown[]) => void): void;
|
|
7
8
|
}
|
|
8
9
|
export interface OneBot12WsCreateOptions {
|
package/lib/wss-endpoint.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { createOnebot12SelfProfile } from './self-profile.js';
|
|
2
|
+
import { toCanonicalSegments } from '@zhin.js/core';
|
|
2
3
|
/**
|
|
3
4
|
* OneBot12 reverse WSS endpoint — accepts inbound WebSocket from OneBot implementation.
|
|
4
5
|
*/
|
|
5
6
|
import { createEndpointSpecification, endpointSpec, createEndpointLifecycle, createRecallEndpointControl, } from 'zhin.js/adapter';
|
|
6
7
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
7
8
|
import { createOneBot12EndpointManagement } from './endpoint-management.js';
|
|
8
|
-
import { buildSendMessageParams, matchesOneBot12Self, formatInboundContent, formatOutboundSegments, isBotMentioned, isMessageEvent, onebot12InboundConversation, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
|
|
9
|
+
import { buildSendMessageParams, matchesOneBot12Self, extractQuoteId, formatInboundContent, formatOutboundSegments, isBotMentioned, isMessageEvent, onebot12InboundConversation, senderNickname, senderUserId, uploadOneBot12MediaSegments, } from './protocol.js';
|
|
9
10
|
import { receiveOneBot12SideEvent } from './side-event-dispatch.js';
|
|
10
11
|
import { createOneBot12ContentPort } from './content-port.js';
|
|
11
12
|
import { callOnebot12Client, readOnebot12Response, onebot12ClientOptions, forwardOnebot12ClientEvents, Onebot12Client } from './client.js';
|
|
@@ -144,15 +145,19 @@ export class OneBot12WssEndpoint extends Onebot12Client {
|
|
|
144
145
|
const conversation = { ...onebot12InboundConversation(String(this.#options.id), ev), endpoint: this[endpointSpec].identity };
|
|
145
146
|
const nickname = senderNickname(ev);
|
|
146
147
|
const mentioned = isBotMentioned(ev);
|
|
148
|
+
const quoteId = extractQuoteId(ev);
|
|
149
|
+
const segments = Array.isArray(ev.message) ? toCanonicalSegments(ev.message) : undefined;
|
|
147
150
|
void this[endpointSpec].events.message({
|
|
148
151
|
event: ev,
|
|
149
152
|
...(typeof ev.time === 'number' ? { platformSentAt: ev.time * 1000 } : {}),
|
|
150
153
|
conversation,
|
|
151
154
|
message: { conversation, id: ev.message_id },
|
|
152
155
|
content: formatInboundContent(ev),
|
|
156
|
+
...(segments?.length ? { segments } : {}),
|
|
153
157
|
sender: { id: senderUserId(ev), name: senderNickname(ev) },
|
|
154
158
|
endpointId: this.#options.config.id,
|
|
155
159
|
...(mentioned ? { mentioned: true } : {}),
|
|
160
|
+
...(quoteId ? { replyTo: { id: quoteId } } : {}),
|
|
156
161
|
metadata: Object.freeze({
|
|
157
162
|
detail_type: ev.detail_type,
|
|
158
163
|
user_id: ev.user_id,
|
|
@@ -188,8 +193,12 @@ export class OneBot12WssEndpoint extends Onebot12Client {
|
|
|
188
193
|
await this.#connectionLifecycle.start(async (lifecycleHandle) => {
|
|
189
194
|
this.#ws = socket;
|
|
190
195
|
lifecycleHandle.onForceClose(() => {
|
|
196
|
+
if (this.#ws === socket) {
|
|
197
|
+
this.#rpc.disconnect();
|
|
198
|
+
}
|
|
191
199
|
try {
|
|
192
200
|
socket.close();
|
|
201
|
+
socket.terminate?.();
|
|
193
202
|
}
|
|
194
203
|
catch {
|
|
195
204
|
/* ignore */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-onebot12",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.23",
|
|
4
4
|
"description": "Zhin.js OneBot 12 adapter for Plugin Runtime (WebSocket client)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -42,31 +42,31 @@
|
|
|
42
42
|
"@imhelper/onebot-v12": "1.0.7",
|
|
43
43
|
"imhelper": "1.0.7",
|
|
44
44
|
"ws": "^8.21.1",
|
|
45
|
-
"@zhin.js/adapter-onebot-events": "0.0.
|
|
46
|
-
"@zhin.js/adapter": "1.1.
|
|
47
|
-
"@zhin.js/client": "1.1.
|
|
45
|
+
"@zhin.js/adapter-onebot-events": "0.0.2",
|
|
46
|
+
"@zhin.js/adapter": "1.1.29",
|
|
47
|
+
"@zhin.js/client": "1.1.25",
|
|
48
48
|
"@zhin.js/console-contract": "1.1.3",
|
|
49
|
-
"@zhin.js/core": "1.1.
|
|
50
|
-
"@zhin.js/feature-kit": "1.1.
|
|
51
|
-
"@zhin.js/host-http": "1.1.
|
|
52
|
-
"@zhin.js/im-contract": "1.1.
|
|
49
|
+
"@zhin.js/core": "1.1.57",
|
|
50
|
+
"@zhin.js/feature-kit": "1.1.13",
|
|
51
|
+
"@zhin.js/host-http": "1.1.15",
|
|
52
|
+
"@zhin.js/im-contract": "1.1.12",
|
|
53
53
|
"@zhin.js/logger": "1.1.2",
|
|
54
|
-
"@zhin.js/page": "1.1.
|
|
55
|
-
"@zhin.js/skill": "1.1.
|
|
54
|
+
"@zhin.js/page": "1.1.15",
|
|
55
|
+
"@zhin.js/skill": "1.1.14"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/node": "^26.1.2",
|
|
59
59
|
"@types/ws": "^8.18.1",
|
|
60
60
|
"typescript": "^6.0.3",
|
|
61
61
|
"vitest": "^4.1.10",
|
|
62
|
-
"@zhin.js/host-http": "1.1.
|
|
63
|
-
"zhin.js": "1.1.
|
|
62
|
+
"@zhin.js/host-http": "1.1.15",
|
|
63
|
+
"zhin.js": "1.1.22"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@zhin.js/adapter": "^1.1.
|
|
67
|
-
"@zhin.js/command": "^1.1.
|
|
68
|
-
"@zhin.js/core": "^1.1.
|
|
69
|
-
"zhin.js": "^1.1.
|
|
66
|
+
"@zhin.js/adapter": "^1.1.29",
|
|
67
|
+
"@zhin.js/command": "^1.1.15",
|
|
68
|
+
"@zhin.js/core": "^1.1.57",
|
|
69
|
+
"zhin.js": "^1.1.22"
|
|
70
70
|
},
|
|
71
71
|
"peerDependenciesMeta": {
|
|
72
72
|
"@zhin.js/command": {
|
package/src/protocol.ts
CHANGED
|
@@ -278,6 +278,18 @@ export function isBotMentioned(ev: OneBot12Event): boolean {
|
|
|
278
278
|
);
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
/** 提取入站消息中的回复引用 message_id。 */
|
|
282
|
+
export function extractQuoteId(ev: OneBot12Event): string | undefined {
|
|
283
|
+
if (!Array.isArray(ev.message)) return undefined;
|
|
284
|
+
for (const seg of ev.message) {
|
|
285
|
+
if (seg?.type === 'reply') {
|
|
286
|
+
const id = seg.data?.['message_id'] ?? seg.data?.['id'];
|
|
287
|
+
if (id != null && String(id).trim() !== '') return String(id);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
|
|
281
293
|
/** OneBot 12 携带媒体的段类型。 */
|
|
282
294
|
const ONEBOT12_MEDIA_TYPES = new Set(['image', 'voice', 'audio', 'video', 'file']);
|
|
283
295
|
|
package/src/webhook.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createOnebot12SelfProfile } from './self-profile.js';
|
|
2
|
+
import { toCanonicalSegments } from '@zhin.js/core';
|
|
2
3
|
import { acceptHttpIngress } from 'imhelper';
|
|
3
4
|
/**
|
|
4
5
|
* OneBot12 HTTP webhook endpoint — POST inbound + api_url outbound.
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
buildSendMessageParams,
|
|
22
23
|
matchesOneBot12Self,
|
|
23
24
|
callOneBot12Action,
|
|
25
|
+
extractQuoteId,
|
|
24
26
|
formatInboundContent,
|
|
25
27
|
formatOutboundSegments,
|
|
26
28
|
isBotMentioned,
|
|
@@ -164,15 +166,19 @@ export class OneBot12WebhookEndpoint extends Onebot12Client implements Endpoint
|
|
|
164
166
|
const content = formatInboundContent(ev);
|
|
165
167
|
const nickname = senderNickname(ev);
|
|
166
168
|
const mentioned = isBotMentioned(ev);
|
|
169
|
+
const quoteId = extractQuoteId(ev);
|
|
170
|
+
const segments = Array.isArray(ev.message) ? toCanonicalSegments(ev.message) : undefined;
|
|
167
171
|
void this[endpointSpec].events.message({
|
|
168
172
|
event: ev,
|
|
169
173
|
...(typeof ev.time === 'number' ? { platformSentAt: ev.time * 1000 } : {}),
|
|
170
174
|
conversation,
|
|
171
175
|
message: { conversation, id: ev.message_id },
|
|
172
176
|
content,
|
|
177
|
+
...(segments?.length ? { segments } : {}),
|
|
173
178
|
sender: { id: senderUserId(ev), ...(nickname ? { name: nickname } : {}) },
|
|
174
179
|
endpointId: this.#options.config.id,
|
|
175
180
|
...(mentioned ? { mentioned: true } : {}),
|
|
181
|
+
...(quoteId ? { replyTo: { id: quoteId } } : {}),
|
|
176
182
|
metadata: Object.freeze({
|
|
177
183
|
detail_type: ev.detail_type,
|
|
178
184
|
user_id: ev.user_id,
|
package/src/ws-endpoint.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createOnebot12SelfProfile } from './self-profile.js';
|
|
2
|
+
import { toCanonicalSegments } from '@zhin.js/core';
|
|
2
3
|
/**
|
|
3
4
|
* OneBot12 WS client endpoint — outbound connect to OneBot implementation.
|
|
4
5
|
*/
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
buildSendMessageParams,
|
|
23
24
|
matchesOneBot12Self,
|
|
24
25
|
buildWsConnectOptions,
|
|
26
|
+
extractQuoteId,
|
|
25
27
|
formatInboundContent,
|
|
26
28
|
formatOutboundSegments,
|
|
27
29
|
isBotMentioned,
|
|
@@ -182,15 +184,19 @@ export class OneBot12WsEndpoint extends Onebot12Client implements Endpoint {
|
|
|
182
184
|
const content = formatInboundContent(ev);
|
|
183
185
|
const nickname = senderNickname(ev);
|
|
184
186
|
const mentioned = isBotMentioned(ev);
|
|
187
|
+
const quoteId = extractQuoteId(ev);
|
|
188
|
+
const segments = Array.isArray(ev.message) ? toCanonicalSegments(ev.message) : undefined;
|
|
185
189
|
void this[endpointSpec].events.message({
|
|
186
190
|
event: ev,
|
|
187
191
|
...(typeof ev.time === 'number' ? { platformSentAt: ev.time * 1000 } : {}),
|
|
188
192
|
conversation,
|
|
189
193
|
message: { conversation, id: ev.message_id },
|
|
190
194
|
content,
|
|
195
|
+
...(segments?.length ? { segments } : {}),
|
|
191
196
|
sender: { id: senderUserId(ev), name: senderNickname(ev) },
|
|
192
197
|
endpointId: this.#options.config.id,
|
|
193
198
|
...(mentioned ? { mentioned: true } : {}),
|
|
199
|
+
...(quoteId ? { replyTo: { id: quoteId } } : {}),
|
|
194
200
|
metadata: Object.freeze({
|
|
195
201
|
detail_type: ev.detail_type,
|
|
196
202
|
user_id: ev.user_id,
|
|
@@ -228,8 +234,12 @@ export class OneBot12WsEndpoint extends Onebot12Client implements Endpoint {
|
|
|
228
234
|
const ws = create(url, { headers });
|
|
229
235
|
this.#ws = ws;
|
|
230
236
|
handle.onForceClose(() => {
|
|
237
|
+
if (this.#ws === ws) {
|
|
238
|
+
this.#rpc.disconnect();
|
|
239
|
+
}
|
|
231
240
|
try {
|
|
232
241
|
ws.close();
|
|
242
|
+
ws.terminate?.();
|
|
233
243
|
} catch {
|
|
234
244
|
/* ignore */
|
|
235
245
|
}
|
package/src/ws-types.ts
CHANGED
package/src/wss-endpoint.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createOnebot12SelfProfile } from './self-profile.js';
|
|
2
|
+
import { toCanonicalSegments } from '@zhin.js/core';
|
|
2
3
|
/**
|
|
3
4
|
* OneBot12 reverse WSS endpoint — accepts inbound WebSocket from OneBot implementation.
|
|
4
5
|
*/
|
|
@@ -20,6 +21,7 @@ import { createOneBot12EndpointManagement } from './endpoint-management.js';
|
|
|
20
21
|
import {
|
|
21
22
|
buildSendMessageParams,
|
|
22
23
|
matchesOneBot12Self,
|
|
24
|
+
extractQuoteId,
|
|
23
25
|
formatInboundContent,
|
|
24
26
|
formatOutboundSegments,
|
|
25
27
|
isBotMentioned,
|
|
@@ -179,15 +181,19 @@ export class OneBot12WssEndpoint extends Onebot12Client implements Endpoint {
|
|
|
179
181
|
const conversation = { ...onebot12InboundConversation(String(this.#options.id), ev), endpoint: this[endpointSpec].identity };
|
|
180
182
|
const nickname = senderNickname(ev);
|
|
181
183
|
const mentioned = isBotMentioned(ev);
|
|
184
|
+
const quoteId = extractQuoteId(ev);
|
|
185
|
+
const segments = Array.isArray(ev.message) ? toCanonicalSegments(ev.message) : undefined;
|
|
182
186
|
void this[endpointSpec].events.message({
|
|
183
187
|
event: ev,
|
|
184
188
|
...(typeof ev.time === 'number' ? { platformSentAt: ev.time * 1000 } : {}),
|
|
185
189
|
conversation,
|
|
186
190
|
message: { conversation, id: ev.message_id },
|
|
187
191
|
content: formatInboundContent(ev),
|
|
192
|
+
...(segments?.length ? { segments } : {}),
|
|
188
193
|
sender: { id: senderUserId(ev), name: senderNickname(ev) },
|
|
189
194
|
endpointId: this.#options.config.id,
|
|
190
195
|
...(mentioned ? { mentioned: true } : {}),
|
|
196
|
+
...(quoteId ? { replyTo: { id: quoteId } } : {}),
|
|
191
197
|
metadata: Object.freeze({
|
|
192
198
|
detail_type: ev.detail_type,
|
|
193
199
|
user_id: ev.user_id,
|
|
@@ -225,8 +231,12 @@ export class OneBot12WssEndpoint extends Onebot12Client implements Endpoint {
|
|
|
225
231
|
await this.#connectionLifecycle.start(async (lifecycleHandle) => {
|
|
226
232
|
this.#ws = socket;
|
|
227
233
|
lifecycleHandle.onForceClose(() => {
|
|
234
|
+
if (this.#ws === socket) {
|
|
235
|
+
this.#rpc.disconnect();
|
|
236
|
+
}
|
|
228
237
|
try {
|
|
229
238
|
socket.close();
|
|
239
|
+
socket.terminate?.();
|
|
230
240
|
} catch {
|
|
231
241
|
/* ignore */
|
|
232
242
|
}
|