@sunnoy/wecom 1.5.1 → 1.6.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,7 @@
37
37
 
38
38
  ## 前置要求
39
39
 
40
- - 已安装 [OpenClaw](https://github.com/openclaw/openclaw) (版本 2026.1.30+)
40
+ - 已安装 [OpenClaw](https://github.com/openclaw/openclaw) (版本 2026.3.2+)
41
41
  - 企业微信管理后台权限,可创建智能机器人应用或自建应用
42
42
  - 可从企业微信访问的服务器地址(HTTP/HTTPS)
43
43
 
@@ -124,6 +124,9 @@ npm run test:e2e
124
124
  "enabled": true,
125
125
  "allowlist": ["/new", "/status", "/help", "/compact"]
126
126
  },
127
+ "network": {
128
+ "egressProxyUrl": "http://your-proxy-host:8080"
129
+ },
127
130
  "agent": {
128
131
  "corpId": "企业 CorpID",
129
132
  "corpSecret": "应用 Secret",
@@ -186,6 +189,15 @@ npm run test:e2e
186
189
  | `channels.wecom.agent.token` | string | 是 | 回调 Token (用于验证签名) |
187
190
  | `channels.wecom.agent.encodingAesKey` | string | 是 | 回调 EncodingAESKey (43 位) |
188
191
 
192
+ #### 网络代理配置 (可选)
193
+
194
+ 用于 Agent / Webhook 等外发请求走固定出口代理(适用于企业微信固定 IP 白名单场景)。
195
+
196
+ | 配置项 | 类型 | 必填 | 说明 |
197
+ |--------|------|------|------|
198
+ | `channels.wecom.network.egressProxyUrl` | string | 否 | 外发 HTTP(S) 代理地址,例如 `http://proxy:8080` |
199
+ | `WECOM_EGRESS_PROXY_URL` | env | 否 | 环境变量方式配置代理,优先级高于 `channels.wecom.network.egressProxyUrl` |
200
+
189
201
  #### Webhook 配置 (可选)
190
202
 
191
203
  配置 Webhook Bot 用于群通知:
package/index.js CHANGED
@@ -38,16 +38,18 @@ const plugin = {
38
38
  api.registerChannel({ plugin: wecomChannelPlugin });
39
39
  logger.info("WeCom channel registered");
40
40
 
41
- // Register HTTP handler for webhooks.
42
- // OpenClaw 2026.3.2+ removed registerHttpHandler; the primary route
43
- // registration now happens in gateway.startAccount via registerPluginHttpRoute.
44
- // Keep the legacy handler for backward compatibility with older versions.
45
- if (typeof api.registerHttpHandler === "function") {
46
- api.registerHttpHandler(wecomHttpHandler);
47
- logger.info("WeCom HTTP handler registered (legacy wildcard)");
48
- } else {
49
- logger.info("WeCom: registerHttpHandler unavailable, routes registered via gateway lifecycle");
50
- }
41
+ // Register webhook HTTP route with auth: "plugin" so gateway does NOT
42
+ // enforce Bearer-token auth. WeCom callbacks use msg_signature verification
43
+ // which the plugin handles internally.
44
+ // OpenClaw 3.2 removed registerHttpHandler; use registerHttpRoute with
45
+ // auth: "plugin" + match: "prefix" to handle all /webhooks/* paths.
46
+ api.registerHttpRoute({
47
+ path: "/webhooks",
48
+ handler: wecomHttpHandler,
49
+ auth: "plugin",
50
+ match: "prefix",
51
+ });
52
+ logger.info("WeCom HTTP route registered (auth: plugin, match: prefix)");
51
53
  },
52
54
  };
53
55
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sunnoy/wecom",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "Enterprise WeChat AI Bot channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -13,7 +13,7 @@ import { resolveWecomTarget } from "./target.js";
13
13
  import { webhookSendImage, webhookSendText, webhookUploadFile, webhookSendFile } from "./webhook-bot.js";
14
14
  import { normalizeWebhookPath, registerWebhookTarget } from "./webhook-targets.js";
15
15
  import { wecomFetch, setConfigProxyUrl } from "./http.js";
16
- import { createWecomRouteHandler } from "./http-handler.js";
16
+
17
17
 
18
18
  const AGENT_IMAGE_EXTS = new Set(["jpg", "jpeg", "png", "gif", "bmp"]);
19
19
 
@@ -726,30 +726,15 @@ export const wecomChannelPlugin = {
726
726
  config: ctx.cfg,
727
727
  });
728
728
 
729
- // Register HTTP route with OpenClaw route framework.
730
- // Uses registerPluginHttpRoute (new API in OpenClaw 2026.3.2+) for explicit
731
- // path-based routing. Falls back gracefully when the SDK is unavailable
732
- // (older OpenClaw uses the legacy wildcard handler registered in index.js).
733
- let unregisterBotRoute;
729
+ // HTTP routing is handled by the wildcard handler registered in
730
+ // index.js via api.registerHttpHandler. That handler bypasses gateway
731
+ // auth, which is required for WeCom webhook callbacks (they carry
732
+ // msg_signature, not Bearer tokens).
734
733
  const botPath = account.webhookPath || "/webhooks/wecom";
735
- try {
736
- const { registerPluginHttpRoute } = await import("openclaw/plugin-sdk");
737
- unregisterBotRoute = registerPluginHttpRoute({
738
- path: botPath,
739
- pluginId: "wecom",
740
- accountId: account.accountId,
741
- log: (msg) => logger.info(msg),
742
- handler: createWecomRouteHandler(normalizeWebhookPath(botPath)),
743
- });
744
- logger.info("WeCom Bot HTTP route registered", { path: botPath });
745
- } catch {
746
- // openclaw/plugin-sdk not available — rely on legacy registerHttpHandler.
747
- logger.debug("registerPluginHttpRoute unavailable, using legacy handler", { path: botPath });
748
- }
734
+ logger.info("WeCom Bot webhook path active", { path: botPath });
749
735
 
750
736
  // Register Agent inbound webhook if agent inbound is fully configured.
751
737
  let unregisterAgent;
752
- let unregisterAgentRoute;
753
738
  // Per-account agent path: /webhooks/app for default, /webhooks/app/{accountId} for others.
754
739
  const agentInboundPath = account.accountId === DEFAULT_ACCOUNT_ID
755
740
  ? "/webhooks/app"
@@ -778,22 +763,6 @@ export const wecomChannelPlugin = {
778
763
  config: ctx.cfg,
779
764
  });
780
765
  logger.info("WeCom Agent inbound webhook registered", { path: agentInboundPath });
781
-
782
- // Register agent inbound HTTP route (new API).
783
- try {
784
- const { registerPluginHttpRoute } = await import("openclaw/plugin-sdk");
785
- unregisterAgentRoute = registerPluginHttpRoute({
786
- path: agentInboundPath,
787
- pluginId: "wecom",
788
- accountId: account.accountId,
789
- source: "agent-inbound",
790
- log: (msg) => logger.info(msg),
791
- handler: createWecomRouteHandler(normalizeWebhookPath(agentInboundPath)),
792
- });
793
- logger.info("WeCom Agent inbound HTTP route registered", { path: agentInboundPath });
794
- } catch {
795
- logger.debug("registerPluginHttpRoute unavailable for agent inbound, using legacy handler");
796
- }
797
766
  }
798
767
  }
799
768
 
@@ -805,9 +774,7 @@ export const wecomChannelPlugin = {
805
774
  }
806
775
  messageBuffers.clear();
807
776
  unregister();
808
- if (unregisterBotRoute) unregisterBotRoute();
809
777
  if (unregisterAgent) unregisterAgent();
810
- if (unregisterAgentRoute) unregisterAgentRoute();
811
778
  };
812
779
 
813
780
  // Backward compatibility: older runtime may not pass abortSignal.
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shared flag that tracks whether the legacy wildcard HTTP handler was
3
+ * successfully registered via api.registerHttpHandler().
4
+ *
5
+ * When true, gateway.startAccount must NOT also register via
6
+ * registerPluginHttpRoute — the latter places the path into
7
+ * registry.httpRoutes which causes shouldEnforceGatewayAuthForPluginPath
8
+ * → isRegisteredPluginHttpRoutePath to return true → gateway auth
9
+ * enforcement runs → WeCom webhook callbacks (which carry msg_signature,
10
+ * not Bearer tokens) get blocked with 401.
11
+ *
12
+ * This module is intentionally separate from index.js to avoid circular
13
+ * ESM imports (index.js ↔ wecom/channel-plugin.js).
14
+ */
15
+ let _wildcardHttpHandlerRegistered = false;
16
+
17
+ export function markWildcardHttpHandlerRegistered() {
18
+ _wildcardHttpHandlerRegistered = true;
19
+ }
20
+
21
+ export function isWildcardHttpHandlerRegistered() {
22
+ return _wildcardHttpHandlerRegistered;
23
+ }