Skip to content

WEIXIN CHANNEL: get_qrcode_status still missing iLink-App-Id header causes login failure (v0.14.2) #3036

@dorokuma

Description

@dorokuma

WEIXIN CHANNEL: get_qrcode_status still missing iLink-App-Id header causes login failure (v0.14.2)

Summary

PR #2943 fixed the missing headers in buildHeaders() (api.ts), but the QR code login flow in waitForLogin() (login.ts) still sends incomplete headers to /ilink/bot/get_qrcode_status, causing authentication failure and inability to connect.

Affected Version

v0.14.2 (latest stable), also v0.14.1

Root Cause

PR #2943 only modified api.tsbuildHeaders(), adding iLink-App-Id and iLink-App-ClientVersion to normal API requests (getUpdates, sendMessage, getConfig).

However, the QR code login flow in login.tswaitForLogin() has its own fetch call to /ilink/bot/get_qrcode_status with a hardcoded header object that was NOT updated by PR #2943:

// packages/channels/weixin/src/login.ts — waitForLogin()
const resp = await fetch(`${apiBaseUrl}/ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(currentQrcodeId)}`, {
    headers: { "iLink-App-ClientVersion": "1" },  // WRONG: missing "iLink-App-Id": "bot"
    signal: controller.signal
});

Additionally, "iLink-App-ClientVersion": "1" is incorrect. It should use the same buildClientVersion(ILINK_PROTOCOL_VERSION) as buildHeaders() to produce the proper encoded version number (e.g., 131331 for version 2.0.0).

Symptoms

  1. Run qwen channel configure-weixin
  2. Scan QR code with WeChat and confirm
  3. The waitForLogin poll loop fails silently (HTTP error or empty response)
  4. account.json is never generated
  5. Service cannot start with error: WeChat account not configured

Even if you manually create account.json, the service starts but the poll loop immediately returns errcode: -14 (session timeout) because the same missing headers affect downstream API calls.

Complete Fix

Two locations need to be fixed:

Fix 1: login.tswaitForLogin() headers (THIS IS STILL BROKEN)

// BEFORE (current v0.14.2):
const resp = await fetch(`${apiBaseUrl}/ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(currentQrcodeId)}`, {
    headers: { "iLink-App-ClientVersion": "1" },
    signal: controller.signal
});

// AFTER:
const resp = await fetch(`${apiBaseUrl}/ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(currentQrcodeId)}`, {
    headers: {
        "iLink-App-Id": "bot",
        "iLink-App-ClientVersion": String(buildClientVersion(ILINK_PROTOCOL_VERSION))
    },
    signal: controller.signal
});

Fix 2: api.tsbuildHeaders() (already fixed in PR #2943, no action needed)

function buildHeaders(token?: string) {
  const headers = {
    "Content-Type": "application/json",
    "X-WECHAT-UIN": randomUin(),
    "iLink-App-Id": "bot",
    "iLink-App-ClientVersion": String(buildClientVersion(ILINK_PROTOCOL_VERSION))
  };
  if (token) {
    headers["AuthorizationType"] = "ilink_bot_token";
    headers["Authorization"] = `Bearer ${token}`;
  }
  return headers;
}

Verification

After applying Fix 1, the full login flow works:

  1. qwen channel configure-weixin → QR code generated
  2. Scan + confirm in WeChat → waitForLogin successfully gets bot_token
  3. account.json generated with valid token
  4. qwen channel start my-weixin → Connected, poll loop running normally

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions