Developer Guide · 07

WeChat Integration

Full iLink protocol details, CDN encryption/decryption, and gotcha notes: see docs/wechat-integration-guide.md.

7.1 Dual-Stack Architecture

text
┌──────────────────────────────────────────────────────────┐
│  Service Channel               │  Admin Self-onboarding  │
├────────────────────────────────┼─────────────────────────┤
│  /api/wc/*                     │  /api/admin/wechat/*    │
│  router.py                     │  admin_router.py         │
│  bridge.py                     │  admin_bridge.py         │
│  Consumer Agent (channel=wechat│  Admin Agent             │
│  Convos in service/conversations│  Convos in admin convos │
│  Sessions in wechat_sessions.json│  admin_wechat_session. │
│  Permissions per service caps  │  Full docs/scripts perms │
└────────────────────────────────┴─────────────────────────┘
Shared: client.py / media.py / delivery.py / rate_limiter.py

7.2 Key Modules

ModuleResponsibility
client.pyiLink protocol: getconfig / getupdates / sendmessage / getuploadurl / cdn upload/download
bridge.pyService Bridge: message routing + multimodal construction + send_message interception + auto-approve HITL
admin_bridge.pyAdmin Bridge: full permissions + inline send_message handling
session_manager.pySession lifecycle + persistence + reconnection (exponential backoff)
media.pyAES-128-ECB encryption/decryption + CDN upload/download
delivery.pyUnified delivery (with <<FILE:>> tag parsing)
rate_limiter.pyPer-user 10/60s + QR 5/60s + global session limit
router.py / admin_router.pyHTTP API endpoints

7.3 Multimedia Delivery

DirectionFlow
Receive imageCDN GET → AES decrypt → base64 multimodal → Agent Vision
Send imagegetuploadurl → AES encrypt → CDN POST → sendmessage(image_item.media)
Receive voiceCDN GET → AES decrypt → SILK→WAV (pysilk) → Whisper transcription
Send TTSMP3 under /generated/audio/ sent as file attachment via send_file

Voice message (voice_item) approach suspended: pysilk-encoded SILK always silent in WeChat client at 24kHz/16kHz. Under further investigation.

7.4 <<FILE:>> Tag Parsing

delivery.py::extract_media_tags(text) -> (cleaned_text, [paths]):

python
_MEDIA_TAG_RE = re.compile(r"<<FILE:([^>]+?)>>")
  • Actively extracts <<FILE:path>> tags from send_message text, converts to additional media delivery
  • Remaining cleaned_text is sent as text
  • Supports both media_path parameter and <<FILE:>> tag usage
  • Bridge and Scheduler share this module, avoiding code duplication

7.5 Session Management Key Points

  • Exponential backoff reconnect (auto-removes after 20 failures)
  • Sessions with from_user_id don't participate in 24h idle cleanup (long-term retention)
  • Sessions without from_user_id (empty sessions) are cleaned based on inactivity
  • Empty polling only discards "not-yet-established" sessions after 50 attempts
  • Multi-Admin isolation: list_sessions / remove_session filter by admin_id

7.6 Admin Self-Onboarding

  • Endpoints: POST /api/admin/wechat/qrcode / GET qrcode/status / GET/DELETE session / GET messages
  • Session persistence: users/{user_id}/admin_wechat_session.json, auto-restored after Docker/restart
  • _save_admin_session() writes on session creation, first from_user_id capture, context_token update
  • restore_admin_sessions() called on main.py startup
  • shutdown_admin_sessions() only stops polling/closes connections, does not delete persistence file