{"record":{"id":"cf429e29881031d0","repo":"jackwener/OpenCLI","slug":"mp-weixin-qq-com","errorCode":null,"errorMessage":"微信公众号草稿箱需要已登录的 mp.weixin.qq.com 会话","messagePattern":"微信公众号草稿箱需要已登录的 mp\\.weixin\\.qq\\.com 会话","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/weixin/drafts.js","lineNumber":26,"sourceCode":"    name: 'drafts',\n    access: 'read',\n    description: '列出微信公众号草稿箱',\n    domain: WEIXIN_DOMAIN,\n    strategy: Strategy.COOKIE,\n    browser: true,\n    navigateBefore: false,\n    args: [\n        { name: 'limit', type: 'int', default: 10, help: '最多显示条数' },\n        { name: 'timeout', type: 'int', required: false, default: 60, help: 'Max seconds for the overall command (default: 60)' },\n    ],\n    columns: ['Index', 'Title', 'Time'],\n\n    func: async (page, kwargs) => {\n        await page.goto('https://mp.weixin.qq.com/');\n        await page.wait(3);\n        const token = await page.evaluate(`(window.location.href.match(/token=(\\\\d+)/)||[])[1]`);\n        if (!token) {\n            throw new AuthRequiredError(WEIXIN_DOMAIN, '微信公众号草稿箱需要已登录的 mp.weixin.qq.com 会话');\n        }\n\n        await page.goto(`https://mp.weixin.qq.com/cgi-bin/appmsg?begin=0&count=${kwargs.limit}&type=77&action=list_card&token=${token}&lang=zh_CN`);\n        await page.wait(4);\n\n        const drafts = await page.evaluate(`(() => {\n            var results = [];\n            var idx = 0;\n\n            var cards = document.querySelectorAll('.weui-desktop-card');\n            for (var i = 0; i < cards.length; i++) {\n                if (cards[i].className.includes('card_new')) continue;\n                var titleEl = cards[i].querySelector('[class*=title]');\n                var timeEl = cards[i].querySelector('[class*=tips]');\n                var title = titleEl ? titleEl.textContent.trim() : '';\n                var time = timeEl ? timeEl.textContent.trim().replace(/\\\\s+/g, ' ') : '';\n                if (title) results.push({ Index: ++idx, Title: title, Time: time });\n            }","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weixin/drafts.js#L8-L44","documentation":"The `weixin drafts` command opens mp.weixin.qq.com and extracts the token=... parameter from the URL after page load. If no token is present in the final URL, the user does not have an active logged-in mp.weixin.qq.com session, so the command throws AuthRequiredError (code AUTH_REQUIRED, exit code 77) naming the WeChat mp domain. This guard exists because the drafts API endpoint only works with a session that already carries valid login cookies.","triggerScenarios":"Running `opencli weixin drafts` when the connected Chrome/Chromium profile has no logged-in mp.weixin.qq.com session: cookies expired, the account logged out, login scan on WeChat app was never done, or the page redirected to a login/QR-code page so window.location has no token= digits.","commonSituations":"WeChat Official Account sessions expire after a few days of inactivity; the browser profile was cleared of cookies; the automation connects a fresh profile that was never logged in; WeChat forces re-scan QR login after security policy updates.","solutions":["Open Chrome/Chromium with the profile used by opencli and log in to mp.weixin.qq.com (scan QR code in the WeChat app)","Re-run `opencli weixin drafts` after login so the token is present in the URL","If you keep hitting this, avoid clearing cookies for that browser profile and re-login whenever WeChat expires the session"],"exampleFix":"// before\nnpx opencli weixin drafts  // fails: no mp session\n// after\n// 1) open browser, log in to https://mp.weixin.qq.com (scan QR)\n// 2) retry\nnpx opencli weixin drafts","handlingStrategy":"try-catch","validationCode":"// probe for a live session before calling drafts\ntry { await run(['weixin', 'drafts']); } catch (e) {\n  if (e instanceof CliError && e.code === 'AUTH_REQUIRED') {\n    console.log('Log in to https://mp.weixin.qq.com in the browser first');\n  }\n}","typeGuard":"function isAuthRequired(e) { return e instanceof CliError && e.code === 'AUTH_REQUIRED' && e.exitCode === 77; }","tryCatchPattern":"try {\n  const drafts = await run(['weixin', 'drafts']);\n} catch (e) {\n  if (e instanceof CliError && e.code === 'AUTH_REQUIRED') {\n    // open Chrome, log in to mp.weixin.qq.com (QR scan), then retry once\n  } else throw e;\n}","preventionTips":["Periodically re-login to mp.weixin.qq.com; WeChat sessions expire after inactivity","Do not clear cookies for the browser profile opencli uses","Check for AuthRequiredError (exit code 77) in scripts and trigger a re-login flow automatically","Avoid running drafts commands against a fresh/never-logged-in browser profile"],"tags":["auth","weixin","session-expired"],"backgroundTag":"auth-required-login-expired","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}