每天自动完成两件事:Buddy 加油站签到 + 派猫猫去旅行。
⏰ 几点跑,你说了算。 这两个脚本是纯手动触发的,里面没有任何定时逻辑 —— 执行时间完全由你在 WorkBuddy 桌面端的「自动化」里自己设置 —— 想几点就几点,一天几次也行。 仓库不规定、也不附带任何默认时间。
| 步骤 | 脚本 | 原理 | 稳定性 |
|---|---|---|---|
| ① 加油站签到 | wb_checkin.js --checkin |
复用常驻 Edge(专用 profile)里已登录的 www.workbuddy.cn 页面,同源 fetch 调官方签到接口;不读、不打印任何 token | 稳定,幂等;登录态由每日运行自己维持 |
| ② 派猫猫旅行 | wb_auto_task.js |
Playwright 驱动 Edge(专用 profile)点击成长中心的「派猫猫旅行」 | v4 起整流程自带最多 3 轮重试,一次运行即吸收 SPA 抖动 |
不用你记命令、也不用手动配调度。把这段话直接甩给 WorkBuddy:
帮我安装 WorkBuddy Daily:https://gitee.com/strange_touchannel/workbuddy-daily 按仓库里的 INSTALL.md 执行。装好后把每日签到(
wb_checkin.js --checkin) 和自动派猫(wb_auto_task.js)设为定时自动化任务,每天到点自己跑。它会替你完成:装依赖 → 拉起登录窗等你扫码 → 建自动化任务。 你唯一要自己做的事,是在自动弹出的 Edge 窗口里登录一次(微信扫码或账号密码,以页面为准)—— 这是唯一没法代劳的一步,原因见下方「为什么不复用你已有的浏览器登录态」。 登录成功后永久有效,日常全自动:到点签到领积分、派猫猫去旅行。 Edge 重启/关窗导致的会话失效,后台跑一次
node wb_login_then_run.js:它会弹出登录窗等你扫码, 检测到登录成功后在同一个常驻会话里自动跑完「派猫 → 签到」,不用再手动补跑 (只想要登录窗、不跑任务时才用node wb_login_once.js --timeout=15。 桌面端令牌自 2026-09-24 起改为加密信封,独立脚本无法解密,「静默续期」路线已废弃)。时间是建自动化任务时你随口指定的(脚本本身不带定时),想改直接在桌面端的自动化列表里改, 或者跟 WorkBuddy 说一句「改成每天早上 9 点」。
详细步骤、故障兜底、给安装者 AI 的纪律都在 INSTALL.md —— 那是写给帮忙安装的 WorkBuddy 读的。
# ① 签到(--status 只查询不领取,--checkin 才真正领取)
node wb_checkin.js --checkin
# ② 派猫猫旅行(输出 JSON)
node wb_auto_task.js
# ③ 看成长任务清单还差什么(只读,无任何写操作)
node wb_tasks.js
# ④ 网页端做成长任务 + 点真实领奖按钮(默认干跑,加 --apply 才真执行)
node wb_start_edge.js && node wb_run_tasks.js --apply
# ⑤ 领活跃地图的连登里程碑奖励(默认干跑,加 --apply 才真领)
node wb_claim_rewards.js --apply不想敲命令可以双击(会自动切到脚本目录并调用正确的 node):
| 双击 | 作用 |
|---|---|
run_login.bat |
扫码登录兜底 —— 常驻 Edge 被关过(重启 / 手动关窗)导致会话失效时运行;只负责登录并让窗口保持常驻。想让扫码成功后自动把当天两步跑完,改用 node wb_login_then_run.js |
run_cat.bat |
派猫猫旅行 |
run_tasks.bat |
成长任务清单(只读) |
run_growth.bat |
成长任务:网页端点真实按钮(会先确保常驻 Edge 在跑) |
run_rewards.bat |
活跃地图连登奖励:先干跑,敲 y 才真领(会先确保常驻 Edge 在跑) |
code=0且出现credit/streak_days→ 领取成功code=10001(今天已签到)→ 幂等,无需重复,视为成功401/403或连续网络失败 → 登录态失效,后台跑node wb_login_then_run.js扫码,成功后自动补跑两步
login:true+catTravel以dispatched开头 → 派遣成功already-traveling→ 猫还在旅行中,跳过gift-claim-failed→ 礼物没领成功,本轮不会继续派遣(看giftLog定位)login:false→ 常驻 Edge 会话失效(被关过 / 重启过 / 会话 cookie 焚毁)→ 后台跑node wb_login_then_run.js,扫码成功后自动在同会话内跑完「派猫 → 签到」attempts> 1 → 首轮撞上 SPA 瞬时抖动,脚本自己重载重试后成功(note里有逐轮结果),属正常自愈attempts= 3 且仍未达成 → 三轮自愈用尽,需人工核对(罕见图)
脚本 v4 起自带重试,一天跑一次就够,不需要再叠一层「稍后补派」的定时任务。
很多人会问:脚本连我平时用的 Edge(已经登录着 WorkBuddy)不就行了,为什么还要扫码一次? 三条路都实测走不通:
- 拷贝 cookie 到独立 profile:workbuddy.cn 的会话 cookie 受 App-Bound Encryption(ABE)保护, 密钥绑定 Edge 二进制 + 机器 + profile 实例。跨 profile 移植后 ABE 层解密失败被直接丢弃 (实测 0 条可解密)。
- attach 正在运行的普通 Edge:CDP 端口必须在 Edge 启动时通过
--remote-debugging-port开启, 普通 Edge 默认不开;手动重启带端口又慢(1.7GB profile 实测 150s 都绑不上)。 - attach 桌面端 WorkBuddy:其 CDP(9222)只暴露
file://渲染页且禁用newPage,无法驱动; 桌面端 accessToken 自 2026-09-24 起改为加密信封,独立进程同样拿不到。
所以架构只能是:脚本拉起自己的专用 Edge profile,在里面原生登录一次(扫码或账密), 之后保持常驻、每日运行自己维持会话。扫码是唯一无法代劳的一步,也是一次性的。
node wb_tasks.js # 按状态分组 + 算出每个任务"还差多少"
node wb_tasks.js --all # 连已领取/未解锁的也列出
node wb_tasks.js --json # 结构化输出,供自动化消费
node wb_tasks.js --raw # 打印原始响应(排查上游字段变化用)拉一次成长中心的任务清单,告诉你 18 个任务里哪些能领、哪些还差几次、哪些有截止日期。 输出分四组:🟢 可领奖 / 🔵 计次进行中(带「还差 N 次」)/ 🟡 无计数待做 / ✅ 已领取(默认折叠)。
它只有 GET,没有任何写操作。 这是刻意的边界:进度由服务端按真实行为点亮,
所以这个脚本只读取、绝不构造或补报行为事件,也绝不伪造客户端身份标识 —— 即「不编造证据」。
它的合规定位与 wb_checkin.js --status 同档:自己的登录态、官方端点、只读不写。
跑它不会让任何进度前进;要达标得去客户端里真实操作(派猫那类可交给 wb_auto_task.js)。
两个实测口径,写脚本时容易踩:
- 上游对「无计数」的一次性任务给的是
progress: null,不是target: 0—— 当成 0 会误判成"还差 0 次"。 claimed_button_text字段不可信:未接受的任务(accept_status=not_accepted)也返回"已完成"。 判断是否已领只能看accept_status。- 只给一部分任务返回
valid_end(有效期),脚本会显示「⏳ 有效期至 X(剩 N 天)」。
node wb_start_edge.js # 先确保常驻 Edge 在跑(冷启动可能 >30s)
node wb_run_tasks.js # 干跑:只报告,不点任何东西(默认)
node wb_run_tasks.js --apply # 真执行
node wb_run_tasks.js --apply --only=chat_5 # 只做指定任务
node wb_run_tasks.js --claim-only --apply # 只领奖用真实浏览器 UI 点击完成「网页端能做」的任务,并点真实领奖按钮。它会先把 18 个任务
逐个分类(依据 jump_url 协议 + DOM 里的 dt-remark.taskCode):
| 分类 | 含义 | 本脚本行为 |
|---|---|---|
| 🟢 可领奖 | 进度已足,只差领 | 点真实领奖按钮并复核 |
| 🤖 可网页代做 | 网页端点击即可完成 | 代做 |
| 🙋 需客户端/真人 | 跳 workbuddy:// 指向桌面端专属界面,或必须真人 |
不碰,列出让你自己点 |
边界(刻意,勿为省事改掉):只做真实点击。不发任何行为上报、不伪造设备标识、 不代做需真人的项。
wb_start_edge.js存在的原因:不是"绕过代理",而是冷启动慢。成长中心的常驻 Edge 冷启动可 > 30s,早先内联在派猫脚本里的等待循环只有 30s,于是反复拉起。现在单独成文件、等满 90s。⚠️ 关于HTTP_PROXY的一处曾用错的归因(2026-09-17 实测修正): 本机环境设了HTTP_PROXY(指向一个本地代理端口),曾判定"代理把127.0.0.1:9223的环回请求 也送进代理 → 拿到 502 → 误判「常驻 Edge 未就绪」"。这个归因是错的,实测三种探活方式 全部成功:不清代理fetch→ HTTP 200;清掉代理 +NO_PROXY→ HTTP 200;net.connect→ 端口在听。 事实是代理能正确转发环回请求:9223 在听就回 200,没人听才回 502(直连则是ECONNREFUSED)。 也就是说502 == 确实没在听,不是假阴性 —— 真因是 Edge 冷启动还没起来。 仍然保留 TCP 探测,理由是刻意收敛不确定性(代理端口每次会话会变、代理可能消失,TCP 少一层); 但它不是 bug 修复,其余脚本的旧写法可用,不必为此改动。 仍然成立的一条:给fetch传{ proxy: undefined }无效 —— undici 读的是环境变量。- 出网不受清代理影响:实测保留/清空代理两种情况下请求
copilot.tencent.com都返回 401(= 到达服务器、只是没带 token),所以那个__loopbackNoProxy块对出网无害。 gs-load-more(「全部任务」)是分页式:点一次只多渲染几行,必须循环点到行数不再增长, 否则只能看到 5 行(首屏只渲染"进行中"的那几个)。- 「领取更多」不是领奖按钮:点了不弹窗、不发请求、按钮文案不变 —— 它只是个跳转入口
(
Hp_Appearance)。按/领取/模糊匹配会把这种跳转钮当领奖点,白点一次还误报成功。 现在用精确文案^(收下奖励|领取奖励|领取 N 积分|领取)$判定,并把跳转钮显式标注出来。 - SPA 渲染竞态会伪装成「页面没数据」:成长中心冷启动渲染出
.gs-task-row需 ~9s。 原先固定await sleep(4000)会读到 0 行,并让expandAll第一轮就break—— 而且一条日志都不打,看起来像页面空了/选择器失效了,极难排查。 现改为轮询等首行出现(waitRows),每次 600ms、上限 30s;等不到会明说当前 URL。 教训:凡"等 SPA 渲染完再读 DOM",一律用「等元素出现」,不要用固定 sleep。 - API 与 DOM 会不一致:
/v2/activity/growth/tasks的accept_status有延迟, 实测 DOM 上已出现可领按钮时 API 仍报claimable=0。以 DOM 为准。 - 本机后台进程留不住:跨
Bash调用启动的 Edge 会被回收,所以run_growth.bat把「拉起 Edge」和「跑任务」放在同一次调用里。
18 个成长任务里:可领奖 0 · 可网页代做 0 · 需客户端/真人 7(其余 11 已完成)。
也就是说 没有一个任务能靠网页端代做。4 个原本归为 auto 的
(chat_5 / expert_5 / create_canvas / playbook_prompt)早已全部领完,
剩余 7 项不是跳 workbuddy:// 桌面端专属界面,就是必须真人:
| taskCode | 分类 | 为什么本脚本不碰 |
|---|---|---|
Buddy_App |
desktop_only | 客户端「发现应用」里进入任一应用 |
Buddy_App_QQ |
desktop_only | 客户端进入「企鹅教师助手」应用 |
Expert_team_use_3 |
desktop_only | 客户端召唤 3 次专家团 |
template_5 |
desktop_only | 客户端用 5 个模板(网页端无模板库) |
Expert_lighthouse |
desktop_only | 客户端体验「腾讯轻量云」专家 |
Hp_Appearance |
desktop_only | 客户端「设置 → 外观」切主题(网页端「领取更多」只是跳转钮) |
black_cat |
human_only | 夜间折扣活动,与消费相关 |
所以这个脚本的真正价值是「分类 + 守边界」 —— 明确告诉你哪些不该碰、 哪些该自己点,而不是代做本身。
「9月活跃地图」里有条连登进度条:连登满 7 / 14 / 28 天可各换一档奖励 (入门档 / 进阶档 / 巅峰档)。这个脚本自动点掉还没领的档位。
node wb_claim_rewards.js # 干跑:报连登状态 + 打开弹窗列出各档位(不点任何东西)
node wb_claim_rewards.js --apply # 真领:打开弹窗,点掉所有可领档位
node wb_claim_rewards.js --status # 极简只读:只读连登 DOM,连弹窗都不开
node wb_claim_rewards.js --probe # 点击链路自检:验证能否定位/点到档位按钮(不点)怎么在「没有可领档位」时确认它真能用? —— 用 --probe。它解析 locator、读
位置 / 尺寸 / 可见性 / disabled,但不点击,所以即使本月已兑完也能验证点击链路是通的:
── --probe 点击链路自检(不点击)──
✓ 入门档 位置=(720,299) 尺寸=70x32 可见=是 可点=否(locked) 定位正常,但 locked → 点会等到超时(--apply 跳过)
✓ 进阶档 位置=(720,367) 尺寸=70x32 可见=是 可点=否(locked) 定位正常,但 locked → 点会等到超时(--apply 跳过)
✓ 巅峰档 位置=(734,435) 尺寸=56x32 可见=是 可点=否(locked) 定位正常,但 locked → 点会等到超时(--apply 跳过)
[--probe] 只验可达性,未点任何按钮。「可点=是」的档位才可能被 --apply 领到。
怎么读这三行 —— boundingBox() 返回 {x, y, width, height} 四项:x/y 是元素左上角
在视口里的坐标(位置),width/height 是元素自身尺寸。
x/y 会随窗口尺寸与滚动变化,不是稳定常量;尺寸才由文案长度决定、是可比的。
y逐行递增 68px(299 → 367 → 435)→ 三档是纵向等距的三行,确实是三个独立元素。x前两档都是 720,巅峰档是 734 → 算x + width:790 / 790 / 790,右边缘完全对齐。 即这三个按钮是右对齐排布,巅峰档因为窄 14px,左边缘便右移 14px。 这条顺带说明为什么不能用「尺寸相同」判定是同一元素 —— 真正区分元素的是位置。- 尺寸由文案长度决定:入门/进阶的文案都是「已兑换」3 个全角字 → 都是
70x32; 巅峰档是「兑换」2 个字 →56x32。差值 14px 正好是一个全角字宽。 所以尺寸能反推文案:若两档尺寸不一样,说明读到的按钮文案不同(可用来自检)。
⚠️ 「定位成功」不等于「能点」:这三档当时全部locked(入门/进阶是已兑换 → 按钮 disabled; 巅峰是未解锁)。Playwright 对disabled元素的click()不是立即失败,而是等到超时, 所以--apply在点之前必须再核一次锁态,否则会把整个循环每档卡 8 秒并误报「点击失败」。
实测输出(2026-09-17):
── 活跃地图 · 连登概览 ──
标题 : 9月活跃地图
连登天数 : 当前连续登录 17 天 (进度条 60.7143%)
下一档 : 连登 28 天获得奖励
本月已兑 : 2 次 · 补登卡: ×4
里程碑 : 7天 已达成 · 14天 已达成 · 28天 未达成
── 选择奖励 · 档位状态 ──
入门档 已兑换 [已兑换] +2 能量 · +1 张补登卡 · +1 次抽奖
进阶档 已兑换 [已兑换] +50 积分 · +3 能量 · +1 张补登卡 · +1 次抽奖
巅峰档 未解锁 [兑换] +150 积分 · +5 能量 · +1 张补登卡 · +1 次抽奖
- 档位按钮的文案不可信 —— 最关键的一条。巅峰档(28 天)在连登不足时文案就已经是「兑换」,
但它
disabled=true且 class 含is-locked。若按文案/兑换/判定可领,就会去点一个 点不动的按钮并误报成功。判定一律看disabled/is-locked,文案只用来识别「已兑换」。 (与成长任务的claimed_button_text是同一类陷阱。) - 连登天数在子元素里:
.gs-streak-days的实际 HTML 是当前连续登录 <b>17</b> 天。 只取直接文本节点会得到「当前连续登录 天」(数字消失)→ 必须用innerText。 .gs-section-title页面里有多个:第一个是「任务」区块的标题,直接querySelector('.gs-section-title')会拿错 → 要用.gs-streak-row往上closest('section')锚定。- 里程碑状态有机器可读标记:
.gs-streak-dot.is-reached,不用去解析「7天/14天」文案。 - 只读接口「时通时不通」,不是"坏":
GET /activity/growth/streak与/activity/growth/redeem/summary在页面内fetch曾实测TypeError: Failed to fetch(同页heatmap却 200 OK),后来同一台机器、同一登录态又都返回 200。 所以脚本以 DOM 为准,接口只当可选佐证、失败不致命。 两者口径一致时能交叉验证:实测redeem/summary返回starter_count / advanced_count / legendary_count = 1 / 1 / 0, 与 DOM 的「入门/进阶已兑换、巅峰未解锁」吻合。
只做真实 UI 点击:打开「兑换奖励」→ 点各档「兑换」。点击用 Playwright 的 click()
(CDP 真实输入事件,isTrusted=true),而不是页面内的 element.click() 合成事件 —— 对齐 wb_auto_task.js。
不向 /v2/report 发合成事件、不伪造设备标识,也不直调 POST /activity/growth/redeem
(口径已摸清,但刻意走点击:服务端记的才是真实发生的领取)。
关于补登:日历上「未打卡(可补登)」的格子能用补登卡回填
(端点 /activity/growth/makeup-cards/use),把连登天数顶上去、提前解锁高阶档位。
它属于可用功能,但改变的是打卡记录本身而非"领取奖励",语义与领奖不同,
所以本脚本默认不做。要顺手补登请明确说。
⚠️ 该活动规则:完成一次对话才能被记录 —— 只有真实对话才算当天活跃。
活动每月会换(9月活跃地图 这个标题就是变量),但探法固定。按顺序来,别跳步:
- 先写只读探针,别先写点击。 新开一个
_wd_probe_xxx.js(.gitignore已覆盖_wd_probe_*.js), 复用常驻 Edge 的登录态,用page.evaluate打印候选锚点与innerText。看清楚再动手。 - 锚点认「数据属性」,不认文案。
.gs-task-action的dt-remark里是 JSON (taskCode/title/buttonText);文案会变、会重复、会撒谎(见上面「领取更多」)。 - 判定认 DOM 状态,不认按钮文字。
disabled/is-locked/is-reached这类 class 与属性才是机器可读的真相 ——claimed_button_text已有实测反例, 巅峰档未解锁时文案就已经是「兑换」。 - 接口只当佐证,以 DOM 为准。 同页
fetch有的通(heatmap200)有的失败 (streak/redeem/summary→Failed to fetch);accept_status还是延迟聚合的。 - 列表面板可能是「累加式分页」。
gs-load-more(「全部任务」)点一次只多渲染几行, 必须循环点到行数不再增长,否则只看到首屏 5 行。 - 等待一律「等元素出现」,不用固定
sleep。 且失败要明确报错 —— 静默break会把"没渲染"伪装成"没数据",极难排查(见上面 SPA 竞态那条)。 - 默认干跑,
--apply才真执行。 再配一个--probe(只验 locator 可达、不点击), 这样即使当下没有可操作项,也能证明链路是通的、而不是"从没跑过"的纸面功能。 ⚠️ 点击前必须复核锁态。 Playwright 对disabled元素的click()不是立即失败, 而是等到超时 —— 不先查disabled/is-locked,会把整个循环每档白卡 8 秒并误报「点击失败」。- 写操作只走真实 UI 点击(Playwright
click()= CDP 真实输入事件,isTrusted=true), 不直调写端点、不发合成上报。这条是刻意的取舍,勿为省事改掉。
node wb_diag_dom.js # dump 派猫按钮 + 弹窗真实 DOM(加 --click 会点一下主按钮观察弹窗)
node wb_diag_gift_flow.js # 完整跑一遍领礼物流程,逐步输出耗时与状态变迁两者都附着在常驻 Edge(9223)上,不会把常驻窗口杀掉。
- 领礼物静默失败复盘(2026-09-13)
—— 一次「note 说已领取、实际没领到」的伪装成功故障;顺带记了自动化脚本里为什么不该用固定
sleep、 为什么不能写空catch。 - 派猫登录态根因与零扫码修复(2026-09-15) —— 用 cookie 数据证实「登录态 = 进程在不在」,进而改用令牌续期方式做到重启零扫码 (含实测记录与遗留边界)。
.github/workflows/sync-to-gitee.yml 把仓库镜像到 Gitee 账号
strange_touchannel。push 到 main 即自动触发,纯 git 直推,约 20 秒完成。
- 可见性自动跟随 GitHub:由
ensure-gitee-repo.sh读 GitHub 仓库的private字段再写回 Gitee —— GitHub 上公开,Gitee 上就公开,不靠人工同步; 已存在且已一致时不发任何写请求,避免无谓覆盖描述等其他设置。 注意顺序:Gitee 不允许把空仓库设为公开(422 空仓库不支持设置为公开仓库), 所以脚本拆成ensure(推送前建仓,一律先私有)和align(推送后改可见性)两个阶段。 - 手动 Run workflow 勾选
include_all_repos,会并行把 workflow 里matrix.repo名单中的所有仓库 一并镜像(fail-fast: false,单个仓库失败不拖累其他)。 - 只用三个凭据,且都是现成的:
GITEE_TOKEN(建仓 / 改可见性)、GITEE_SSH_KEY(推送)、GITHUB_TOKEN(runner 自带,仅用于读一个private字段)。 不需要任何 GitHub PAT,因此不存在「令牌被轮换 → 静默失效」的风险。 - 唯一维护点:新建仓库后要把名字追加进
matrix.repo名单,不会自动发现。 - 2026-09-16 重写原因:旧版用
Yikun/hub-mirror-action,它必须先调 GitHub API 列出账号下的仓库清单,这需要src_token。该 secret 从未配置 → 请求走匿名 → 撞上 GitHub 匿名限流(60 次/小时,runner 共享出口 IP 几乎必然耗尽)→ 日志里Total: 0, successed: 0(一个仓库都没同步),但退出码仍是 0 → Actions 上显示绿色 ✓。 实测同步是「时灵时不灵」的抽奖,且失败时没有任何提示。新版全程不碰 GitHub API 的仓库枚举 (git 协议不消耗 API 配额),任何一步失败都会让 job 真失败,不会再出现「绿色空转」。
走了上面的「推荐用法」的话,这三步 WorkBuddy 已经替你跑完了,这里只是留档说明每一步在做什么。完整版(含故障兜底)见 INSTALL.md。
- 装依赖(Playwright core,走本地 playwright-core,无需下载浏览器):
npm i playwright-core
- 登录一次:
在弹出的 Edge 窗口里登录 www.workbuddy.cn。**登完不要关窗口** —— SSO 会话是浏览器会话级的, 进程一关就焚(2026-09-06 实测踩坑),保持常驻才能让每日任务复用。登录态落在
node wb_login_once.js --timeout=15
wb_auto_profile_edge/。 想「登录 + 验证」一步到位,直接跑node wb_login_then_run.js:扫码成功后它会自动在同一个常驻会话里 依次跑「派猫 → 签到」并打印结果。
不需要关闭 Edge 的 App-Bound Encryption,也不需要改动任何浏览器安全策略。 脚本附着在自己拉起的、带独立
--user-data-dir的专用 Edge 上,cookie 由 Edge 进程自己解密与维持。如果早期版本导入过
disable_edge_abe.reg(v1 遗留步骤,已确认不再需要): 在注册表编辑器里把HKLM\SOFTWARE\Policies\Microsoft\Edge下的ApplicationBoundEncryptionEnabled改为1(或删除该值),重启 Edge 即恢复系统默认的凭据保护。
- 派猫必须点二次确认框。主按钮点完会弹「确定派出」,不点这个确认框服务端不会真正派遣 —— 早期版本漏了这步导致"假成功"。脚本现在会点击后复核按钮是否切到「旅行中/倒计时」才算真成功。
- 礼物态要先领再派。猫回家后按钮变成「领取礼物」,需先领奖励,按钮才会回到「派猫猫旅行」。
⚠️ 领取礼物是异步的,别在领取中刷新页面(2026-09-13 故障根因)。点「领取 N 积分」后按钮会变成「领取中…」并 disabled;旧版只等 1.5s 就page.goto刷新,把还没完成的领取请求打断 → 礼物其实没领到,刷新后按钮仍是「领取礼物」,而外层catch(e){}又把异常静默吞掉,最后报unknown-state:领取礼物还谎称"已领礼物"。现在改成:全程轮询(等弹窗、等领取按钮可点、等按钮真正离开「领取」态最多 20s)+ 结果强校验 + 失败重试一轮 + 异常全记进res.giftLog。- SPA 渲染会延迟。
getTravelBtn轮询最多 25s 等按钮出现,否则会误判no-travel-button(成长中心实测约 5–10s 才渲染出按钮)。 - 别用固定
sleep等异步 UI。凡是"点了之后再操作"的地方(礼物弹窗、派遣确认框)一律轮询等目标出现/可点,页面负载一波动固定等待必然偶发漏步。 - 加油站签到走浏览器同源会话,不读 token。签到 API 与页面同源(www.workbuddy.cn),常驻 Edge 对该域有有效会话 cookie,页面内同源 fetch 即完成鉴权。早期版本读桌面端登录态文件直连 API,2026-09-24 桌面端把 accessToken 改为加密信封后该路线废弃。
- Edge 会话失效需重新扫码(v3 之后的现实)。SSO 会话 cookie 是会话级的,浏览器进程一关就焚。v3 曾用桌面端长期令牌续期做到重启零扫码,但 2026-09-24 起令牌加密(独立脚本无法解密),该路线已废弃;扫码本身由
wb_login_once.js在自己的专用 profile 里原生完成,登完保持常驻。掉登录后的自动化兜底是wb_login_then_run.js(2026-10-07 新增):登录等待与任务执行放在同一个 Node 进程里(本机会回收父进程退出后的 detached Edge),扫码成功后立即在同一常驻会话内依次跑「派猫 → 签到」,彻底免掉「扫完码还要手动补跑」那一步。 - 签到收尾不能关浏览器。
wb_checkin.js释放连接时只disconnect()CDP 句柄,不再browser.close()—— 附着模式下close()会把整个常驻 Edge 关掉,连带焚毁会话级 cookie,还会让后续派猫只能冷启动去撞connectOverCDP超时(2026-10-07 修复)。同时末尾显式process.exit(0),避免disconnect()之后 playwright 句柄占着事件循环、进程挂住不退(2026-10-11 修复)。 - 瞬时失败靠「整流程重试」吸收(v4)。SPA 渲染抖动/冷启动竞态会让点击、查找按钮偶发失败(实测 2026-09-15、09-16 每天都要人工复跑 1~2 次才派成功)。现在把「进成长中心 → 判定状态 → 执行动作」抽成单轮函数
runOnce(),外层最多跑 3 轮,每轮重新加载页面,一次运行即自愈。这也是 19:25「补派兜底」自动化被删掉的前提——兜底能力已下沉到脚本内部,比「25 分钟后再跑一次」更准、更省积分。回归测试见test_round_retry.js。
- 脚本不读取、不打印、不落盘任何 accessToken。签到通过常驻 Edge 内的同源 fetch 完成,凭据完全留在浏览器进程内;日志只输出积分与连续签到天数。
- 只请求
www.workbuddy.cn官方域名(与页面同源),无第三方。 wb_auto_profile_edge/是浏览器 profile,含真实登录 cookie,已在.gitignore中排除,切勿提交。- 只读本机登录态文件,不修改 WorkBuddy 本体。
- 仓库内不存在任何"行为上报":
wb_tasks.js只有 GET;wb_auto_task.js与wb_run_tasks.js只做真实 UI 点击(点了按钮服务端才记账)。没有一条请求是替你 去"声明"某件你没做过的事,也不伪造设备标识/客户端指纹。这条是刻意的取舍, 勿为省事发合成事件。
- Windows + Edge(macOS / Linux 也能跑,路径会自动探测)
- Node 22+(
fetch原生可用) playwright-core(npm i playwright-core)
机器相关的路径 —— Edge 可执行文件、浏览器 profile、playwright-core、node.exe ——
全部由 wb_paths.js 自动探测,仓库里不写死任何本机路径,clone 下来就能跑。
优先级(高 → 低):
| 级别 | 方式 | 说明 |
|---|---|---|
| 1 | 环境变量 WB_EDGE / WB_PROFILE / WB_PLAYWRIGHT / WB_NODE |
临时改一次用 |
| 2 | local.config.js |
不提交(已 gitignore),从 local.config.example.js 复制。想永久钉死自己的路径就写这儿 |
| 3 | 自动探测 | 按平台枚举常见安装位置,找不到再退到 PATH |
换机器后想确认探测得对不对:
node wb_paths.js # 打印 edge / profile / playwright / node 的最终解析结果