Skip to content

feat(gateway): add WeChat adapter with iLink 2.1.x protocol#2502

Closed
linxule wants to merge 3 commits into
NousResearch:mainfrom
linxule:feature/weixin-platform
Closed

feat(gateway): add WeChat adapter with iLink 2.1.x protocol#2502
linxule wants to merge 3 commits into
NousResearch:mainfrom
linxule:feature/weixin-platform

Conversation

@linxule

@linxule linxule commented Mar 22, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds WeChat as a supported messaging platform for the Hermes gateway, implementing the iLink Bot API protocol from the @tencent-weixin/openclaw-weixin SDK 2.1.7. No external SDK dependency — pure Python port with SDK 2.1.7 protocol compliance.

This is a complete rewrite of the original weixin adapter submission (March 22), upgraded to match the current SDK protocol, renamed for codebase consistency (weixinwechat), and restructured into a clean 3-file architecture.

Related Issue

N/A — new platform adapter.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

Core adapter (3-file architecture)

  • gateway/platforms/wechat.py (~870 lines) — adapter lifecycle, message routing, media handling
  • gateway/platforms/wechat_transport.py (~465 lines) — HTTP transport, CDN upload/download, AES-128-ECB crypto
  • gateway/platforms/wechat_state.py (~105 lines) — context token and sync buffer disk persistence

Protocol compliance (openclaw-weixin SDK 2.1.7)

  • iLink-App-Id + iLink-App-ClientVersion headers on all API requests
  • IDC redirect (scaned_but_redirect) in QR login flow
  • Context token reload from disk at startup (survive gateway restarts)
  • Context token clear on session expiry (errcode -14)
  • Referenced message (ref_msg) extraction for quoted replies
  • SILK voice transcoding with graceful fallback
  • CDN upload with upload_full_url priority + exponential backoff
  • CDN download with full_url forward-compatibility
  • Dynamic channel_version (not hardcoded)
  • File len field uses plaintext size (not ciphertext — matches SDK)

Platform integration (all 16 checklist items from ADDING_A_PLATFORM.md)

  • gateway/config.pyPlatform.WECHAT enum, env overrides, connection check
  • gateway/run.py — adapter factory, auth maps, update-allowed set
  • toolsets.pyhermes-wechat toolset + gateway composite
  • tools/send_message_tool.py — platform routing + standalone _send_wechat()
  • hermes_cli/gateway.py — setup wizard entry
  • hermes_cli/config.py — WECHAT env vars in _EXTRA_ENV_KEYS
  • hermes_cli/tools_config.py, skills_config.py, status.py
  • cron/scheduler.py, gateway/channel_directory.py
  • tools/cronjob_tools.py, agent/prompt_builder.py

Login script

  • scripts/wechat_login.py — QR login with iLink headers, IDC redirect handling, auto-refresh

Tests

  • tests/gateway/test_wechat.py — 85 tests covering adapter, transport, state, protocol compliance, and source-level registration assertions

Documentation

  • website/docs/user-guide/messaging/wechat.md — full setup guide with env vars, feature matrix, troubleshooting
  • Updated: messaging/index.md, environment-variables.md, sidebars.ts, README.md, AGENTS.md

How to Test

  1. Install dependencies: httpx and cryptography (both already in Hermes [all] extras)
  2. Run tests: python -m pytest tests/gateway/test_wechat.py -v (85 tests, all passing)
  3. Set up credentials: python scripts/wechat_login.py (scan QR with WeChat)
  4. Export WECHAT_BOT_TOKEN and WECHAT_ACCOUNT_ID from login output
  5. hermes gateway start — verify WeChat adapter connects
  6. Send a text message from WeChat — verify bot receives and responds

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: Raspberry Pi OS (aarch64), macOS 15.4

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings)
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A (env-var-only config)
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

Known Limitations

  • Single-account design: Supports one WeChat account per gateway instance (multi-account would require per-account transport pooling — documented, not a blocker)
  • SILK voice transcoding: Requires ffmpeg and silk-v3-decoder on PATH for native voice bubble playback; falls back to file attachment delivery when unavailable
  • Standalone send race window: _send_wechat() in send_message_tool starts a poll loop during connect/disconnect — consistent with the WeCom adapter pattern but creates a brief race window with the main gateway's poll loop

Acknowledgments

This adapter was developed collaboratively:

  • Protocol port, gateway integration, and multi-round code review by Claude (Anthropic)
  • Test suite (85 tests), registration files, and verification review by Codex (OpenAI)
  • Architecture decisions, SDK analysis, live testing, and project direction by @linxule

🤖 Generated with Claude Code

@linxule linxule force-pushed the feature/weixin-platform branch from a8cd652 to 2eae331 Compare March 24, 2026 18:53
linxule and others added 3 commits April 8, 2026 05:03
…support

3-file architecture (adapter/transport/state) implementing the iLink Bot
API protocol from openclaw-weixin SDK 2.1.7:

- iLink-App-Id + iLink-App-ClientVersion headers on all API requests
- IDC redirect (scaned_but_redirect) in QR login flow
- Context token persistence with reload at startup and clear on session expiry
- Referenced message (ref_msg) extraction for quoted replies
- SILK voice transcoding with graceful fallback
- CDN upload with upload_full_url priority and exponential backoff
- CDN download with full_url forward-compatibility
- Dynamic channel_version (not hardcoded)
- AES-128-ECB media encryption with dual key format support

Full platform integration: enum, env overrides, adapter factory, auth maps,
toolsets, CLI setup wizard, status display, cron delivery, send_message tool,
channel directory, prompt hints, env sanitizer keys, and login script.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comprehensive coverage of adapter, transport, and state modules:
- Platform enum and config loading from env vars
- iLink header encoding and presence verification
- AES-128-ECB encrypt/decrypt round-trip with key parsing
- Context token persistence (save/load/clear lifecycle)
- Sync buffer persistence
- Inbound message extraction (text, voice, media, ref_msg)
- Media selection priority and CDN upload size guard
- Markdown stripping, dedup, typing ticket TTL
- Send behavior (context tokens, chunking, self-message filtering)
- Source-level registration assertions (config, run, toolsets)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: OpenAI Codex <noreply@openai.com>
- New: website/docs/user-guide/messaging/wechat.md (full setup guide with
  env vars, feature matrix, architecture overview, troubleshooting)
- Update messaging index with WeChat in architecture diagram, toolset
  table, and platform links
- Add WECHAT_* env vars to environment-variables.md reference
- Add WeChat to README.md platform mentions and AGENTS.md directory listing
- Add wechat to website sidebar navigation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: OpenAI Codex <noreply@openai.com>
@linxule linxule force-pushed the feature/weixin-platform branch from 2eae331 to 6fb5307 Compare April 8, 2026 04:04
@linxule linxule changed the title Add Weixin (WeChat) platform adapter to the Hermes gateway feat(gateway): add WeChat adapter with iLink 2.1.x protocol Apr 8, 2026
@linxule

linxule commented Apr 10, 2026

Copy link
Copy Markdown
Contributor Author

Closing — WeChat support landed via #7166. Glad to see the feature ship. Will help test on Pi.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant