Skip to content

fix(dashboard): display WeChat QR code for iLink login#1572

Merged
houko merged 18 commits into
mainfrom
fix/wechat-qr-display
Mar 24, 2026
Merged

fix(dashboard): display WeChat QR code for iLink login#1572
houko merged 18 commits into
mainfrom
fix/wechat-qr-display

Conversation

@houko

@houko houko commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • WeChat QR login fix: Use iLink's qrcode_img_content (full URL) to generate the QR code instead of the raw token string, so WeChat can properly recognise the scan
  • WeChat message delivery fix: Add missing from_user_id, client_id, and base_info fields to iLink sendmessage request — without these iLink returns 200 OK but silently drops the message
  • WeChat token save fix: Frontend sent bot_token but backend field is bot_token_env, causing token not to persist after QR login
  • WeChat startup fix: Skip adapter start when no token is available, preventing QR login from blocking the entire server
  • iLink long-poll fix: Increase QR status timeout from 10s to 35s for iLink's long-polling design
  • Agents path fix: All agent template paths now use ~/.librefang/workspaces/agents instead of ~/.librefang/agents
  • Vite dev server: Set allowedHosts to true to allow all hosts (supports Cloudflare Tunnel and custom domain access)
  • Auto-install deps: just dash and just api now run pnpm install before starting
  • Daemon logging: Write logs to ~/.librefang/daemon.log in addition to stderr
  • i18n: Add missing common.retry and AnyEnvVar requirement type

WeChat QR Login

Scan the QR code with a WeChat account bound to a +86 phone number. After successful login, the bot token is saved to ~/.librefang/secrets.env and the adapter will use it on subsequent restarts without requiring another scan.

How to use

  1. Open the dashboard Channels page
  2. Click "Configure" on the WeChat card
  3. Scan the QR code with your WeChat app
  4. After login succeeds, the token is saved automatically
  5. Send a message to ClawBot in WeChat — it will reply via the configured agent
wechat

Test plan

  • QR code displays correctly in dashboard (uses full URL, not raw token)
  • Scanning with +86 WeChat completes login flow
  • Token persists to secrets.env after successful scan
  • Bot receives messages and replies to WeChat
  • Accessing dashboard via Cloudflare Tunnel custom domain works
  • just dash / just api auto-install dependencies
  • Agent template resolution works from workspaces/agents path

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Jengro777

Copy link
Copy Markdown
Contributor

I hope to release a lastest version today after this merger

@houko

houko commented Mar 24, 2026

Copy link
Copy Markdown
Contributor Author

I hope to release a lastest version today after this merger

yeah, I will release a new version after ci all passed.

@houko
houko force-pushed the fix/wechat-qr-display branch from 20fdf4d to 0100404 Compare March 24, 2026 10:45
Add /api/channels/wechat/qr/start and /qr/status endpoints that proxy
to the iLink API, mirroring the existing WhatsApp QR pattern.

On the dashboard, channels with setup_type "qr" now open a QR login
dialog instead of the config form. The dialog renders the QR code via
the qrcode npm package, polls for scan confirmation, and auto-saves
the bot_token on success.

Closes #1560
@houko
houko force-pushed the fix/wechat-qr-display branch from 0100404 to 010a8c3 Compare March 24, 2026 10:47
split_whitespace() already handles leading/trailing whitespace,
so the preceding trim() call is unnecessary.
@github-actions github-actions Bot added the area/kernel Core kernel (scheduling, RBAC, workflows) label Mar 24, 2026
@github-actions github-actions Bot added the area/ci CI/CD and build tooling label Mar 24, 2026
@github-actions github-actions Bot added the area/runtime Agent loop, LLM drivers, WASM sandbox label Mar 24, 2026
houko added 4 commits March 24, 2026 23:01
The test was failing on CI because ~/.librefang doesn't exist on
runners. Filter "does not exist" warnings alongside the existing
"is not set" filter since both are environment-dependent, not structural.
…blocking

- Fix QR login token not saving: frontend sent `bot_token` but backend expects `bot_token_env`
- Fix agents directory: all paths now use `~/.librefang/workspaces/agents` instead of `~/.librefang/agents`
- Fix iLink QR status timeout: increase to 35s for long-poll, treat timeout as "waiting"
- Fix WeChat adapter blocking server startup when no token available
- Add `AnyEnvVar` variant to `RequirementType` enum for HAND.toml compatibility
- Write daemon logs to `~/.librefang/daemon.log` in addition to stderr
…lient_id, base_info)

iLink sendmessage requires from_user_id (empty string), client_id (random UUID),
and base_info.channel_version to deliver messages. Without these fields iLink
returns 200 OK but silently drops the message.
@github-actions github-actions Bot added the area/channels Messaging channel adapters label Mar 24, 2026
@houko
houko merged commit 3868b23 into main Mar 24, 2026
9 checks passed
@houko
houko deleted the fix/wechat-qr-display branch March 24, 2026 15:27
houko pushed a commit that referenced this pull request Jun 11, 2026
The WeChat sidecar's QR login encoded the iLink `qrcode` field into the dashboard QR canvas.
But `qrcode` is only the opaque status-poll key — the payload the WeChat app decodes on scan is `qrcode_img_content`.
Encoding the poll token makes WeChat render the QR as a plain-text string rather than a login prompt.

The pre-migration in-process Rust adapter surfaced `qrcode_img_content` as the QR payload (the original #1560 / #1572 fix: "use iLink qr_url so WeChat can recognise the scan").
The sidecar migration (#5421) dropped that field and fell back to encoding the token, re-introducing the exact bug #1572 had fixed.

`_qr_login` now reads `qrcode_img_content` and emits it as the `qr_ready` payload, falling back to the token with a WARN only if iLink omits the field; the `qrcode` token still drives status polling.

Tests: updated the happy-path assertion to require `qrcode_img_content`, added a degraded-fallback case; full sdk/python suite 1874 passed.
houko added a commit that referenced this pull request Jun 11, 2026
…annable (#6086)

* fix(channels/wechat): encode qrcode_img_content so the QR is scannable

The WeChat sidecar's QR login encoded the iLink `qrcode` field into the dashboard QR canvas.
But `qrcode` is only the opaque status-poll key — the payload the WeChat app decodes on scan is `qrcode_img_content`.
Encoding the poll token makes WeChat render the QR as a plain-text string rather than a login prompt.

The pre-migration in-process Rust adapter surfaced `qrcode_img_content` as the QR payload (the original #1560 / #1572 fix: "use iLink qr_url so WeChat can recognise the scan").
The sidecar migration (#5421) dropped that field and fell back to encoding the token, re-introducing the exact bug #1572 had fixed.

`_qr_login` now reads `qrcode_img_content` and emits it as the `qr_ready` payload, falling back to the token with a WARN only if iLink omits the field; the `qrcode` token still drives status polling.

Tests: updated the happy-path assertion to require `qrcode_img_content`, added a degraded-fallback case; full sdk/python suite 1874 passed.

* test(channels/wechat): add qrcode_img_content to unrelated QR test mocks

Three tests that exercise different failure/edge paths all used a mock
iLink response without `qrcode_img_content`, causing the fallback WARN
introduced alongside the fix to fire spuriously on every run.
Each affected test now uses a realistic response that matches the happy
path, so the warning stays silent unless the field is genuinely absent.

---------

Co-authored-by: Evan <[email protected]>
Co-authored-by: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/channels Messaging channel adapters area/ci CI/CD and build tooling area/kernel Core kernel (scheduling, RBAC, workflows) area/runtime Agent loop, LLM drivers, WASM sandbox

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants