@openclaw-china/wecom 2026.3.22 → 2026.4.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/dist/index.d.ts CHANGED
@@ -103,6 +103,13 @@ interface PluginConfig {
103
103
  };
104
104
  }
105
105
 
106
+ type WecomMessageActionName = "send" | "sendAttachment";
107
+ interface WecomMessageToolResult {
108
+ ok: boolean;
109
+ messageId?: string;
110
+ error?: string;
111
+ [key: string]: unknown;
112
+ }
106
113
  declare const wecomPlugin: {
107
114
  id: string;
108
115
  meta: {
@@ -463,6 +470,25 @@ declare const wecomPlugin: {
463
470
  setStatus?: (status: Record<string, unknown>) => void;
464
471
  }) => Promise<void>;
465
472
  };
473
+ actions: {
474
+ describeMessageTool: () => {
475
+ actions: WecomMessageActionName[];
476
+ capabilities: string[];
477
+ schema?: {
478
+ properties: Record<string, unknown>;
479
+ visibility?: "current-channel" | "all-configured";
480
+ };
481
+ };
482
+ handleAction: (ctx: {
483
+ channel: string;
484
+ action: string;
485
+ params: Record<string, unknown>;
486
+ cfg: PluginConfig;
487
+ accountId?: string | null;
488
+ sessionKey?: string | null;
489
+ sessionId?: string | null;
490
+ }) => Promise<WecomMessageToolResult>;
491
+ };
466
492
  };
467
493
 
468
494
  /**
package/dist/index.js CHANGED
@@ -1723,9 +1723,10 @@ var CONFIG_FILE_PATH = join(OPENCLAW_HOME, "openclaw.json");
1723
1723
  var ANSI_RESET = "\x1B[0m";
1724
1724
  var ANSI_LINK = "\x1B[1;4;96m";
1725
1725
  var ANSI_BORDER = "\x1B[92m";
1726
+ var QQBOT_CHANNEL_ID = "qqbot-china";
1726
1727
  var CHANNEL_ORDER = [
1727
1728
  "dingtalk",
1728
- "qqbot",
1729
+ QQBOT_CHANNEL_ID,
1729
1730
  "wecom",
1730
1731
  "wecom-app",
1731
1732
  "wecom-kf",
@@ -1739,7 +1740,7 @@ var CHANNEL_DISPLAY_LABELS = {
1739
1740
  "wecom-app": "WeCom App\uFF08\u81EA\u5EFA\u5E94\u7528-\u53EF\u63A5\u5165\u5FAE\u4FE1\uFF09",
1740
1741
  "wecom-kf": "WeCom KF\uFF08\u5FAE\u4FE1\u5BA2\u670D\uFF09",
1741
1742
  "wechat-mp": "WeChat MP\uFF08\u5FAE\u4FE1\u516C\u4F17\u53F7\uFF09",
1742
- qqbot: "QQBot\uFF08QQ \u673A\u5668\u4EBA\uFF09"
1743
+ "qqbot-china": "QQBot\uFF08QQ \u673A\u5668\u4EBA\uFF09"
1743
1744
  };
1744
1745
  var CHANNEL_GUIDE_LINKS = {
1745
1746
  dingtalk: `${GUIDES_BASE}/dingtalk/configuration.md`,
@@ -1748,7 +1749,7 @@ var CHANNEL_GUIDE_LINKS = {
1748
1749
  "wecom-app": `${GUIDES_BASE}/wecom-app/configuration.md`,
1749
1750
  "wecom-kf": "https://github.com/BytePioneer-AI/openclaw-china/blob/main/extensions/wecom-kf/README.md",
1750
1751
  "wechat-mp": `${GUIDES_BASE}/wechat-mp/configuration.md`,
1751
- qqbot: `${GUIDES_BASE}/qqbot/configuration.md`
1752
+ "qqbot-china": `${GUIDES_BASE}/qqbot/configuration.md`
1752
1753
  };
1753
1754
  var CHINA_CLI_STATE_KEY = /* @__PURE__ */ Symbol.for("@openclaw-china/china-cli-state");
1754
1755
  var PromptCancelledError = class extends Error {
@@ -1950,7 +1951,7 @@ function isChannelConfigured(cfg, channelId) {
1950
1951
  return hasNonEmptyString(channelCfg.clientId) && hasNonEmptyString(channelCfg.clientSecret);
1951
1952
  case "feishu-china":
1952
1953
  return hasNonEmptyString(channelCfg.appId) && hasNonEmptyString(channelCfg.appSecret);
1953
- case "qqbot":
1954
+ case "qqbot-china":
1954
1955
  return hasNonEmptyString(channelCfg.appId) && hasNonEmptyString(channelCfg.clientSecret);
1955
1956
  case "wecom":
1956
1957
  return hasWecomWsCredentialPair(channelCfg);
@@ -1971,11 +1972,12 @@ function withConfiguredSuffix(cfg, channelId) {
1971
1972
  function mergeChannelConfig(cfg, channelId, patch) {
1972
1973
  const channels = isRecord(cfg.channels) ? { ...cfg.channels } : {};
1973
1974
  const existing = getChannelConfig(cfg, channelId);
1974
- channels[channelId] = {
1975
+ const nextChannelConfig = {
1975
1976
  ...existing,
1976
1977
  ...patch,
1977
1978
  enabled: true
1978
1979
  };
1980
+ channels[channelId] = nextChannelConfig;
1979
1981
  return {
1980
1982
  ...cfg,
1981
1983
  channels
@@ -2352,8 +2354,8 @@ async function configureWechatMp(prompter, cfg) {
2352
2354
  }
2353
2355
  async function configureQQBot(prompter, cfg) {
2354
2356
  section("\u914D\u7F6E QQBot\uFF08QQ \u673A\u5668\u4EBA\uFF09");
2355
- showGuideLink("qqbot");
2356
- const existing = getChannelConfig(cfg, "qqbot");
2357
+ showGuideLink(QQBOT_CHANNEL_ID);
2358
+ const existing = getChannelConfig(cfg, QQBOT_CHANNEL_ID);
2357
2359
  const existingAsr = isRecord(existing.asr) ? existing.asr : {};
2358
2360
  const appId = await prompter.askText({
2359
2361
  label: "QQBot appId",
@@ -2390,7 +2392,7 @@ async function configureQQBot(prompter, cfg) {
2390
2392
  required: true
2391
2393
  });
2392
2394
  }
2393
- return mergeChannelConfig(cfg, "qqbot", {
2395
+ return mergeChannelConfig(cfg, QQBOT_CHANNEL_ID, {
2394
2396
  appId,
2395
2397
  clientSecret,
2396
2398
  asr
@@ -2410,7 +2412,7 @@ async function configureSingleChannel(channel, prompter, cfg) {
2410
2412
  return configureWecomKf(prompter, cfg);
2411
2413
  case "wechat-mp":
2412
2414
  return configureWechatMp(prompter, cfg);
2413
- case "qqbot":
2415
+ case "qqbot-china":
2414
2416
  return configureQQBot(prompter, cfg);
2415
2417
  default:
2416
2418
  return cfg;
@@ -2552,7 +2554,7 @@ var SUPPORTED_CHANNELS = [
2552
2554
  "wecom-app",
2553
2555
  "wecom-kf",
2554
2556
  "wechat-mp",
2555
- "qqbot"
2557
+ "qqbot-china"
2556
2558
  ];
2557
2559
  var CHINA_INSTALL_HINT_SHOWN_KEY = /* @__PURE__ */ Symbol.for("@openclaw-china/china-install-hint-shown");
2558
2560
  function isRecord2(value) {
@@ -10178,6 +10180,91 @@ function stopWecomWsGatewayForAccount(accountId) {
10178
10180
  }
10179
10181
 
10180
10182
  // src/channel.ts
10183
+ function readStringParam(params, name, opts) {
10184
+ const value = params[name];
10185
+ if (value === void 0 || value === null) {
10186
+ if (opts?.required) {
10187
+ throw new Error(`wecom ${name} param is required`);
10188
+ }
10189
+ return void 0;
10190
+ }
10191
+ const str = String(value);
10192
+ return opts?.trim ? str.trim() : str;
10193
+ }
10194
+ async function handleWecomMessageAction(ctx, outbound) {
10195
+ const { action, params, cfg, accountId, sessionKey, sessionId } = ctx;
10196
+ const commonParams = {
10197
+ cfg,
10198
+ accountId: accountId ?? void 0,
10199
+ sessionKey: sessionKey ?? void 0,
10200
+ runId: sessionId ?? void 0
10201
+ };
10202
+ if (action === "send") {
10203
+ const to = readStringParam(params, "to", { required: true });
10204
+ const message = readStringParam(params, "message", { required: false, trim: true }) ?? "";
10205
+ const media = readStringParam(params, "media", { trim: false });
10206
+ if (!to) {
10207
+ return { ok: false, error: "wecom send requires 'to' param" };
10208
+ }
10209
+ if (media) {
10210
+ const result = await outbound.sendMedia({
10211
+ ...commonParams,
10212
+ to,
10213
+ mediaUrl: media,
10214
+ text: message || void 0
10215
+ });
10216
+ if (!result.ok) {
10217
+ return { ok: false, error: result.error?.message ?? "sendMedia failed" };
10218
+ }
10219
+ return { ok: true, messageId: result.messageId };
10220
+ } else {
10221
+ const result = await outbound.sendText({
10222
+ ...commonParams,
10223
+ to,
10224
+ text: message
10225
+ });
10226
+ if (!result.ok) {
10227
+ return { ok: false, error: result.error?.message ?? "sendText failed" };
10228
+ }
10229
+ return { ok: true, messageId: result.messageId };
10230
+ }
10231
+ }
10232
+ if (action === "sendAttachment") {
10233
+ const to = readStringParam(params, "to", { required: true });
10234
+ const media = readStringParam(params, "media", { trim: false });
10235
+ const caption = readStringParam(params, "caption", { required: false, trim: true });
10236
+ if (!to) {
10237
+ return { ok: false, error: "wecom sendAttachment requires 'to' param" };
10238
+ }
10239
+ if (!media) {
10240
+ return { ok: false, error: "wecom sendAttachment requires 'media' param" };
10241
+ }
10242
+ const result = await outbound.sendMedia({
10243
+ ...commonParams,
10244
+ to,
10245
+ mediaUrl: media,
10246
+ text: caption
10247
+ });
10248
+ if (!result.ok) {
10249
+ return { ok: false, error: result.error?.message ?? "sendMedia failed" };
10250
+ }
10251
+ return { ok: true, messageId: result.messageId };
10252
+ }
10253
+ return { ok: false, error: `Unsupported wecom action: ${action}` };
10254
+ }
10255
+ function describeWecomMessageTool() {
10256
+ return {
10257
+ actions: ["send", "sendAttachment"],
10258
+ capabilities: ["media"],
10259
+ schema: {
10260
+ properties: {
10261
+ media: { type: "string", description: "Media file URL or local file path (for file/image/audio/video attachments)" },
10262
+ caption: { type: "string", description: "Optional caption text for the media" }
10263
+ },
10264
+ visibility: "current-channel"
10265
+ }
10266
+ };
10267
+ }
10181
10268
  var BARE_USER_ID_RE = /^[a-z0-9][a-z0-9._@-]{0,63}$/;
10182
10269
  var EXPLICIT_USER_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._@-]{0,63}$/;
10183
10270
  var GROUP_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/;
@@ -10932,6 +11019,10 @@ var wecomPlugin = {
10932
11019
  stopWecomWsGatewayForAccount(ctx.accountId);
10933
11020
  ctx.setStatus?.({ accountId: ctx.accountId, running: false, lastStopAt: Date.now() });
10934
11021
  }
11022
+ },
11023
+ actions: {
11024
+ describeMessageTool: () => describeWecomMessageTool(),
11025
+ handleAction: async (ctx) => handleWecomMessageAction(ctx, wecomPlugin.outbound)
10935
11026
  }
10936
11027
  };
10937
11028