claw_messenger 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +577 -0
  3. package/bin/auto-init.js +104 -0
  4. package/bin/cli.js +5 -0
  5. package/bin/diagnose-plugin.js +174 -0
  6. package/bin/dm-bridge.cjs +12 -0
  7. package/bin/install.js +452 -0
  8. package/bin/postinstall.js +23 -0
  9. package/bin/qr-crypto-node.js +186 -0
  10. package/bin/setup.js +262 -0
  11. package/dist/auto-register.d.ts +49 -0
  12. package/dist/auto-register.js +328 -0
  13. package/dist/bridge-runner.d.ts +1 -0
  14. package/dist/bridge-runner.js +107 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.js +164 -0
  17. package/dist/device-status.d.ts +30 -0
  18. package/dist/device-status.js +109 -0
  19. package/dist/env-polyfill.d.ts +3 -0
  20. package/dist/env-polyfill.js +166 -0
  21. package/dist/group-config-manager.d.ts +22 -0
  22. package/dist/group-config-manager.js +130 -0
  23. package/dist/index.d.ts +17 -0
  24. package/dist/index.js +36 -0
  25. package/dist/logger.d.ts +14 -0
  26. package/dist/logger.js +103 -0
  27. package/dist/mac-address.d.ts +1 -0
  28. package/dist/mac-address.js +46 -0
  29. package/dist/openclaw-client.d.ts +41 -0
  30. package/dist/openclaw-client.js +530 -0
  31. package/dist/openclaw-config.d.ts +41 -0
  32. package/dist/openclaw-config.js +359 -0
  33. package/dist/openclaw.plugin.json +40 -0
  34. package/dist/package.json +112 -0
  35. package/dist/plugin-entry.d.ts +54 -0
  36. package/dist/plugin-entry.js +772 -0
  37. package/dist/postinstall.js +23 -0
  38. package/dist/rongcloud-client.d.ts +16 -0
  39. package/dist/rongcloud-client.js +274 -0
  40. package/dist/rongcloud-server-api.d.ts +53 -0
  41. package/dist/rongcloud-server-api.js +221 -0
  42. package/dist/utils.d.ts +9 -0
  43. package/dist/utils.js +97 -0
  44. package/openclaw.plugin.json +40 -0
  45. package/package.json +112 -0
@@ -0,0 +1,359 @@
1
+ /**
2
+ * OpenClaw 配置管理
3
+ * 自动配置 plugins.allow / plugins.entries / channels 等,只添加不重置
4
+ */
5
+ import { homedir } from 'os';
6
+ import { join, dirname } from 'path';
7
+ import { access, readFile, writeFile, mkdir, rename } from 'fs/promises';
8
+ import { createLogger } from './logger.js';
9
+ const log = createLogger('openclaw-config');
10
+ const OPENCLAW_DIR = join(homedir(), '.openclaw');
11
+ const SETTINGS_FILE = join(OPENCLAW_DIR, 'openclaw.json');
12
+ const DEFAULT_PLUGINS = [
13
+ 'claw_messenger',
14
+ ];
15
+ const REMOVED_PLUGINS = [
16
+ 'openclaw-weixin',
17
+ 'openclaw-wechat',
18
+ ];
19
+ /**
20
+ * 安全读取配置文件
21
+ * - 文件不存在:返回 null(调用方决定是创建新文件还是跳过)
22
+ * - 文件存在但解析失败:抛错,避免后续覆盖导致配置丢失
23
+ */
24
+ async function safeReadSettings(file) {
25
+ try {
26
+ await access(file);
27
+ }
28
+ catch (_a) {
29
+ return null;
30
+ }
31
+ const content = await readFile(file, 'utf-8');
32
+ try {
33
+ return JSON.parse(content);
34
+ }
35
+ catch (err) {
36
+ throw new Error(`配置文件 ${file} 解析失败: ${err.message}。请检查 JSON 语法,修复后再试。`);
37
+ }
38
+ }
39
+ /**
40
+ * 安全写入配置文件
41
+ * - 先写入临时文件
42
+ * - 再原子重命名为目标文件,避免写入中断导致文件损坏
43
+ */
44
+ async function safeWriteSettings(file, settings) {
45
+ await mkdir(dirname(file), { recursive: true });
46
+ const tmpFile = `${file}.tmp.${Date.now()}`;
47
+ await writeFile(tmpFile, JSON.stringify(settings, null, 2), 'utf-8');
48
+ await rename(tmpFile, file);
49
+ }
50
+ export async function getOpenClawSettings(settingsPath) {
51
+ const file = settingsPath || SETTINGS_FILE;
52
+ try {
53
+ return await safeReadSettings(file);
54
+ }
55
+ catch (_a) {
56
+ return null;
57
+ }
58
+ }
59
+ export async function getPluginsAllow() {
60
+ var _a;
61
+ const settings = await getOpenClawSettings();
62
+ return ((_a = settings === null || settings === void 0 ? void 0 : settings.plugins) === null || _a === void 0 ? void 0 : _a.allow) || [];
63
+ }
64
+ export async function ensurePluginsAllow(settingsPath) {
65
+ const file = settingsPath || SETTINGS_FILE;
66
+ let settings;
67
+ try {
68
+ settings = (await safeReadSettings(file)) || {};
69
+ if (settings) {
70
+ log.info('[OpenClawConfig] 已加载配置文件');
71
+ }
72
+ else {
73
+ log.info('[OpenClawConfig] 配置文件不存在,创建新配置');
74
+ settings = {};
75
+ }
76
+ }
77
+ catch (err) {
78
+ log.error('[OpenClawConfig]', err.message);
79
+ return false;
80
+ }
81
+ if (!settings.plugins) {
82
+ settings.plugins = {};
83
+ }
84
+ const existingAllow = settings.plugins.allow || [];
85
+ const cleanedAllow = existingAllow.filter(p => !REMOVED_PLUGINS.includes(p));
86
+ const removedCount = existingAllow.length - cleanedAllow.length;
87
+ const missingPlugins = DEFAULT_PLUGINS.filter(p => !cleanedAllow.includes(p));
88
+ if (missingPlugins.length === 0 && removedCount === 0) {
89
+ log.info('[OpenClawConfig] plugins.allow 已配置完整');
90
+ return true;
91
+ }
92
+ settings.plugins.allow = [...new Set([...cleanedAllow, ...DEFAULT_PLUGINS])];
93
+ try {
94
+ await safeWriteSettings(file, settings);
95
+ if (missingPlugins.length > 0) {
96
+ log.info(`[OpenClawConfig] 已添加插件到 plugins.allow: ${missingPlugins.join(', ')}`);
97
+ }
98
+ if (removedCount > 0) {
99
+ log.info(`[OpenClawConfig] 已清理无效插件: ${REMOVED_PLUGINS.join(', ')}`);
100
+ }
101
+ return true;
102
+ }
103
+ catch (err) {
104
+ log.error('[OpenClawConfig] 写入配置失败:', err.message);
105
+ return false;
106
+ }
107
+ }
108
+ /**
109
+ * 确保插件在 plugins.entries 中注册
110
+ * OpenClaw 只有在 entries 中配置了才会加载插件
111
+ */
112
+ export async function ensurePluginEntry(settingsPath) {
113
+ const file = settingsPath || SETTINGS_FILE;
114
+ let settings;
115
+ try {
116
+ settings = (await safeReadSettings(file)) || {};
117
+ if (settings) {
118
+ log.info('[OpenClawConfig] 已加载配置文件');
119
+ }
120
+ else {
121
+ log.info('[OpenClawConfig] 配置文件不存在,创建新配置');
122
+ settings = {};
123
+ }
124
+ }
125
+ catch (err) {
126
+ log.error('[OpenClawConfig]', err.message);
127
+ return false;
128
+ }
129
+ if (!settings.plugins) {
130
+ settings.plugins = {};
131
+ }
132
+ // 确保 plugins.allow 包含 claw_messenger
133
+ const existingAllow = settings.plugins.allow || [];
134
+ if (!existingAllow.includes('claw_messenger')) {
135
+ settings.plugins.allow = [...existingAllow, 'claw_messenger'];
136
+ log.info('[OpenClawConfig] 已添加 claw_messenger 到 plugins.allow');
137
+ }
138
+ // 确保 plugins.entries 包含 claw_messenger
139
+ if (!settings.plugins.entries) {
140
+ settings.plugins.entries = {};
141
+ }
142
+ const existingEntry = settings.plugins.entries['claw_messenger'];
143
+ if (!existingEntry || existingEntry.enabled !== true) {
144
+ settings.plugins.entries['claw_messenger'] = {
145
+ enabled: true
146
+ };
147
+ log.info('[OpenClawConfig] 已启用 claw_messenger 插件 entries');
148
+ }
149
+ // 确保 plugins.load.paths 包含扩展目录(辅助发现,非必须)
150
+ const extensionsDir = join(OPENCLAW_DIR, 'extensions', 'claw_messenger');
151
+ if (!settings.plugins.load) {
152
+ settings.plugins.load = {};
153
+ }
154
+ if (!settings.plugins.load.paths) {
155
+ settings.plugins.load.paths = [];
156
+ }
157
+ if (!settings.plugins.load.paths.includes(extensionsDir)) {
158
+ settings.plugins.load.paths.push(extensionsDir);
159
+ log.info(`[OpenClawConfig] 已添加插件加载路径: ${extensionsDir}`);
160
+ }
161
+ try {
162
+ await safeWriteSettings(file, settings);
163
+ log.info('[OpenClawConfig] 已注册 claw_messenger 插件到 plugins.entries');
164
+ return true;
165
+ }
166
+ catch (err) {
167
+ log.error('[OpenClawConfig] 注册插件 entries 失败:', err.message);
168
+ return false;
169
+ }
170
+ }
171
+ /**
172
+ * 确保 channels.claw_messenger 配置包含 nodeName
173
+ * OpenClaw 的 hasMeaningfulChannelConfig 会忽略 enabled,
174
+ * 只有包含非 enabled 属性时才认为 channel 已配置,从而加载插件。
175
+ */
176
+ export async function ensureChannelConfig(nodeName, settingsPath) {
177
+ const file = settingsPath || SETTINGS_FILE;
178
+ let settings;
179
+ try {
180
+ settings = (await safeReadSettings(file)) || {};
181
+ if (!settings) {
182
+ log.info('[OpenClawConfig] 配置文件不存在,创建新配置');
183
+ settings = {};
184
+ }
185
+ }
186
+ catch (err) {
187
+ log.error('[OpenClawConfig]', err.message);
188
+ return false;
189
+ }
190
+ if (!settings.channels) {
191
+ settings.channels = {};
192
+ }
193
+ const existingChannelConfig = settings.channels['claw_messenger'] || {};
194
+ const existingNodeName = existingChannelConfig.nodeName;
195
+ if (existingNodeName && typeof existingNodeName === 'string' && existingNodeName.trim()) {
196
+ log.info('[OpenClawConfig] channels.claw_messenger 已包含 nodeName');
197
+ return true;
198
+ }
199
+ // 尝试从节点配置文件读取昵称
200
+ let finalNodeName = nodeName;
201
+ if (!finalNodeName) {
202
+ try {
203
+ const bridgeConfigPath = join(homedir(), '.claw-bridge', 'openclaw', 'config.json');
204
+ const bridgeContent = await readFile(bridgeConfigPath, 'utf-8');
205
+ const bridgeConfig = JSON.parse(bridgeContent);
206
+ finalNodeName = bridgeConfig.nodeName;
207
+ }
208
+ catch (_a) {
209
+ // 忽略读取失败
210
+ }
211
+ }
212
+ if (!finalNodeName || typeof finalNodeName !== 'string' || !finalNodeName.trim()) {
213
+ log.warn('[OpenClawConfig] 未找到节点昵称,跳过 channels.claw_messenger 配置');
214
+ return false;
215
+ }
216
+ settings.channels['claw_messenger'] = Object.assign(Object.assign({}, existingChannelConfig), { nodeName: finalNodeName.trim() });
217
+ try {
218
+ await safeWriteSettings(file, settings);
219
+ log.info(`[OpenClawConfig] 已设置 channels.claw_messenger.nodeName: ${finalNodeName.trim()}`);
220
+ return true;
221
+ }
222
+ catch (err) {
223
+ log.error('[OpenClawConfig] 写入 channel 配置失败:', err.message);
224
+ return false;
225
+ }
226
+ }
227
+ /**
228
+ * 确保 gateway HTTP chatCompletions 端点已启用
229
+ * 供 SSE 流式调用使用(OpenClaw 默认禁用该端点)
230
+ */
231
+ export async function ensureChatCompletionsEnabled(settingsPath) {
232
+ var _a, _b, _c, _d;
233
+ const file = settingsPath || SETTINGS_FILE;
234
+ let settings;
235
+ try {
236
+ settings = (await safeReadSettings(file)) || {};
237
+ if (settings) {
238
+ log.info('[OpenClawConfig] 已加载配置文件');
239
+ }
240
+ else {
241
+ log.info('[OpenClawConfig] 配置文件不存在,创建新配置');
242
+ settings = {};
243
+ }
244
+ }
245
+ catch (err) {
246
+ log.error('[OpenClawConfig]', err.message);
247
+ return false;
248
+ }
249
+ const current = (_d = (_c = (_b = (_a = settings.gateway) === null || _a === void 0 ? void 0 : _a.http) === null || _b === void 0 ? void 0 : _b.endpoints) === null || _c === void 0 ? void 0 : _c.chatCompletions) === null || _d === void 0 ? void 0 : _d.enabled;
250
+ if (current === true) {
251
+ log.info('[OpenClawConfig] chatCompletions 端点已启用');
252
+ return true;
253
+ }
254
+ // 深度设置路径 gateway.http.endpoints.chatCompletions.enabled
255
+ if (!settings.gateway) {
256
+ settings.gateway = {};
257
+ }
258
+ if (!settings.gateway.http) {
259
+ settings.gateway.http = {};
260
+ }
261
+ if (!settings.gateway.http.endpoints) {
262
+ settings.gateway.http.endpoints = {};
263
+ }
264
+ if (!settings.gateway.http.endpoints.chatCompletions) {
265
+ settings.gateway.http.endpoints.chatCompletions = {};
266
+ }
267
+ settings.gateway.http.endpoints.chatCompletions.enabled = true;
268
+ try {
269
+ await safeWriteSettings(file, settings);
270
+ log.info('[OpenClawConfig] 已启用 chatCompletions 端点');
271
+ return true;
272
+ }
273
+ catch (err) {
274
+ log.error('[OpenClawConfig] 启用 chatCompletions 端点失败:', err.message);
275
+ return false;
276
+ }
277
+ }
278
+ /**
279
+ * 确保网关模型支持 image 类型
280
+ * OpenClaw 默认模型 type 只有 "text",插件需要 "image" 支持
281
+ * 遍历 gateway.http.endpoints.chatCompletions.models 中的每个模型,
282
+ * 如果 type 是字符串 "text" 则改为 ["text", "image"],
283
+ * 如果 type 是数组则追加 "image"
284
+ */
285
+ export async function ensureImageModelSupport(settingsPath) {
286
+ var _a, _b, _c, _d;
287
+ const file = settingsPath || SETTINGS_FILE;
288
+ let settings;
289
+ try {
290
+ settings = (await safeReadSettings(file)) || {};
291
+ if (!settings) {
292
+ log.info('[OpenClawConfig] 配置文件不存在,跳过模型 image 类型配置');
293
+ return true;
294
+ }
295
+ }
296
+ catch (err) {
297
+ log.error('[OpenClawConfig]', err.message);
298
+ return false;
299
+ }
300
+ const models = (_d = (_c = (_b = (_a = settings === null || settings === void 0 ? void 0 : settings.gateway) === null || _a === void 0 ? void 0 : _a.http) === null || _b === void 0 ? void 0 : _b.endpoints) === null || _c === void 0 ? void 0 : _c.chatCompletions) === null || _d === void 0 ? void 0 : _d.models;
301
+ if (!models) {
302
+ log.info('[OpenClawConfig] 未找到 models 配置,跳过');
303
+ return true;
304
+ }
305
+ let modified = false;
306
+ // 确保 type 包含 image
307
+ const ensureImageType = (type) => {
308
+ if (typeof type === 'string') {
309
+ return type === 'text' ? ['text', 'image'] : [type, 'image'];
310
+ }
311
+ if (Array.isArray(type)) {
312
+ if (!type.includes('image')) {
313
+ return [...type, 'image'];
314
+ }
315
+ return type;
316
+ }
317
+ return ['text', 'image'];
318
+ };
319
+ // 处理 models 数组格式: [{ id: "...", type: "text" }, ...]
320
+ if (Array.isArray(models)) {
321
+ for (const model of models) {
322
+ if (model && typeof model === 'object') {
323
+ const newType = ensureImageType(model.type);
324
+ if (JSON.stringify(newType) !== JSON.stringify(model.type)) {
325
+ model.type = newType;
326
+ modified = true;
327
+ log.info(`[OpenClawConfig] 模型 "${model.id || model.model || '(unknown)'}" type 已更新为`, newType);
328
+ }
329
+ }
330
+ }
331
+ }
332
+ // 处理 models 对象格式: { "claude": { type: "text" }, ... }
333
+ else if (typeof models === 'object' && models !== null) {
334
+ for (const key of Object.keys(models)) {
335
+ const model = models[key];
336
+ if (model && typeof model === 'object') {
337
+ const newType = ensureImageType(model.type);
338
+ if (JSON.stringify(newType) !== JSON.stringify(model.type)) {
339
+ model.type = newType;
340
+ modified = true;
341
+ log.info(`[OpenClawConfig] 模型 "${key}" type 已更新为`, newType);
342
+ }
343
+ }
344
+ }
345
+ }
346
+ if (!modified) {
347
+ log.info('[OpenClawConfig] 模型 image 类型已配置');
348
+ return true;
349
+ }
350
+ try {
351
+ await safeWriteSettings(file, settings);
352
+ log.info('[OpenClawConfig] 已为模型添加 image 类型支持');
353
+ return true;
354
+ }
355
+ catch (err) {
356
+ log.error('[OpenClawConfig] 更新模型 image 类型失败:', err.message);
357
+ return false;
358
+ }
359
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "id": "claw_messenger",
3
+ "name": "claw_messenger",
4
+ "description": "虾说 IM 直连通道插件,支持私聊、群聊、流式消息",
5
+ "version": "2.1.2",
6
+ "author": "",
7
+ "license": "MIT",
8
+ "repository": "https://github.com/quukk/clawmessenger",
9
+ "keywords": ["claw-messenger", "im", "chat", "channel"],
10
+ "entry": "./dist/plugin-entry.js",
11
+ "channels": ["claw_messenger"],
12
+ "channelConfigs": {
13
+ "claw_messenger": {
14
+ "schema": {
15
+ "type": "object",
16
+ "additionalProperties": true,
17
+ "properties": {
18
+ "nodeName": {
19
+ "type": "string",
20
+ "label": "节点昵称",
21
+ "description": "在虾说 IM 中显示的节点名称"
22
+ }
23
+ }
24
+ },
25
+ "label": "虾说 IM",
26
+ "description": "通过融云 IM 连接虾说消息系统",
27
+ "preferOver": []
28
+ }
29
+ },
30
+ "configSchema": {
31
+ "type": "object",
32
+ "additionalProperties": true,
33
+ "properties": {
34
+ "nodeName": {
35
+ "type": "string",
36
+ "label": "节点昵称"
37
+ }
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,112 @@
1
+ {
2
+ "name": "claw_messenger",
3
+ "version": "1.0.0",
4
+ "description": "OpenClaw 插件 - 虾说应用桥接",
5
+ "type": "module",
6
+ "main": "dist/plugin-entry.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "claw_messenger": "bin/install.js",
10
+ "claw-messenger": "bin/install.js",
11
+ "claw-messenger-bridge": "bin/install.js",
12
+ "claw-bridge": "dist/bridge-runner.js",
13
+ "claw-bridge-setup": "bin/setup.js",
14
+ "clawmessenger": "bin/cli.js"
15
+ },
16
+ "files": [
17
+ "bin",
18
+ "dist",
19
+ "package.json",
20
+ "openclaw.plugin.json",
21
+ "README.md"
22
+ ],
23
+ "openclaw": {
24
+ "extensions": [
25
+ "./dist/plugin-entry.js"
26
+ ],
27
+ "channel": {
28
+ "id": "claw_messenger",
29
+ "label": "claw_messenger",
30
+ "selectionLabel": "虾说 IM",
31
+ "docsPath": "/channels/claw_messenger",
32
+ "blurb": "claw_messenger IM channel for OpenClaw",
33
+ "order": 80
34
+ },
35
+ "compat": {
36
+ "pluginApi": ">=2.0.0"
37
+ },
38
+ "install": {
39
+ "npmSpec": "claw_messenger",
40
+ "defaultChoice": "npx",
41
+ "minHostVersion": ">=2026.3.24"
42
+ }
43
+ },
44
+ "scripts": {
45
+ "build": "node ./node_modules/typescript/bin/tsc && copy /Y package.json dist\\ && copy /Y openclaw.plugin.json dist\\ && copy /Y bin\\postinstall.js dist\\postinstall.js",
46
+ "setup": "npm run build && node bin/install.js",
47
+ "install-local": "node bin/install.js",
48
+ "start": "node bin/dm-bridge.cjs",
49
+ "bridge": "ts-node bridge-runner.ts",
50
+ "test": "vitest run",
51
+ "test:watch": "vitest",
52
+ "test:coverage": "vitest run --coverage",
53
+ "prepublishOnly": "npm run build",
54
+ "postinstall": "node dist/postinstall.js",
55
+ "publish:patch": "npm version patch && npm publish",
56
+ "publish:minor": "npm version minor && npm publish",
57
+ "publish:major": "npm version major && npm publish",
58
+ "unpublish:last": "node scripts/unpublish.js",
59
+ "unpublish:version": "node scripts/unpublish.js",
60
+ "deprecate:last": "npm deprecate $(node -p \"require('./package.json').name\")@$(node -p \"require('./package.json').version\") \"This version is deprecated. Please upgrade.\"",
61
+ "deprecate:version": "npm deprecate"
62
+ },
63
+ "keywords": [
64
+ "openclaw",
65
+ "claw-messenger",
66
+ "im",
67
+ "chat",
68
+ "bridge",
69
+ "ai"
70
+ ],
71
+ "author": "",
72
+ "license": "MIT",
73
+ "repository": {
74
+ "type": "git",
75
+ "url": "git+https://github.com/quukk/clawmessenger.git"
76
+ },
77
+ "bugs": {
78
+ "url": "https://github.com/quukk/clawmessenger/issues"
79
+ },
80
+ "homepage": "https://github.com/quukk/clawmessenger#readme",
81
+ "dependencies": {
82
+ "@rongcloud/engine": "^5.36.6",
83
+ "@rongcloud/imlib-next": "^5.36.6",
84
+ "axios": "^1.15.0",
85
+ "fake-indexeddb": "^6.2.5",
86
+ "jsdom": "^24.0.0",
87
+ "qrcode-terminal": "^0.12.0",
88
+ "ws": "^8.16.0"
89
+ },
90
+ "peerDependencies": {
91
+ "openclaw": ">=2026.3.24"
92
+ },
93
+ "peerDependenciesMeta": {
94
+ "openclaw": {
95
+ "optional": true
96
+ }
97
+ },
98
+ "devDependencies": {
99
+ "@types/jsdom": "^21.1.6",
100
+ "@types/node": "^20.11.0",
101
+ "@types/qrcode-terminal": "^0.12.2",
102
+ "@types/ws": "^8.5.10",
103
+ "@vitest/coverage-v8": "^1.6.1",
104
+ "ts-node": "^10.9.2",
105
+ "tsx": "^4.7.0",
106
+ "typescript": "^5.3.3",
107
+ "vitest": "^1.6.1"
108
+ },
109
+ "engines": {
110
+ "node": ">=16.0.0"
111
+ }
112
+ }
@@ -0,0 +1,54 @@
1
+ interface ChannelGatewayContext {
2
+ cfg: any;
3
+ accountId: string;
4
+ account: any;
5
+ runtime?: any;
6
+ channelRuntime?: any;
7
+ abortSignal: AbortSignal;
8
+ log?: {
9
+ info?: (msg: string) => void;
10
+ warn?: (msg: string) => void;
11
+ error?: (msg: string) => void;
12
+ debug?: (msg: string) => void;
13
+ };
14
+ getStatus: () => any;
15
+ setStatus: (next: any) => void;
16
+ }
17
+ declare class RongCloudChannelImpl {
18
+ private client;
19
+ private accountId;
20
+ private openclaw;
21
+ private serverAPI;
22
+ private appSecret;
23
+ private streamQueue;
24
+ private streamMessageUIDs;
25
+ /**
26
+ * 启动 channel account(OpenClaw 2026.4.21+ 新 API)
27
+ */
28
+ startAccount(ctx: ChannelGatewayContext): Promise<void>;
29
+ sendMessage(to: string, content: string, metadata?: any): Promise<void>;
30
+ sendMediaMessage(targetId: string, media: {
31
+ mediaUrl: string;
32
+ mimeType?: string;
33
+ fileName?: string;
34
+ fileSize?: number;
35
+ }, conversationType: number): Promise<void>;
36
+ private extractMentions;
37
+ handleMessage(msg: any, ctx: ChannelGatewayContext): Promise<void>;
38
+ private handleStreamChat;
39
+ private _handleDeviceStatusRequest;
40
+ private _sendDeviceStatusReport;
41
+ private _sendWebSearchStatus;
42
+ private _sendStreamChunk;
43
+ private _sendStreamHistory;
44
+ callOpenClaw(message: string, fromUser: string): Promise<string>;
45
+ }
46
+ declare const channelImpl: RongCloudChannelImpl;
47
+ export { RongCloudChannelImpl, channelImpl };
48
+ declare const _default: {
49
+ id: string;
50
+ name: string;
51
+ description: string;
52
+ register(api: any): void;
53
+ };
54
+ export default _default;