@wecom/wecom-openclaw-plugin 2026.3.20 → 2026.3.24-beta.1
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/README.md +19 -1
- package/dist/index.cjs.js +26 -186
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.esm.js +16 -177
- package/dist/index.esm.js.map +1 -1
- package/dist/src/channel.d.ts +1 -1
- package/dist/src/dm-policy.d.ts +1 -1
- package/dist/src/group-policy.d.ts +2 -1
- package/dist/src/interface.d.ts +2 -1
- package/dist/src/media-handler.d.ts +2 -1
- package/dist/src/message-sender.d.ts +1 -1
- package/dist/src/onboarding.d.ts +2 -2
- package/dist/src/reqid-store.d.ts +3 -11
- package/dist/src/runtime.d.ts +1 -1
- package/dist/src/state-manager.d.ts +4 -0
- package/dist/src/utils.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,7 +37,25 @@
|
|
|
37
37
|
|
|
38
38
|
- OpenClaw `>= 2026.2.13`
|
|
39
39
|
|
|
40
|
-
###
|
|
40
|
+
### Quick Install
|
|
41
|
+
|
|
42
|
+
Use the CLI tool to automatically install the plugin and complete bot configuration in one step:
|
|
43
|
+
|
|
44
|
+
```shell
|
|
45
|
+
# Automatically install the channel plugin and quickly complete configuration; also works for updates
|
|
46
|
+
npx -y @wecom/wecom-openclaw-cli install
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
More Options
|
|
50
|
+
```shell
|
|
51
|
+
# If installation fails, try force install
|
|
52
|
+
npx -y @wecom/wecom-openclaw-cli install --force
|
|
53
|
+
|
|
54
|
+
# Use --help to learn more about the tool
|
|
55
|
+
npx -y @wecom/wecom-openclaw-cli --help
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Manual Install
|
|
41
59
|
|
|
42
60
|
```shell
|
|
43
61
|
openclaw plugins install @wecom/wecom-openclaw-plugin
|
package/dist/index.cjs.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var core = require('openclaw/plugin-sdk/core');
|
|
6
6
|
var os$1 = require('os');
|
|
7
7
|
var path$1 = require('path');
|
|
8
8
|
var aibotNodeSdk = require('@wecom/aibot-node-sdk');
|
|
@@ -12,6 +12,7 @@ var os = require('node:os');
|
|
|
12
12
|
var node_url = require('node:url');
|
|
13
13
|
var fileType = require('file-type');
|
|
14
14
|
var node_fs = require('node:fs');
|
|
15
|
+
var setup = require('openclaw/plugin-sdk/setup');
|
|
15
16
|
|
|
16
17
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
17
18
|
function _interopNamespaceDefault(e) {
|
|
@@ -57,7 +58,7 @@ function getWeComRuntime() {
|
|
|
57
58
|
* 本模块在加载时一次性探测 SDK 导出,存在则直接 re-export SDK 版本,
|
|
58
59
|
* 不存在则导出 fallback 实现。其他模块统一从本文件导入,无需关心底层兼容细节。
|
|
59
60
|
*/
|
|
60
|
-
const _sdkReady = import('openclaw/plugin-sdk')
|
|
61
|
+
const _sdkReady = import('openclaw/plugin-sdk/core')
|
|
61
62
|
.then((sdk) => {
|
|
62
63
|
const exports$1 = {};
|
|
63
64
|
if (typeof sdk.loadOutboundMediaFromUrl === "function") {
|
|
@@ -1199,80 +1200,27 @@ async function checkDmPolicy(params) {
|
|
|
1199
1200
|
return { allowed: false };
|
|
1200
1201
|
}
|
|
1201
1202
|
|
|
1203
|
+
// ============================================================================
|
|
1204
|
+
// 类型定义
|
|
1205
|
+
// ============================================================================
|
|
1202
1206
|
// ============================================================================
|
|
1203
1207
|
// 常量
|
|
1204
1208
|
// ============================================================================
|
|
1205
1209
|
const DEFAULT_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 天
|
|
1206
1210
|
const DEFAULT_MEMORY_MAX_SIZE = 200;
|
|
1207
|
-
const DEFAULT_FILE_MAX_ENTRIES = 500;
|
|
1208
|
-
const DEFAULT_FLUSH_DEBOUNCE_MS = 1000;
|
|
1209
|
-
const DEFAULT_LOCK_OPTIONS = {
|
|
1210
|
-
stale: 60000,
|
|
1211
|
-
retries: {
|
|
1212
|
-
retries: 6,
|
|
1213
|
-
factor: 1.35,
|
|
1214
|
-
minTimeout: 8,
|
|
1215
|
-
maxTimeout: 180,
|
|
1216
|
-
randomize: true,
|
|
1217
|
-
},
|
|
1218
|
-
};
|
|
1219
|
-
// ============================================================================
|
|
1220
|
-
// 状态目录解析
|
|
1221
|
-
// ============================================================================
|
|
1222
|
-
function resolveStateDirFromEnv(env = process.env) {
|
|
1223
|
-
const stateOverride = env.OPENCLAW_STATE_DIR?.trim() || env.CLAWDBOT_STATE_DIR?.trim();
|
|
1224
|
-
if (stateOverride) {
|
|
1225
|
-
return stateOverride;
|
|
1226
|
-
}
|
|
1227
|
-
if (env.VITEST || env.NODE_ENV === "test") {
|
|
1228
|
-
return path.join(os.tmpdir(), ["openclaw-vitest", String(process.pid)].join("-"));
|
|
1229
|
-
}
|
|
1230
|
-
return path.join(os.homedir(), ".openclaw");
|
|
1231
|
-
}
|
|
1232
|
-
function resolveReqIdFilePath(accountId) {
|
|
1233
|
-
const safe = accountId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1234
|
-
return path.join(resolveStateDirFromEnv(), "wecom", `reqid-map-${safe}.json`);
|
|
1235
|
-
}
|
|
1236
1211
|
// ============================================================================
|
|
1237
1212
|
// 核心实现
|
|
1238
1213
|
// ============================================================================
|
|
1239
1214
|
function createPersistentReqIdStore(accountId, options) {
|
|
1240
1215
|
const ttlMs = DEFAULT_TTL_MS;
|
|
1241
1216
|
const memoryMaxSize = DEFAULT_MEMORY_MAX_SIZE;
|
|
1242
|
-
const fileMaxEntries = DEFAULT_FILE_MAX_ENTRIES;
|
|
1243
|
-
const flushDebounceMs = DEFAULT_FLUSH_DEBOUNCE_MS;
|
|
1244
|
-
const filePath = resolveReqIdFilePath(accountId);
|
|
1245
1217
|
// 内存层:chatId → ReqIdEntry
|
|
1246
1218
|
const memory = new Map();
|
|
1247
|
-
// 防抖写入相关
|
|
1248
|
-
let dirty = false;
|
|
1249
|
-
let flushTimer = null;
|
|
1250
1219
|
// ========== 内部辅助函数 ==========
|
|
1251
1220
|
/** 检查条目是否过期 */
|
|
1252
1221
|
function isExpired(entry, now) {
|
|
1253
1222
|
return now - entry.ts >= ttlMs;
|
|
1254
1223
|
}
|
|
1255
|
-
/** 验证磁盘条目的合法性 */
|
|
1256
|
-
function isValidEntry(entry) {
|
|
1257
|
-
return (typeof entry === "object" &&
|
|
1258
|
-
entry !== null &&
|
|
1259
|
-
typeof entry.reqId === "string" &&
|
|
1260
|
-
typeof entry.ts === "number" &&
|
|
1261
|
-
Number.isFinite(entry.ts));
|
|
1262
|
-
}
|
|
1263
|
-
/** 清理磁盘数据中的无效值,返回干净的 Record */
|
|
1264
|
-
function sanitizeData(value) {
|
|
1265
|
-
if (!value || typeof value !== "object") {
|
|
1266
|
-
return {};
|
|
1267
|
-
}
|
|
1268
|
-
const out = {};
|
|
1269
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
1270
|
-
if (isValidEntry(entry)) {
|
|
1271
|
-
out[key] = entry;
|
|
1272
|
-
}
|
|
1273
|
-
}
|
|
1274
|
-
return out;
|
|
1275
|
-
}
|
|
1276
1224
|
/**
|
|
1277
1225
|
* 内存容量控制:淘汰最旧的条目。
|
|
1278
1226
|
* 利用 Map 的插入顺序 + touch(先 delete 再 set) 实现类 LRU 效果。
|
|
@@ -1286,61 +1234,6 @@ function createPersistentReqIdStore(accountId, options) {
|
|
|
1286
1234
|
memory.delete(key);
|
|
1287
1235
|
}
|
|
1288
1236
|
}
|
|
1289
|
-
/** 磁盘数据容量控制:先清过期,再按时间淘汰超量 */
|
|
1290
|
-
function pruneFileData(data, now) {
|
|
1291
|
-
{
|
|
1292
|
-
for (const [key, entry] of Object.entries(data)) {
|
|
1293
|
-
if (now - entry.ts >= ttlMs) {
|
|
1294
|
-
delete data[key];
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
}
|
|
1298
|
-
const keys = Object.keys(data);
|
|
1299
|
-
if (keys.length <= fileMaxEntries)
|
|
1300
|
-
return;
|
|
1301
|
-
keys
|
|
1302
|
-
.sort((a, b) => data[a].ts - data[b].ts)
|
|
1303
|
-
.slice(0, keys.length - fileMaxEntries)
|
|
1304
|
-
.forEach((key) => delete data[key]);
|
|
1305
|
-
}
|
|
1306
|
-
/** 防抖写入磁盘 */
|
|
1307
|
-
function scheduleDiskFlush() {
|
|
1308
|
-
dirty = true;
|
|
1309
|
-
if (flushTimer)
|
|
1310
|
-
return;
|
|
1311
|
-
flushTimer = setTimeout(async () => {
|
|
1312
|
-
flushTimer = null;
|
|
1313
|
-
if (!dirty)
|
|
1314
|
-
return;
|
|
1315
|
-
await flushToDisk();
|
|
1316
|
-
}, flushDebounceMs);
|
|
1317
|
-
}
|
|
1318
|
-
/** 立即写入磁盘(带文件锁,参考 createPersistentDedupe 的 checkAndRecordInner) */
|
|
1319
|
-
async function flushToDisk() {
|
|
1320
|
-
dirty = false;
|
|
1321
|
-
const now = Date.now();
|
|
1322
|
-
try {
|
|
1323
|
-
await pluginSdk.withFileLock(filePath, DEFAULT_LOCK_OPTIONS, async () => {
|
|
1324
|
-
// 读取现有磁盘数据并合并
|
|
1325
|
-
const { value } = await pluginSdk.readJsonFileWithFallback(filePath, {});
|
|
1326
|
-
const data = sanitizeData(value);
|
|
1327
|
-
// 将内存中未过期的数据合并到磁盘数据(内存优先)
|
|
1328
|
-
for (const [chatId, entry] of memory) {
|
|
1329
|
-
if (!isExpired(entry, now)) {
|
|
1330
|
-
data[chatId] = entry;
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
// 清理过期和超量
|
|
1334
|
-
pruneFileData(data, now);
|
|
1335
|
-
// 原子写入
|
|
1336
|
-
await pluginSdk.writeJsonFileAtomically(filePath, data);
|
|
1337
|
-
});
|
|
1338
|
-
}
|
|
1339
|
-
catch (error) {
|
|
1340
|
-
// 磁盘写入失败不影响内存使用,降级到纯内存模式
|
|
1341
|
-
// console.error(`[WeCom] reqid-store: flush to disk failed: ${String(error)}`);
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
1237
|
// ========== 公开 API ==========
|
|
1345
1238
|
function set(chatId, reqId) {
|
|
1346
1239
|
const entry = { reqId, ts: Date.now() };
|
|
@@ -1348,11 +1241,10 @@ function createPersistentReqIdStore(accountId, options) {
|
|
|
1348
1241
|
memory.delete(chatId);
|
|
1349
1242
|
memory.set(chatId, entry);
|
|
1350
1243
|
pruneMemory();
|
|
1351
|
-
scheduleDiskFlush();
|
|
1352
1244
|
}
|
|
1353
1245
|
async function get(chatId) {
|
|
1354
1246
|
const now = Date.now();
|
|
1355
|
-
//
|
|
1247
|
+
// 仅查内存
|
|
1356
1248
|
const memEntry = memory.get(chatId);
|
|
1357
1249
|
if (memEntry && !isExpired(memEntry, now)) {
|
|
1358
1250
|
return memEntry.reqId;
|
|
@@ -1360,20 +1252,6 @@ function createPersistentReqIdStore(accountId, options) {
|
|
|
1360
1252
|
if (memEntry) {
|
|
1361
1253
|
memory.delete(chatId); // 过期则删除
|
|
1362
1254
|
}
|
|
1363
|
-
// 2. 内存 miss,回查磁盘并回填内存
|
|
1364
|
-
try {
|
|
1365
|
-
const { value } = await pluginSdk.readJsonFileWithFallback(filePath, {});
|
|
1366
|
-
const data = sanitizeData(value);
|
|
1367
|
-
const diskEntry = data[chatId];
|
|
1368
|
-
if (diskEntry && !isExpired(diskEntry, now)) {
|
|
1369
|
-
// 回填内存
|
|
1370
|
-
memory.set(chatId, diskEntry);
|
|
1371
|
-
return diskEntry.reqId;
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
catch {
|
|
1375
|
-
// 磁盘读取失败,降级返回 undefined
|
|
1376
|
-
}
|
|
1377
1255
|
return undefined;
|
|
1378
1256
|
}
|
|
1379
1257
|
function getSync(chatId) {
|
|
@@ -1389,34 +1267,6 @@ function createPersistentReqIdStore(accountId, options) {
|
|
|
1389
1267
|
}
|
|
1390
1268
|
function del(chatId) {
|
|
1391
1269
|
memory.delete(chatId);
|
|
1392
|
-
scheduleDiskFlush();
|
|
1393
|
-
}
|
|
1394
|
-
async function warmup(onError) {
|
|
1395
|
-
const now = Date.now();
|
|
1396
|
-
try {
|
|
1397
|
-
const { value } = await pluginSdk.readJsonFileWithFallback(filePath, {});
|
|
1398
|
-
const data = sanitizeData(value);
|
|
1399
|
-
let loaded = 0;
|
|
1400
|
-
for (const [chatId, entry] of Object.entries(data)) {
|
|
1401
|
-
if (!isExpired(entry, now)) {
|
|
1402
|
-
memory.set(chatId, entry);
|
|
1403
|
-
loaded++;
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
pruneMemory();
|
|
1407
|
-
return loaded;
|
|
1408
|
-
}
|
|
1409
|
-
catch (error) {
|
|
1410
|
-
onError?.(error);
|
|
1411
|
-
return 0;
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
async function flush() {
|
|
1415
|
-
if (flushTimer) {
|
|
1416
|
-
clearTimeout(flushTimer);
|
|
1417
|
-
flushTimer = null;
|
|
1418
|
-
}
|
|
1419
|
-
await flushToDisk();
|
|
1420
1270
|
}
|
|
1421
1271
|
function clearMemory() {
|
|
1422
1272
|
memory.clear();
|
|
@@ -1429,8 +1279,6 @@ function createPersistentReqIdStore(accountId, options) {
|
|
|
1429
1279
|
get,
|
|
1430
1280
|
getSync,
|
|
1431
1281
|
delete: del,
|
|
1432
|
-
warmup,
|
|
1433
|
-
flush,
|
|
1434
1282
|
clearMemory,
|
|
1435
1283
|
memorySize,
|
|
1436
1284
|
};
|
|
@@ -1533,7 +1381,7 @@ const reqIdStores = new Map();
|
|
|
1533
1381
|
function getOrCreateReqIdStore(accountId) {
|
|
1534
1382
|
let store = reqIdStores.get(accountId);
|
|
1535
1383
|
if (!store) {
|
|
1536
|
-
store = createPersistentReqIdStore(
|
|
1384
|
+
store = createPersistentReqIdStore();
|
|
1537
1385
|
reqIdStores.set(accountId, store);
|
|
1538
1386
|
}
|
|
1539
1387
|
return store;
|
|
@@ -1549,12 +1397,13 @@ function setReqIdForChat(chatId, reqId, accountId = "default") {
|
|
|
1549
1397
|
}
|
|
1550
1398
|
/**
|
|
1551
1399
|
* 启动时预热 reqId 缓存(从磁盘加载到内存)
|
|
1400
|
+
*
|
|
1401
|
+
* 注意:由于移除了磁盘存储,此函数现在只返回 0(无预热条目)
|
|
1552
1402
|
*/
|
|
1553
1403
|
async function warmupReqIdStore(accountId = "default", log) {
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
});
|
|
1404
|
+
// 由于移除了磁盘存储,不再需要预热过程
|
|
1405
|
+
log?.("[WeCom] reqid-store warmup: no-op (disk storage removed)");
|
|
1406
|
+
return 0;
|
|
1558
1407
|
}
|
|
1559
1408
|
// ============================================================================
|
|
1560
1409
|
// 全局 cleanup(断开连接时释放所有资源)
|
|
@@ -1574,17 +1423,8 @@ async function cleanupAccount(accountId) {
|
|
|
1574
1423
|
}
|
|
1575
1424
|
wsClientInstances.delete(accountId);
|
|
1576
1425
|
}
|
|
1577
|
-
// 2. flush reqId
|
|
1578
|
-
|
|
1579
|
-
if (store) {
|
|
1580
|
-
try {
|
|
1581
|
-
await store.flush();
|
|
1582
|
-
}
|
|
1583
|
-
catch {
|
|
1584
|
-
// 忽略 flush 错误
|
|
1585
|
-
}
|
|
1586
|
-
// 注意:不删除 store,因为重连后可能还需要
|
|
1587
|
-
}
|
|
1426
|
+
// 2. 由于移除了磁盘存储,不再需要 flush reqId 存储
|
|
1427
|
+
// 注意:不删除 store,因为重连后可能还需要
|
|
1588
1428
|
}
|
|
1589
1429
|
|
|
1590
1430
|
/** 从 package.json 中读取版本号,兼容打包产物和直接运行 .ts 两种场景 */
|
|
@@ -2277,7 +2117,7 @@ const DefaultWsUrl = "wss://openws.work.weixin.qq.com";
|
|
|
2277
2117
|
function resolveWeComAccount(cfg) {
|
|
2278
2118
|
const wecomConfig = (cfg.channels?.[CHANNEL_ID] ?? {});
|
|
2279
2119
|
return {
|
|
2280
|
-
accountId:
|
|
2120
|
+
accountId: core.DEFAULT_ACCOUNT_ID,
|
|
2281
2121
|
name: wecomConfig.name ?? "企业微信",
|
|
2282
2122
|
enabled: wecomConfig.enabled ?? false,
|
|
2283
2123
|
websocketUrl: wecomConfig.websocketUrl || DefaultWsUrl,
|
|
@@ -2359,7 +2199,7 @@ function setWeComDmPolicy(cfg, dmPolicy) {
|
|
|
2359
2199
|
const account = resolveWeComAccount(cfg);
|
|
2360
2200
|
const existingAllowFrom = account.config.allowFrom ?? [];
|
|
2361
2201
|
const allowFrom = dmPolicy === "open"
|
|
2362
|
-
?
|
|
2202
|
+
? setup.addWildcardAllowFrom(existingAllowFrom.map((x) => String(x)))
|
|
2363
2203
|
: existingAllowFrom.map((x) => String(x));
|
|
2364
2204
|
return setWeComAccount(cfg, {
|
|
2365
2205
|
dmPolicy,
|
|
@@ -2435,7 +2275,7 @@ const wecomOnboardingAdapter = {
|
|
|
2435
2275
|
* 无需依赖 reqId,直接向指定会话推送消息
|
|
2436
2276
|
*/
|
|
2437
2277
|
async function sendWeComMessage({ to, content, accountId, }) {
|
|
2438
|
-
const resolvedAccountId = accountId ??
|
|
2278
|
+
const resolvedAccountId = accountId ?? core.DEFAULT_ACCOUNT_ID;
|
|
2439
2279
|
// 从 to 中提取 chatId(格式是 "${CHANNEL_ID}:chatId" 或直接是 chatId)
|
|
2440
2280
|
const channelPrefix = new RegExp(`^${CHANNEL_ID}:`, "i");
|
|
2441
2281
|
const chatId = to.replace(channelPrefix, "");
|
|
@@ -2497,11 +2337,11 @@ const wecomPlugin = {
|
|
|
2497
2337
|
reload: { configPrefixes: [`channels.${CHANNEL_ID}`] },
|
|
2498
2338
|
config: {
|
|
2499
2339
|
// 列出所有账户 ID(最小实现只支持默认账户)
|
|
2500
|
-
listAccountIds: () => [
|
|
2340
|
+
listAccountIds: () => [core.DEFAULT_ACCOUNT_ID],
|
|
2501
2341
|
// 解析账户配置
|
|
2502
2342
|
resolveAccount: (cfg) => resolveWeComAccount(cfg),
|
|
2503
2343
|
// 获取默认账户 ID
|
|
2504
|
-
defaultAccountId: () =>
|
|
2344
|
+
defaultAccountId: () => core.DEFAULT_ACCOUNT_ID,
|
|
2505
2345
|
// 设置账户启用状态
|
|
2506
2346
|
setAccountEnabled: ({ cfg, enabled }) => {
|
|
2507
2347
|
const wecomConfig = (cfg.channels?.[CHANNEL_ID] ?? {});
|
|
@@ -2557,7 +2397,7 @@ const wecomPlugin = {
|
|
|
2557
2397
|
allowFrom: account.config.allowFrom ?? [],
|
|
2558
2398
|
policyPath: `${basePath}dmPolicy`,
|
|
2559
2399
|
allowFromPath: basePath,
|
|
2560
|
-
approveHint:
|
|
2400
|
+
approveHint: core.formatPairingApproveHint(CHANNEL_ID),
|
|
2561
2401
|
normalizeEntry: (raw) => raw.replace(new RegExp(`^${CHANNEL_ID}:`, "i"), "").trim(),
|
|
2562
2402
|
};
|
|
2563
2403
|
},
|
|
@@ -2613,7 +2453,7 @@ const wecomPlugin = {
|
|
|
2613
2453
|
return sendWeComMessage({ to, content: text, accountId: accountId ?? undefined });
|
|
2614
2454
|
},
|
|
2615
2455
|
sendMedia: async ({ to, text, mediaUrl, mediaLocalRoots, accountId }) => {
|
|
2616
|
-
const resolvedAccountId = accountId ??
|
|
2456
|
+
const resolvedAccountId = accountId ?? core.DEFAULT_ACCOUNT_ID;
|
|
2617
2457
|
const channelPrefix = new RegExp(`^${CHANNEL_ID}:`, "i");
|
|
2618
2458
|
const chatId = to.replace(channelPrefix, "");
|
|
2619
2459
|
// 获取 WSClient 实例
|
|
@@ -2658,14 +2498,14 @@ const wecomPlugin = {
|
|
|
2658
2498
|
},
|
|
2659
2499
|
status: {
|
|
2660
2500
|
defaultRuntime: {
|
|
2661
|
-
accountId:
|
|
2501
|
+
accountId: core.DEFAULT_ACCOUNT_ID,
|
|
2662
2502
|
running: false,
|
|
2663
2503
|
lastStartAt: null,
|
|
2664
2504
|
lastStopAt: null,
|
|
2665
2505
|
lastError: null,
|
|
2666
2506
|
},
|
|
2667
2507
|
collectStatusIssues: (accounts) => accounts.flatMap((entry) => {
|
|
2668
|
-
const accountId = String(entry.accountId ??
|
|
2508
|
+
const accountId = String(entry.accountId ?? core.DEFAULT_ACCOUNT_ID);
|
|
2669
2509
|
const enabled = entry.enabled !== false;
|
|
2670
2510
|
const configured = entry.configured === true;
|
|
2671
2511
|
if (!enabled) {
|
|
@@ -2832,7 +2672,7 @@ const inflightInitRequests = new Map();
|
|
|
2832
2672
|
* @returns 完整的 response.body 配置对象(至少包含 url 字段)
|
|
2833
2673
|
*/
|
|
2834
2674
|
async function fetchMcpConfig(category) {
|
|
2835
|
-
const wsClient = getWeComWebSocket(
|
|
2675
|
+
const wsClient = getWeComWebSocket(core.DEFAULT_ACCOUNT_ID);
|
|
2836
2676
|
if (!wsClient) {
|
|
2837
2677
|
throw new Error("WSClient 未连接,无法拉取 MCP 配置");
|
|
2838
2678
|
}
|
|
@@ -3573,7 +3413,7 @@ const plugin = {
|
|
|
3573
3413
|
id: "wecom-openclaw-plugin",
|
|
3574
3414
|
name: "企业微信",
|
|
3575
3415
|
description: "企业微信 OpenClaw 插件",
|
|
3576
|
-
configSchema:
|
|
3416
|
+
configSchema: core.emptyPluginConfigSchema(),
|
|
3577
3417
|
register(api) {
|
|
3578
3418
|
setWeComRuntime(api.runtime);
|
|
3579
3419
|
api.registerChannel({ plugin: wecomPlugin });
|