WeChat iLink Backend Runbook
Use this runbook when the production WeChat surface stops receiving or sending messages. WeChat is connected exclusively through the native iLink provider in the Spectrum bridge. There is no desktop WeChat client or companion agent service in the supported architecture.
Architecture
The bridge registers wechat-ilink-photon-sdk when WECHAT_BRIDGE_ENABLED=1. The provider polls iLink, claims inbound messages and the sync cursor atomically in Postgres, and emits claimed messages into the shared Photon routing pipeline. Outbound and recovered sends use the live iLink runtime and the durable per-recipient context token.
The relevant operational tables are:
wechat_ilink_credentials: active scanner sessions and sync cursors.wechat_inbound_ledger: claimed inbound-message ledger and dispatch state.wechat_context_tokens: durable recipient send context.wechat_ilink_outbound_receipts: send-attempt reconciliation receipts.
Do not delete credential, cursor, ledger, token, or receipt rows as routine recovery. Do not reset the cursor unless you have confirmed that replaying from the server's fresh position is safe.
Required configuration
WECHAT_BRIDGE_ENABLED=1
WECHAT_LINE_REF=wechat
Optional tuning:
WECHAT_ILINK_SHADOW=0
WECHAT_ILINK_STALENESS_MS=180000
WECHAT_SEND_PACING_MS=700
The line ref must match the deployed WeChat routing metadata. A WeChat-only bridge should also set IMESSAGE_BRIDGE_ENABLED=0.
Inspect session status
Run the operator CLI with DATABASE_URL pointed at the target database and the same WECHAT_LINE_REF as the bridge:
npx tsx scripts/wechat-ilink-login.ts --status
A healthy line has at least one active credential. The status output shows each session key, account, user, endpoint, and whether a cursor is present. Never paste bot tokens, database URLs, or project secrets into tickets or logs.
Log triage
Inspect the WeChat bridge logs and confirm:
1. The provider registered and acquired the line-scoped exclusive lock. 2. Credentials were loaded for the expected WECHAT_LINE_REF. 3. Polling advances without repeated authentication or protocol errors. 4. Claimed inbound messages reach [spectrum-bridge] inbound processing. 5. Outbound sends complete without non-zero iLink return codes.
Repeated lock-wait messages normally indicate two bridge replicas are trying to own the same line. Scale back to one owner or correct the duplicate line-ref configuration before restarting anything.
Restore or add a scanner session
The login CLI persists a confirmed QR session directly to Postgres. A running bridge discovers it without a redeploy:
npx tsx scripts/wechat-ilink-login.ts
Scan the displayed QR code with WeChat. Then rerun --status and watch bridge logs for credential pickup. Multiple confirmed scanners may coexist; login adds or refreshes the session keyed to the scanning user.
Cursor recovery
Resetting the cursor is a last resort for a cursor rejected by iLink after credentials and connectivity have been verified. First stop or scale down the bridge that owns the line, record current status and relevant logs, and confirm that the inbound ledger will safely deduplicate any messages returned again.
npx tsx scripts/wechat-ilink-login.ts --reset-cursor
Restart one bridge owner and verify that polling resumes. The reset clears only the active credential cursors for the selected line; it does not delete the inbound ledger or context tokens.
End-to-end verification
After recovery:
1. Send a new DM to the iLink bot and confirm exactly one inbound ledger claim. 2. Confirm the message routes to the intended deployment and character. 3. Confirm one response arrives in WeChat, including typing where supported. 4. Exercise one media response if the incident affected attachments. 5. Restart the bridge and verify queued outbound recovery can reconstruct the recipient from the durable context token. 6. Run --status again and confirm the expected session and cursor remain.
If inbound claims succeed but routing fails, debug deployment metadata and the shared Photon pipeline. If routing succeeds but sends fail, inspect context-token and outbound-receipt state before changing credentials.