@openhermit/channel-wechat
v0.7.0
Published
OpenHermit channel plugin for personal WeChat (Weixin) via Tencent iLink. Text, full media in both directions: inbound images/voice/file/video and outbound images/video/files (outbound voice gated; iLink drops it).
Downloads
33
Maintainers
Readme
WeChat Channel Adapter
@openhermit/channel-wechat connects a personal WeChat (Weixin) bot to a
gateway-managed OpenHermit agent over Tencent's iLink HTTP protocol.
Scope
- Text inbound and outbound.
- Inbound images: photos are downloaded from the WeChat C2C CDN and
AES-128-ECB decrypted, then uploaded to the agent as attachments (images
become vision input). Attachments over the 25 MiB cap are skipped. The CDN
base defaults to
https://novac2c.cdn.weixin.qq.com/c2c, overridable viaOPENHERMIT_WECHAT_CDN_BASE_URL; a server-providedfull_urlis preferred. - Inbound voice: WeChat usually pre-transcribes voice notes and ships the
text in
voice_item.text, which is used directly (prefixed with a[Voice message, transcribed.]marker). If a SILK clip arrives without a transcript it is downloaded, decrypted, transcoded to WAV viasilk-wasm, and sent through the agent's STT; non-SILK codecs are skipped. - Outbound voice (DM replies, off by default): set
OPENHERMIT_WECHAT_VOICE_REPLY=1to enable. When on, a reply to a voice note is synthesized via TTS as Ogg/Opus @ 48 kHz (audio/ogg), uploaded to the WeChat C2C CDN, and sent as a voice item (encode_type: 8). ⚠️ Known limitation: iLink silently drops bot→user VOICE messages — the send is accepted (ret=0) but the WeChat client never renders it (confirmed live for both SILK and Ogg/Opus; documented by reverse-engineered iLink SDKs). The code path is kept for a possible future iLink change / QQ reuse, but voice replies do not currently reach the user, which is why it is disabled by default. With it off, voice notes are transcribed inbound and answered with text. - Outbound media (agent → user): attachments the agent emits (
attachmentevents) are downloaded, encrypted, uploaded to the WeChat C2C CDN, and sent as the matching item — images (image_item), video (video_item), or any other file as a file attachment (file_item). Unlike voice, iLink delivers these. Outbound media over 8 MiB is skipped (the CDN upload link is slow); an optional caption is sent as a leading text item. - Inbound file / video: documents and videos a user sends are downloaded
from the CDN, AES-128-ECB decrypted, and uploaded to the agent as session
attachments (the file keeps its original name; video is
video.mp4). Over the 25 MiB cap they are skipped. - QR-link wizard (
ChannelSetup) returns the QR URL as a plain string; the admin UI renders it with its own QR-code library. - No typing indicators, no multi-account juggling.
The CDN download + AES decryption is ported from Tencent's MIT-licensed
openclaw-weixin (see the
header in src/ilink/media.ts).
Loading the plugin
This package is not bundled into the gateway by default. Add it to the gateway config:
{
"channelPackages": ["@openhermit/channel-wechat"]
}On gateway boot the plugin loader picks it up via dynamic import and
registers the wechat channel manifest with the runtime registry as
an external origin — so unlike telegram / slack / discord, no
row is auto-seeded into agent_channels on agent create. Owners add
WeChat on demand from the UI's "Add channel" picker.
Linking a bot
- In
/manage/channels(web) or/admin/channels(gateway admin), click Add channel → pick WeChat. - The wizard renders a QR code (
qrTextcarries the URL). - Open WeChat on your phone, scan the QR, confirm on phone. On
confirmation the gateway persists the
agent_channelsrow and the channel comes online.
Stored config
After setup, the agent_channels.config row carries:
| key | value |
|-----------------|---------------------------------------------|
| bot_token | iLink bot token |
| base_url | IDC-redirected per-bot base URL |
| ilink_bot_id | server-issued bot id (diagnostics) |
| ilink_user_id | scanner's iLink user id (optional) |
| bot_agent | optional override for the User-Agent-style header |
iLink-App-Id
Tencent's iLink protocol carries an iLink-App-Id header read from
this package's own package.json (ilink_appid). Operators running
their own iLink app should either:
- patch the
ilink_appidfield inpackage.json, or - set the
OPENHERMIT_WECHAT_APP_IDenv var on the gateway process.
The default empty value works against Tencent's public iLink endpoints for testing only.
