Skip to content

Documentation Sync

This page is auto-generated from plugins/adapters/wecom/README.md. Please edit the in-package README and then run pnpm sync:adapter-docs.

@zhin.js/adapter-wecom

Zhin.js WeCom (Enterprise WeChat) adapter (Plugin Runtime). Sends and receives messages via the Runtime Host HTTP Webhook.

Features

  • Webhook event reception (httpHostToken GET signature verification + decryption + POST messages)
  • AES-256-CBC message encryption/decryption with SHA1 signature verification
  • Automatic Access Token refresh
  • Convention-based defineAdapter / definePlugin (no usePlugin needed)

Installation

bash
pnpm add @zhin.js/adapter-wecom

Plugin Runtime

  • @zhin.js/adapter — convention-based adapters/wecom.ts (defineAdapter)
  • @zhin.js/coremessageGatewayToken inbound/outbound
  • @zhin.js/host-httphttpHostToken registers Webhook route (not legacy host-router/Koa)
  • @zhin.js/plugin-runtimeplugin.ts (definePlugin)
  • Configuration goes to plugins.<instanceKey> via the plugin's schema.json

Inbound: gateway.receive({ adapter, target: FromUserName, content: text, sender, metadata }) Outbound: send({ target, payload }) -> WeCom message/send API

Inbound metadata.mentioned: not wired. The XML event in WeCom application message callbacks does not contain mentions/@ fields. The ToUserName in the callback is the CorpID (Enterprise ID) rather than a comparable bot user id, and the configuration does not contain a bot id/name that can serve as a reliable basis for comparison, so @ bot detection is not reliably possible.

Prerequisites

WeCom Admin Console Configuration

  1. Log in to the WeCom Admin Console
  2. "App Management" -> "Self-built" -> Create an application, obtain CorpId, AgentId, Secret
  3. "Receive Messages" settings:
    • URL: https://yourdomain.com/wecom/callback
    • Token / EncodingAESKey must match the configuration
  4. The Runtime Host (http) must already be listening for the Webhook to be reachable

Required fields (endpoints[i]): name, corpId, agentSecret, token, encodingAESKey.

Minimal Configuration

yaml
# zhin.config.yml (Plugin Runtime)
plugins:
  wecom:
    webhookPath: /wecom/callback       # optional, default /wecom/callback
    apiBaseUrl: https://qyapi.weixin.qq.com  # optional
    endpoints:
      - name: wecom-bot
        corpId: ${WECOM_CORP_ID}
        agentSecret: ${WECOM_AGENT_SECRET}
        token: ${WECOM_TOKEN}
        encodingAESKey: ${WECOM_AES_KEY}

The root plugin zhin.plugins (or project graph) must reference @zhin.js/adapter-wecom (instanceKey: wecom).

Environment Variables

VariableDescription
WECOM_CORP_IDEnterprise ID
WECOM_AGENT_SECRETApplication Secret
WECOM_TOKENCallback signature Token
WECOM_AES_KEYEncodingAESKey (43 characters)

Message Type Support

Inbound TypeContent Summary
textOriginal text
image[image: url]
voiceRecognition result or [voice]
video / shortvideo[video]
location[location] ...
link[link: ...]
event[event] ...
Outbound WireDescription
textSupports <@userid>
imageRequires media_id
markdownWeCom native Markdown
newsLink segment mapping

Security Notes

WeCom callbacks are always encrypted:

  • Signature: SHA1 sorted concatenation of [token, timestamp, nonce, encrypt]
  • Decryption: AES-256-CBC (Key = Base64 of encodingAESKey + =, IV = first 16 bytes of Key)

Access Token is automatically refreshed 5 minutes before expiration.

Troubleshooting

SymptomInvestigation
URL verification failuretoken / encodingAESKey / corpId must match the admin console; Host must be listening and publicly accessible
Not receiving messagesApplication must have message reception enabled; sender must be in the visible range; endpoint must have called open()
Send failurecorpId + agentSecret must be able to obtain a token; recipient must be in the visible range

AI Tools

CategoryPath
Permit vocabularyagent/PERMITS.md
Platform tools (4)agent/tools/
Skill documentationagent/skills/wecom.md

Platform Permissions (platform permit)

plugin.ts registers the src/platform-permit.ts checker during generation setup and unregisters on dispose; CapabilityIngress and ToolSystem uniformly consume tool permissions via Core's canAccessTool().

License

MIT License