@wecom/wecom-openclaw-plugin 2026.3.20 → 2026.3.24-beta.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.
package/README.md CHANGED
@@ -37,7 +37,25 @@
37
37
 
38
38
  - OpenClaw `>= 2026.2.13`
39
39
 
40
- ### Installation
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 pluginSdk = require('openclaw/plugin-sdk');
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');
@@ -11,7 +11,10 @@ var path = require('node:path');
11
11
  var os = require('node:os');
12
12
  var node_url = require('node:url');
13
13
  var fileType = require('file-type');
14
+ var jsonStore = require('openclaw/plugin-sdk/json-store');
15
+ var infraRuntime = require('openclaw/plugin-sdk/infra-runtime');
14
16
  var node_fs = require('node:fs');
17
+ var setup = require('openclaw/plugin-sdk/setup');
15
18
 
16
19
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
17
20
  function _interopNamespaceDefault(e) {
@@ -57,7 +60,7 @@ function getWeComRuntime() {
57
60
  * 本模块在加载时一次性探测 SDK 导出,存在则直接 re-export SDK 版本,
58
61
  * 不存在则导出 fallback 实现。其他模块统一从本文件导入,无需关心底层兼容细节。
59
62
  */
60
- const _sdkReady = import('openclaw/plugin-sdk')
63
+ const _sdkReady = import('openclaw/plugin-sdk/core')
61
64
  .then((sdk) => {
62
65
  const exports$1 = {};
63
66
  if (typeof sdk.loadOutboundMediaFromUrl === "function") {
@@ -1320,9 +1323,9 @@ function createPersistentReqIdStore(accountId, options) {
1320
1323
  dirty = false;
1321
1324
  const now = Date.now();
1322
1325
  try {
1323
- await pluginSdk.withFileLock(filePath, DEFAULT_LOCK_OPTIONS, async () => {
1326
+ await infraRuntime.withFileLock(filePath, DEFAULT_LOCK_OPTIONS, async () => {
1324
1327
  // 读取现有磁盘数据并合并
1325
- const { value } = await pluginSdk.readJsonFileWithFallback(filePath, {});
1328
+ const { value } = await jsonStore.readJsonFileWithFallback(filePath, {});
1326
1329
  const data = sanitizeData(value);
1327
1330
  // 将内存中未过期的数据合并到磁盘数据(内存优先)
1328
1331
  for (const [chatId, entry] of memory) {
@@ -1333,7 +1336,7 @@ function createPersistentReqIdStore(accountId, options) {
1333
1336
  // 清理过期和超量
1334
1337
  pruneFileData(data, now);
1335
1338
  // 原子写入
1336
- await pluginSdk.writeJsonFileAtomically(filePath, data);
1339
+ await jsonStore.writeJsonFileAtomically(filePath, data);
1337
1340
  });
1338
1341
  }
1339
1342
  catch (error) {
@@ -1362,7 +1365,7 @@ function createPersistentReqIdStore(accountId, options) {
1362
1365
  }
1363
1366
  // 2. 内存 miss,回查磁盘并回填内存
1364
1367
  try {
1365
- const { value } = await pluginSdk.readJsonFileWithFallback(filePath, {});
1368
+ const { value } = await jsonStore.readJsonFileWithFallback(filePath, {});
1366
1369
  const data = sanitizeData(value);
1367
1370
  const diskEntry = data[chatId];
1368
1371
  if (diskEntry && !isExpired(diskEntry, now)) {
@@ -1394,7 +1397,7 @@ function createPersistentReqIdStore(accountId, options) {
1394
1397
  async function warmup(onError) {
1395
1398
  const now = Date.now();
1396
1399
  try {
1397
- const { value } = await pluginSdk.readJsonFileWithFallback(filePath, {});
1400
+ const { value } = await jsonStore.readJsonFileWithFallback(filePath, {});
1398
1401
  const data = sanitizeData(value);
1399
1402
  let loaded = 0;
1400
1403
  for (const [chatId, entry] of Object.entries(data)) {
@@ -2277,7 +2280,7 @@ const DefaultWsUrl = "wss://openws.work.weixin.qq.com";
2277
2280
  function resolveWeComAccount(cfg) {
2278
2281
  const wecomConfig = (cfg.channels?.[CHANNEL_ID] ?? {});
2279
2282
  return {
2280
- accountId: pluginSdk.DEFAULT_ACCOUNT_ID,
2283
+ accountId: core.DEFAULT_ACCOUNT_ID,
2281
2284
  name: wecomConfig.name ?? "企业微信",
2282
2285
  enabled: wecomConfig.enabled ?? false,
2283
2286
  websocketUrl: wecomConfig.websocketUrl || DefaultWsUrl,
@@ -2359,7 +2362,7 @@ function setWeComDmPolicy(cfg, dmPolicy) {
2359
2362
  const account = resolveWeComAccount(cfg);
2360
2363
  const existingAllowFrom = account.config.allowFrom ?? [];
2361
2364
  const allowFrom = dmPolicy === "open"
2362
- ? pluginSdk.addWildcardAllowFrom(existingAllowFrom.map((x) => String(x)))
2365
+ ? setup.addWildcardAllowFrom(existingAllowFrom.map((x) => String(x)))
2363
2366
  : existingAllowFrom.map((x) => String(x));
2364
2367
  return setWeComAccount(cfg, {
2365
2368
  dmPolicy,
@@ -2435,7 +2438,7 @@ const wecomOnboardingAdapter = {
2435
2438
  * 无需依赖 reqId,直接向指定会话推送消息
2436
2439
  */
2437
2440
  async function sendWeComMessage({ to, content, accountId, }) {
2438
- const resolvedAccountId = accountId ?? pluginSdk.DEFAULT_ACCOUNT_ID;
2441
+ const resolvedAccountId = accountId ?? core.DEFAULT_ACCOUNT_ID;
2439
2442
  // 从 to 中提取 chatId(格式是 "${CHANNEL_ID}:chatId" 或直接是 chatId)
2440
2443
  const channelPrefix = new RegExp(`^${CHANNEL_ID}:`, "i");
2441
2444
  const chatId = to.replace(channelPrefix, "");
@@ -2497,11 +2500,11 @@ const wecomPlugin = {
2497
2500
  reload: { configPrefixes: [`channels.${CHANNEL_ID}`] },
2498
2501
  config: {
2499
2502
  // 列出所有账户 ID(最小实现只支持默认账户)
2500
- listAccountIds: () => [pluginSdk.DEFAULT_ACCOUNT_ID],
2503
+ listAccountIds: () => [core.DEFAULT_ACCOUNT_ID],
2501
2504
  // 解析账户配置
2502
2505
  resolveAccount: (cfg) => resolveWeComAccount(cfg),
2503
2506
  // 获取默认账户 ID
2504
- defaultAccountId: () => pluginSdk.DEFAULT_ACCOUNT_ID,
2507
+ defaultAccountId: () => core.DEFAULT_ACCOUNT_ID,
2505
2508
  // 设置账户启用状态
2506
2509
  setAccountEnabled: ({ cfg, enabled }) => {
2507
2510
  const wecomConfig = (cfg.channels?.[CHANNEL_ID] ?? {});
@@ -2557,7 +2560,7 @@ const wecomPlugin = {
2557
2560
  allowFrom: account.config.allowFrom ?? [],
2558
2561
  policyPath: `${basePath}dmPolicy`,
2559
2562
  allowFromPath: basePath,
2560
- approveHint: pluginSdk.formatPairingApproveHint(CHANNEL_ID),
2563
+ approveHint: core.formatPairingApproveHint(CHANNEL_ID),
2561
2564
  normalizeEntry: (raw) => raw.replace(new RegExp(`^${CHANNEL_ID}:`, "i"), "").trim(),
2562
2565
  };
2563
2566
  },
@@ -2613,7 +2616,7 @@ const wecomPlugin = {
2613
2616
  return sendWeComMessage({ to, content: text, accountId: accountId ?? undefined });
2614
2617
  },
2615
2618
  sendMedia: async ({ to, text, mediaUrl, mediaLocalRoots, accountId }) => {
2616
- const resolvedAccountId = accountId ?? pluginSdk.DEFAULT_ACCOUNT_ID;
2619
+ const resolvedAccountId = accountId ?? core.DEFAULT_ACCOUNT_ID;
2617
2620
  const channelPrefix = new RegExp(`^${CHANNEL_ID}:`, "i");
2618
2621
  const chatId = to.replace(channelPrefix, "");
2619
2622
  // 获取 WSClient 实例
@@ -2658,14 +2661,14 @@ const wecomPlugin = {
2658
2661
  },
2659
2662
  status: {
2660
2663
  defaultRuntime: {
2661
- accountId: pluginSdk.DEFAULT_ACCOUNT_ID,
2664
+ accountId: core.DEFAULT_ACCOUNT_ID,
2662
2665
  running: false,
2663
2666
  lastStartAt: null,
2664
2667
  lastStopAt: null,
2665
2668
  lastError: null,
2666
2669
  },
2667
2670
  collectStatusIssues: (accounts) => accounts.flatMap((entry) => {
2668
- const accountId = String(entry.accountId ?? pluginSdk.DEFAULT_ACCOUNT_ID);
2671
+ const accountId = String(entry.accountId ?? core.DEFAULT_ACCOUNT_ID);
2669
2672
  const enabled = entry.enabled !== false;
2670
2673
  const configured = entry.configured === true;
2671
2674
  if (!enabled) {
@@ -2832,7 +2835,7 @@ const inflightInitRequests = new Map();
2832
2835
  * @returns 完整的 response.body 配置对象(至少包含 url 字段)
2833
2836
  */
2834
2837
  async function fetchMcpConfig(category) {
2835
- const wsClient = getWeComWebSocket(pluginSdk.DEFAULT_ACCOUNT_ID);
2838
+ const wsClient = getWeComWebSocket(core.DEFAULT_ACCOUNT_ID);
2836
2839
  if (!wsClient) {
2837
2840
  throw new Error("WSClient 未连接,无法拉取 MCP 配置");
2838
2841
  }
@@ -3573,7 +3576,7 @@ const plugin = {
3573
3576
  id: "wecom-openclaw-plugin",
3574
3577
  name: "企业微信",
3575
3578
  description: "企业微信 OpenClaw 插件",
3576
- configSchema: pluginSdk.emptyPluginConfigSchema(),
3579
+ configSchema: core.emptyPluginConfigSchema(),
3577
3580
  register(api) {
3578
3581
  setWeComRuntime(api.runtime);
3579
3582
  api.registerChannel({ plugin: wecomPlugin });