@zhin.js/adapter-onebot11 4.0.1 → 4.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 +56 -0
- package/README.md +40 -370
- package/adapters/onebot11.ts +39 -0
- package/agent/tools/set_title.ts +21 -0
- package/lib/index.d.ts +7 -16
- package/lib/index.js +6 -56
- package/lib/onebot11-agent-deps.d.ts +15 -0
- package/lib/onebot11-agent-deps.js +30 -0
- package/lib/protocol.d.ts +144 -0
- package/lib/protocol.js +235 -0
- package/lib/ws-endpoint.d.ts +28 -0
- package/lib/ws-endpoint.js +210 -0
- package/lib/ws-transport.d.ts +13 -0
- package/lib/ws-transport.js +74 -0
- package/lib/ws-types.d.ts +17 -0
- package/lib/ws-types.js +1 -0
- package/lib/wss-auth.d.ts +2 -0
- package/lib/wss-auth.js +16 -0
- package/lib/wss-endpoint.d.ts +26 -0
- package/lib/wss-endpoint.js +143 -0
- package/package.json +52 -22
- package/plugin.ts +13 -0
- package/schema.json +36 -0
- package/src/index.ts +54 -68
- package/src/onebot11-agent-deps.ts +49 -0
- package/src/protocol.ts +370 -0
- package/src/ws-endpoint.ts +266 -0
- package/src/ws-transport.ts +101 -0
- package/src/ws-types.ts +20 -0
- package/src/wss-auth.ts +17 -0
- package/src/wss-endpoint.ts +189 -0
- package/lib/adapter.d.ts +0 -41
- package/lib/adapter.d.ts.map +0 -1
- package/lib/adapter.js +0 -101
- package/lib/adapter.js.map +0 -1
- package/lib/endpoint-ws-client.d.ts +0 -41
- package/lib/endpoint-ws-client.d.ts.map +0 -1
- package/lib/endpoint-ws-client.js +0 -408
- package/lib/endpoint-ws-client.js.map +0 -1
- package/lib/endpoint-ws-server.d.ts +0 -43
- package/lib/endpoint-ws-server.d.ts.map +0 -1
- package/lib/endpoint-ws-server.js +0 -355
- package/lib/endpoint-ws-server.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/onebot-get-msg.d.ts +0 -3
- package/lib/onebot-get-msg.d.ts.map +0 -1
- package/lib/onebot-get-msg.js +0 -27
- package/lib/onebot-get-msg.js.map +0 -1
- package/lib/segment-mapper.d.ts +0 -2
- package/lib/segment-mapper.d.ts.map +0 -1
- package/lib/segment-mapper.js +0 -2
- package/lib/segment-mapper.js.map +0 -1
- package/lib/types.d.ts +0 -61
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js +0 -5
- package/lib/types.js.map +0 -1
- package/plugin.yml +0 -3
- package/src/adapter.ts +0 -114
- package/src/endpoint-ws-client.ts +0 -435
- package/src/endpoint-ws-server.ts +0 -396
- package/src/onebot-get-msg.ts +0 -33
- package/src/segment-mapper.ts +0 -1
- package/src/types.ts +0 -60
- /package/{skills/onebot11 → agent}/PERMITS.md +0 -0
- /package/{skills/onebot11/SKILL.md → agent/skills/onebot11.md} +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { clearInterval, clearTimeout, setInterval, setTimeout } from 'node:timers';
|
|
2
|
+
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
3
|
+
import {
|
|
4
|
+
type OneBot11ActionRequest,
|
|
5
|
+
type OneBot11ActionResponse,
|
|
6
|
+
type OneBot11Event,
|
|
7
|
+
} from './protocol.js';
|
|
8
|
+
import {
|
|
9
|
+
WS_OPEN,
|
|
10
|
+
type OneBot11PendingAction,
|
|
11
|
+
type OneBot11WsSocket,
|
|
12
|
+
} from './ws-types.js';
|
|
13
|
+
|
|
14
|
+
const logger = getLogger('onebot11');
|
|
15
|
+
|
|
16
|
+
export function decodeWsPayload(data: unknown): string {
|
|
17
|
+
if (typeof data === 'string') return data;
|
|
18
|
+
if (Buffer.isBuffer(data)) return data.toString();
|
|
19
|
+
if (data instanceof ArrayBuffer) return new TextDecoder().decode(data);
|
|
20
|
+
return String(data ?? '');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function handleOneBot11WsMessage(
|
|
24
|
+
data: unknown,
|
|
25
|
+
options: {
|
|
26
|
+
readonly endpointName: string;
|
|
27
|
+
readonly pending: Map<string, OneBot11PendingAction>;
|
|
28
|
+
readonly admit: (ev: OneBot11Event) => void;
|
|
29
|
+
},
|
|
30
|
+
): void {
|
|
31
|
+
try {
|
|
32
|
+
const raw = decodeWsPayload(data);
|
|
33
|
+
const msg = JSON.parse(raw) as OneBot11Event | OneBot11ActionResponse;
|
|
34
|
+
if ('echo' in msg && typeof (msg as OneBot11ActionResponse).echo === 'string') {
|
|
35
|
+
const resp = msg as OneBot11ActionResponse;
|
|
36
|
+
const pending = options.pending.get(resp.echo!);
|
|
37
|
+
if (pending) {
|
|
38
|
+
options.pending.delete(resp.echo!);
|
|
39
|
+
clearTimeout(pending.timeout);
|
|
40
|
+
if (resp.status === 'ok') pending.resolve(resp.data);
|
|
41
|
+
else pending.reject(new Error(`OneBot11 retcode=${resp.retcode}`));
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
options.admit(msg as OneBot11Event);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
logger.warn(formatCompact({
|
|
48
|
+
op: 'onebot11_parse_failed',
|
|
49
|
+
endpoint: options.endpointName,
|
|
50
|
+
error: error instanceof Error ? error.message : String(error),
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function callOneBot11WsAction(
|
|
56
|
+
ws: OneBot11WsSocket | undefined,
|
|
57
|
+
pending: Map<string, OneBot11PendingAction>,
|
|
58
|
+
requestId: { value: number },
|
|
59
|
+
action: string,
|
|
60
|
+
params: Record<string, unknown>,
|
|
61
|
+
): Promise<unknown> {
|
|
62
|
+
if (!ws || ws.readyState !== WS_OPEN) {
|
|
63
|
+
return Promise.reject(new Error('WebSocket 未连接'));
|
|
64
|
+
}
|
|
65
|
+
const echo = `ob11_${++requestId.value}`;
|
|
66
|
+
const req: OneBot11ActionRequest = { action, params, echo };
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const timeout = setTimeout(() => {
|
|
69
|
+
pending.delete(echo);
|
|
70
|
+
reject(new Error(`OneBot11 动作超时: ${action}`));
|
|
71
|
+
}, 30_000);
|
|
72
|
+
pending.set(echo, { resolve, reject, timeout });
|
|
73
|
+
ws.send(JSON.stringify(req));
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function startOneBot11Heartbeat(
|
|
78
|
+
ws: OneBot11WsSocket | undefined,
|
|
79
|
+
intervalMs: number,
|
|
80
|
+
existingTimer?: NodeJS.Timeout,
|
|
81
|
+
): NodeJS.Timeout {
|
|
82
|
+
if (existingTimer) clearInterval(existingTimer);
|
|
83
|
+
return setInterval(() => {
|
|
84
|
+
try {
|
|
85
|
+
ws?.ping?.();
|
|
86
|
+
} catch {
|
|
87
|
+
/* ignore */
|
|
88
|
+
}
|
|
89
|
+
}, intervalMs);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function rejectAllPending(
|
|
93
|
+
pending: Map<string, OneBot11PendingAction>,
|
|
94
|
+
message = '连接已关闭',
|
|
95
|
+
): void {
|
|
96
|
+
for (const [, entry] of pending) {
|
|
97
|
+
clearTimeout(entry.timeout);
|
|
98
|
+
entry.reject(new Error(message));
|
|
99
|
+
}
|
|
100
|
+
pending.clear();
|
|
101
|
+
}
|
package/src/ws-types.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Minimal WS surface used by the endpoint (real `ws` or test mock). */
|
|
2
|
+
export interface OneBot11WsSocket {
|
|
3
|
+
readonly readyState: number;
|
|
4
|
+
send(data: string): void;
|
|
5
|
+
close(code?: number, reason?: string): void;
|
|
6
|
+
ping?(): void;
|
|
7
|
+
on(event: 'open' | 'message' | 'close' | 'error', listener: (...args: unknown[]) => void): void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface OneBot11WsCreateOptions {
|
|
11
|
+
readonly headers?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const WS_OPEN = 1;
|
|
15
|
+
|
|
16
|
+
export interface OneBot11PendingAction {
|
|
17
|
+
resolve: (value: unknown) => void;
|
|
18
|
+
reject: (err: Error) => void;
|
|
19
|
+
timeout: NodeJS.Timeout;
|
|
20
|
+
}
|
package/src/wss-auth.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IncomingMessage } from 'node:http';
|
|
2
|
+
|
|
3
|
+
export function verifyOneBotAccessToken(
|
|
4
|
+
accessToken: string | undefined,
|
|
5
|
+
request: IncomingMessage,
|
|
6
|
+
): boolean {
|
|
7
|
+
if (!accessToken) return true;
|
|
8
|
+
const auth = request.headers.authorization ?? '';
|
|
9
|
+
if (auth === `Bearer ${accessToken}`) return true;
|
|
10
|
+
try {
|
|
11
|
+
const url = new URL(request.url ?? '/', 'http://localhost');
|
|
12
|
+
if (url.searchParams.get('access_token') === accessToken) return true;
|
|
13
|
+
} catch {
|
|
14
|
+
/* ignore */
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OneBot11 reverse WSS endpoint — accepts inbound WebSocket from OneBot implementation.
|
|
3
|
+
*/
|
|
4
|
+
import { clearInterval } from 'node:timers';
|
|
5
|
+
import type { EndpointInstance } from '@zhin.js/adapter';
|
|
6
|
+
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
7
|
+
import type { HttpHost, WsConnection } from '@zhin.js/host-http';
|
|
8
|
+
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
9
|
+
import type { CapabilityId } from '@zhin.js/plugin-runtime';
|
|
10
|
+
import { registerOnebot11AgentEndpoint } from './onebot11-agent-deps.js';
|
|
11
|
+
import {
|
|
12
|
+
buildSendAction,
|
|
13
|
+
formatInboundContent,
|
|
14
|
+
formatInboundMetadata,
|
|
15
|
+
formatInboundTarget,
|
|
16
|
+
formatOutboundSegments,
|
|
17
|
+
isMessageEvent,
|
|
18
|
+
senderUserId,
|
|
19
|
+
type OneBot11Event,
|
|
20
|
+
type OneBot11WssConfig,
|
|
21
|
+
} from './protocol.js';
|
|
22
|
+
import { verifyOneBotAccessToken } from './wss-auth.js';
|
|
23
|
+
import {
|
|
24
|
+
callOneBot11WsAction,
|
|
25
|
+
handleOneBot11WsMessage,
|
|
26
|
+
rejectAllPending,
|
|
27
|
+
startOneBot11Heartbeat,
|
|
28
|
+
} from './ws-transport.js';
|
|
29
|
+
import { OneBot11WsEndpoint } from './ws-endpoint.js';
|
|
30
|
+
import {
|
|
31
|
+
type OneBot11PendingAction,
|
|
32
|
+
type OneBot11WsSocket,
|
|
33
|
+
} from './ws-types.js';
|
|
34
|
+
|
|
35
|
+
const logger = getLogger('onebot11');
|
|
36
|
+
|
|
37
|
+
export interface OneBot11WssEndpointOptions {
|
|
38
|
+
readonly id: CapabilityId;
|
|
39
|
+
readonly gateway: MessageGateway;
|
|
40
|
+
readonly http: HttpHost;
|
|
41
|
+
readonly config: OneBot11WssConfig;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class OneBot11WssEndpoint implements EndpointInstance {
|
|
45
|
+
readonly #options: OneBot11WssEndpointOptions;
|
|
46
|
+
#ws?: OneBot11WsSocket;
|
|
47
|
+
#wsRelease?: () => void;
|
|
48
|
+
#heartbeatTimer?: NodeJS.Timeout;
|
|
49
|
+
#requestId = { value: 0 };
|
|
50
|
+
#pending = new Map<string, OneBot11PendingAction>();
|
|
51
|
+
#open = false;
|
|
52
|
+
#started = false;
|
|
53
|
+
#unregisterAgent?: () => void;
|
|
54
|
+
|
|
55
|
+
constructor(options: OneBot11WssEndpointOptions) {
|
|
56
|
+
this.#options = options;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async start(): Promise<void> {
|
|
60
|
+
if (this.#started) return;
|
|
61
|
+
this.#started = true;
|
|
62
|
+
this.#unregisterAgent = registerOnebot11AgentEndpoint(
|
|
63
|
+
this.#options.config.name,
|
|
64
|
+
this as unknown as OneBot11WsEndpoint,
|
|
65
|
+
);
|
|
66
|
+
const handle = this.#options.http.ws(this.#options.config.path);
|
|
67
|
+
this.#wsRelease = handle.onConnection((connection) => {
|
|
68
|
+
this.#acceptConnection(connection);
|
|
69
|
+
});
|
|
70
|
+
logger.info(formatCompact({
|
|
71
|
+
op: 'listen',
|
|
72
|
+
endpoint: this.#options.config.name,
|
|
73
|
+
mode: 'wss',
|
|
74
|
+
path: this.#options.config.path,
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
open(): void {
|
|
79
|
+
this.#open = true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
close(): void {
|
|
83
|
+
this.#open = false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async stop(): Promise<void> {
|
|
87
|
+
this.#open = false;
|
|
88
|
+
this.#unregisterAgent?.();
|
|
89
|
+
this.#unregisterAgent = undefined;
|
|
90
|
+
this.#wsRelease?.();
|
|
91
|
+
this.#wsRelease = undefined;
|
|
92
|
+
if (this.#heartbeatTimer) {
|
|
93
|
+
clearInterval(this.#heartbeatTimer);
|
|
94
|
+
this.#heartbeatTimer = undefined;
|
|
95
|
+
}
|
|
96
|
+
rejectAllPending(this.#pending);
|
|
97
|
+
if (this.#ws) {
|
|
98
|
+
try {
|
|
99
|
+
this.#ws.close();
|
|
100
|
+
} catch {
|
|
101
|
+
/* ignore */
|
|
102
|
+
}
|
|
103
|
+
this.#ws = undefined;
|
|
104
|
+
}
|
|
105
|
+
this.#started = false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async send({ target, payload }: { readonly target: string; readonly payload: unknown }): Promise<string> {
|
|
109
|
+
const message = formatOutboundSegments(payload);
|
|
110
|
+
const { action, params } = buildSendAction(target, message);
|
|
111
|
+
const data = await this.callApi(action, params) as { message_id?: number | string } | undefined;
|
|
112
|
+
return data?.message_id != null ? String(data.message_id) : '';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
callApi(action: string, params: Record<string, unknown> = {}): Promise<unknown> {
|
|
116
|
+
return callOneBot11WsAction(this.#ws, this.#pending, this.#requestId, action, params);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async setTitle(groupId: number, userId: number, title: string, duration = -1): Promise<boolean> {
|
|
120
|
+
await this.callApi('set_group_special_title', {
|
|
121
|
+
group_id: groupId,
|
|
122
|
+
user_id: userId,
|
|
123
|
+
special_title: title,
|
|
124
|
+
duration,
|
|
125
|
+
});
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
admit(ev: OneBot11Event): void {
|
|
130
|
+
if (!this.#open || !isMessageEvent(ev)) return;
|
|
131
|
+
const target = formatInboundTarget(ev);
|
|
132
|
+
void this.#options.gateway.receive({
|
|
133
|
+
adapter: this.#options.id,
|
|
134
|
+
target,
|
|
135
|
+
content: formatInboundContent(ev),
|
|
136
|
+
sender: senderUserId(ev),
|
|
137
|
+
id: String(ev.message_id),
|
|
138
|
+
metadata: formatInboundMetadata(ev, this.#options.config.name),
|
|
139
|
+
}).catch((err) => {
|
|
140
|
+
logger.warn(formatCompact({
|
|
141
|
+
op: 'onebot11_gateway_receive_failed',
|
|
142
|
+
target,
|
|
143
|
+
error: err instanceof Error ? err.message : String(err),
|
|
144
|
+
}));
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#acceptConnection(connection: WsConnection): void {
|
|
149
|
+
if (!verifyOneBotAccessToken(this.#options.config.access_token, connection.request)) {
|
|
150
|
+
connection.socket.close(4003, 'Unauthorized');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const socket = connection.socket as unknown as OneBot11WsSocket;
|
|
154
|
+
if (this.#ws) {
|
|
155
|
+
try {
|
|
156
|
+
this.#ws.close();
|
|
157
|
+
} catch {
|
|
158
|
+
/* ignore */
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
this.#ws = socket;
|
|
162
|
+
this.#heartbeatTimer = startOneBot11Heartbeat(
|
|
163
|
+
this.#ws,
|
|
164
|
+
this.#options.config.heartbeat_interval,
|
|
165
|
+
this.#heartbeatTimer,
|
|
166
|
+
);
|
|
167
|
+
socket.on('message', (data) => {
|
|
168
|
+
handleOneBot11WsMessage(data, {
|
|
169
|
+
endpointName: this.#options.config.name,
|
|
170
|
+
pending: this.#pending,
|
|
171
|
+
admit: (ev) => this.admit(ev),
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
socket.on('close', () => {
|
|
175
|
+
if (this.#ws === socket) {
|
|
176
|
+
this.#ws = undefined;
|
|
177
|
+
if (this.#heartbeatTimer) {
|
|
178
|
+
clearInterval(this.#heartbeatTimer);
|
|
179
|
+
this.#heartbeatTimer = undefined;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
logger.debug(formatCompact({
|
|
184
|
+
endpoint: this.#options.config.name,
|
|
185
|
+
mode: 'wss',
|
|
186
|
+
peer: connection.request.socket.remoteAddress,
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
}
|
package/lib/adapter.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OneBot11 适配器:单一适配器支持正向 WS / 反向 WS,由 config.connection 区分
|
|
3
|
-
*/
|
|
4
|
-
import { Adapter, Plugin } from 'zhin.js';
|
|
5
|
-
import { OneBot11WsClient } from './endpoint-ws-client.js';
|
|
6
|
-
import { OneBot11WsServer } from './endpoint-ws-server.js';
|
|
7
|
-
import type { OneBot11EndpointConfig } from './types.js';
|
|
8
|
-
export type OneBot11Bot = OneBot11WsClient | OneBot11WsServer;
|
|
9
|
-
export declare class OneBot11Adapter extends Adapter<OneBot11Bot> {
|
|
10
|
-
#private;
|
|
11
|
-
static readonly capabilities: readonly ["inbound", "outbound"];
|
|
12
|
-
static outboundRichSegmentPolicy: import("zhin.js").OutboundRichSegmentPolicy;
|
|
13
|
-
static interactivePolicy: "text";
|
|
14
|
-
static aiOutboundCapabilities: {
|
|
15
|
-
mentions: boolean;
|
|
16
|
-
richSegments: string[];
|
|
17
|
-
interactive: "text";
|
|
18
|
-
};
|
|
19
|
-
static aiOutboundExtensions: import("zhin.js").AiOutboundExtensionDefinition[];
|
|
20
|
-
constructor(plugin: Plugin);
|
|
21
|
-
createEndpoint(config: OneBot11EndpointConfig): OneBot11Bot;
|
|
22
|
-
removeMember(endpointId: string, sceneId: string, userId: string): Promise<boolean>;
|
|
23
|
-
muteMember(endpointId: string, sceneId: string, userId: string, duration?: number): Promise<boolean>;
|
|
24
|
-
setSceneMuted(endpointId: string, sceneId: string, enable?: boolean): Promise<boolean>;
|
|
25
|
-
setModerator(endpointId: string, sceneId: string, userId: string, enable?: boolean): Promise<boolean>;
|
|
26
|
-
setMemberNickname(endpointId: string, sceneId: string, userId: string, nickname: string): Promise<boolean>;
|
|
27
|
-
renameScene(endpointId: string, sceneId: string, name: string): Promise<boolean>;
|
|
28
|
-
listMembers(endpointId: string, sceneId: string): Promise<{
|
|
29
|
-
members: {
|
|
30
|
-
user_id: any;
|
|
31
|
-
nickname: any;
|
|
32
|
-
card: any;
|
|
33
|
-
role: any;
|
|
34
|
-
title: any;
|
|
35
|
-
}[];
|
|
36
|
-
count: number;
|
|
37
|
-
}>;
|
|
38
|
-
getSceneInfo(endpointId: string, sceneId: string): Promise<any>;
|
|
39
|
-
start(): Promise<void>;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=adapter.d.ts.map
|
package/lib/adapter.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAiB,OAAO,EAAE,MAAM,EAA+E,MAAM,SAAS,CAAC;AAEtI,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAGV,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAE9D,qBAAa,eAAgB,SAAQ,OAAO,CAAC,WAAW,CAAC;;IACvD,gBAAyB,YAAY,mCAAoC;IACzE,OAAgB,yBAAyB,8CAAwC;IACjF,OAAgB,iBAAiB,EAAG,MAAM,CAAU;IACpD,OAAgB,sBAAsB;;;;MAIpC;IACF,OAAgB,oBAAoB,oDAA2C;gBAInE,MAAM,EAAE,MAAM;IAI1B,cAAc,CAAC,MAAM,EAAE,sBAAsB,GAAG,WAAW;IAerD,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAMhE,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAM;IAM9E,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAO;IAMhE,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO;IAM/E,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAMvF,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAM7D,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;;;;;;;IAgB/C,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAMhD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
|
package/lib/adapter.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OneBot11 适配器:单一适配器支持正向 WS / 反向 WS,由 config.connection 区分
|
|
3
|
-
*/
|
|
4
|
-
import { Adapter, OUTBOUND_RICH_SEGMENT_POLICY_IM_FULL, ONEBOT_KEYBOARD_AI_OUTBOUND_EXTENSION } from 'zhin.js';
|
|
5
|
-
import { OneBot11WsClient } from './endpoint-ws-client.js';
|
|
6
|
-
import { OneBot11WsServer } from './endpoint-ws-server.js';
|
|
7
|
-
export class OneBot11Adapter extends Adapter {
|
|
8
|
-
static capabilities = ['inbound', 'outbound'];
|
|
9
|
-
static outboundRichSegmentPolicy = OUTBOUND_RICH_SEGMENT_POLICY_IM_FULL;
|
|
10
|
-
static interactivePolicy = 'text';
|
|
11
|
-
static aiOutboundCapabilities = {
|
|
12
|
-
mentions: true,
|
|
13
|
-
richSegments: ['qrcode', 'html', 'markdown', 'tts'],
|
|
14
|
-
interactive: 'text',
|
|
15
|
-
};
|
|
16
|
-
static aiOutboundExtensions = [ONEBOT_KEYBOARD_AI_OUTBOUND_EXTENSION];
|
|
17
|
-
#router;
|
|
18
|
-
constructor(plugin) {
|
|
19
|
-
super(plugin, 'onebot11', []);
|
|
20
|
-
}
|
|
21
|
-
createEndpoint(config) {
|
|
22
|
-
const connection = config.connection ?? 'ws';
|
|
23
|
-
switch (connection) {
|
|
24
|
-
case 'ws':
|
|
25
|
-
return new OneBot11WsClient(this, config);
|
|
26
|
-
case 'wss':
|
|
27
|
-
if (!this.#router) {
|
|
28
|
-
throw new Error('OneBot11 connection: wss 需要 router,请安装并在配置中启用 @zhin.js/host-router');
|
|
29
|
-
}
|
|
30
|
-
return new OneBot11WsServer(this, this.#router, config);
|
|
31
|
-
default:
|
|
32
|
-
throw new Error(`Unknown OneBot11 connection: ${connection}`);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
async removeMember(endpointId, sceneId, userId) {
|
|
36
|
-
const endpoint = this.endpoints.get(endpointId);
|
|
37
|
-
if (!endpoint)
|
|
38
|
-
throw new Error(`Endpoint ${endpointId} 不存在`);
|
|
39
|
-
return endpoint.kickMember(Number(sceneId), Number(userId), false);
|
|
40
|
-
}
|
|
41
|
-
async muteMember(endpointId, sceneId, userId, duration = 600) {
|
|
42
|
-
const endpoint = this.endpoints.get(endpointId);
|
|
43
|
-
if (!endpoint)
|
|
44
|
-
throw new Error(`Endpoint ${endpointId} 不存在`);
|
|
45
|
-
return endpoint.muteMember(Number(sceneId), Number(userId), duration);
|
|
46
|
-
}
|
|
47
|
-
async setSceneMuted(endpointId, sceneId, enable = true) {
|
|
48
|
-
const endpoint = this.endpoints.get(endpointId);
|
|
49
|
-
if (!endpoint)
|
|
50
|
-
throw new Error(`Endpoint ${endpointId} 不存在`);
|
|
51
|
-
return endpoint.muteAll(Number(sceneId), enable);
|
|
52
|
-
}
|
|
53
|
-
async setModerator(endpointId, sceneId, userId, enable = true) {
|
|
54
|
-
const endpoint = this.endpoints.get(endpointId);
|
|
55
|
-
if (!endpoint)
|
|
56
|
-
throw new Error(`Endpoint ${endpointId} 不存在`);
|
|
57
|
-
return endpoint.setAdmin(Number(sceneId), Number(userId), enable);
|
|
58
|
-
}
|
|
59
|
-
async setMemberNickname(endpointId, sceneId, userId, nickname) {
|
|
60
|
-
const endpoint = this.endpoints.get(endpointId);
|
|
61
|
-
if (!endpoint)
|
|
62
|
-
throw new Error(`Endpoint ${endpointId} 不存在`);
|
|
63
|
-
return endpoint.setCard(Number(sceneId), Number(userId), nickname);
|
|
64
|
-
}
|
|
65
|
-
async renameScene(endpointId, sceneId, name) {
|
|
66
|
-
const endpoint = this.endpoints.get(endpointId);
|
|
67
|
-
if (!endpoint)
|
|
68
|
-
throw new Error(`Endpoint ${endpointId} 不存在`);
|
|
69
|
-
return endpoint.setGroupName(Number(sceneId), name);
|
|
70
|
-
}
|
|
71
|
-
async listMembers(endpointId, sceneId) {
|
|
72
|
-
const endpoint = this.endpoints.get(endpointId);
|
|
73
|
-
if (!endpoint)
|
|
74
|
-
throw new Error(`Endpoint ${endpointId} 不存在`);
|
|
75
|
-
const members = await endpoint.getMemberList(Number(sceneId));
|
|
76
|
-
return {
|
|
77
|
-
members: members.map((m) => ({
|
|
78
|
-
user_id: m.user_id,
|
|
79
|
-
nickname: m.nickname,
|
|
80
|
-
card: m.card,
|
|
81
|
-
role: m.role,
|
|
82
|
-
title: m.title,
|
|
83
|
-
})),
|
|
84
|
-
count: members.length,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
async getSceneInfo(endpointId, sceneId) {
|
|
88
|
-
const endpoint = this.endpoints.get(endpointId);
|
|
89
|
-
if (!endpoint)
|
|
90
|
-
throw new Error(`Endpoint ${endpointId} 不存在`);
|
|
91
|
-
return endpoint.getGroupInfo(Number(sceneId));
|
|
92
|
-
}
|
|
93
|
-
async start() {
|
|
94
|
-
this.#router = this.plugin.inject('router');
|
|
95
|
-
this.plugin.useContext('router', (router) => {
|
|
96
|
-
this.#router = router;
|
|
97
|
-
});
|
|
98
|
-
await super.start();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
//# sourceMappingURL=adapter.js.map
|
package/lib/adapter.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from 'events';
|
|
2
|
-
import { Endpoint, Message, SendOptions, type QuotedMessagePayload } from 'zhin.js';
|
|
3
|
-
import type { OneBot11WsClientConfig, OneBot11Message } from './types.js';
|
|
4
|
-
import type { OneBot11Adapter } from './adapter.js';
|
|
5
|
-
export declare class OneBot11WsClient extends EventEmitter implements Endpoint<OneBot11WsClientConfig, OneBot11Message> {
|
|
6
|
-
adapter: OneBot11Adapter;
|
|
7
|
-
$config: OneBot11WsClientConfig;
|
|
8
|
-
$connected: boolean;
|
|
9
|
-
private ws?;
|
|
10
|
-
private reconnectTimer?;
|
|
11
|
-
private heartbeatTimer?;
|
|
12
|
-
private requestId;
|
|
13
|
-
private pendingRequests;
|
|
14
|
-
get logger(): import("zhin.js").Logger;
|
|
15
|
-
constructor(adapter: OneBot11Adapter, $config: OneBot11WsClientConfig);
|
|
16
|
-
get $id(): string;
|
|
17
|
-
$connect(): Promise<void>;
|
|
18
|
-
$disconnect(): Promise<void>;
|
|
19
|
-
private toWireSendContent;
|
|
20
|
-
$formatMessage(onebotMsg: OneBot11Message): Message<OneBot11Message>;
|
|
21
|
-
$sendMessage(options: SendOptions): Promise<string>;
|
|
22
|
-
$recallMessage(id: string): Promise<void>;
|
|
23
|
-
$getMsg(messageId: string): Promise<QuotedMessagePayload>;
|
|
24
|
-
kickMember(groupId: number, userId: number, rejectAddRequest?: boolean): Promise<boolean>;
|
|
25
|
-
muteMember(groupId: number, userId: number, duration?: number): Promise<boolean>;
|
|
26
|
-
muteAll(groupId: number, enable?: boolean): Promise<boolean>;
|
|
27
|
-
setAdmin(groupId: number, userId: number, enable?: boolean): Promise<boolean>;
|
|
28
|
-
setCard(groupId: number, userId: number, card: string): Promise<boolean>;
|
|
29
|
-
setTitle(groupId: number, userId: number, title: string, duration?: number): Promise<boolean>;
|
|
30
|
-
setGroupName(groupId: number, name: string): Promise<boolean>;
|
|
31
|
-
getMemberList(groupId: number): Promise<any[]>;
|
|
32
|
-
getGroupInfo(groupId: number): Promise<any>;
|
|
33
|
-
private callApi;
|
|
34
|
-
private handleWebSocketMessage;
|
|
35
|
-
private handleOneBot11Notice;
|
|
36
|
-
private handleOneBot11Request;
|
|
37
|
-
private handleOneBot11Message;
|
|
38
|
-
private startHeartbeat;
|
|
39
|
-
private scheduleReconnect;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=endpoint-ws-client.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"endpoint-ws-client.d.ts","sourceRoot":"","sources":["../src/endpoint-ws-client.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAiB,QAAQ,EAAE,OAAO,EAAyC,WAAW,EAAsC,KAAK,oBAAoB,EAAyD,MAAM,SAAS,CAAC;AAGrO,OAAO,KAAK,EACV,sBAAsB,EACtB,eAAe,EAEhB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD,qBAAa,gBAAiB,SAAQ,YAAa,YAAW,QAAQ,CAAC,sBAAsB,EAAE,eAAe,CAAC;IAe1F,OAAO,EAAE,eAAe;IAAS,OAAO,EAAE,sBAAsB;IAdnF,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,CAAY;IACvB,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,eAAe,CAIlB;IACL,IAAI,MAAM,6BAET;gBAEkB,OAAO,EAAE,eAAe,EAAS,OAAO,EAAE,sBAAsB;IAKnF,IAAI,GAAG,WAEN;IAEK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAyDzB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBlC,OAAO,CAAC,iBAAiB;IAOzB,cAAc,CAAC,SAAS,EAAE,eAAe;IA2CnC,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAsBnD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAMzD,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAE,OAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAehG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAerF,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,OAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAWlE,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,OAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAWnF,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWxE,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBjG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW7D,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAS9C,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;YASnC,OAAO;IAgBrB,OAAO,CAAC,sBAAsB;IAkB9B,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,qBAAqB;IAmC7B,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,iBAAiB;CAa1B"}
|