

适合人群:想让 WorkBuddy 把重复动作自己跑起来的开发者,以及被"断签清零"折磨过的普通用户。 实测环境:Windows 10 22H2(19045)+ WorkBuddy 5.8.3 + Python 3.13。
WorkBuddy 的加油站签到,规则很简单也很残酷:
一个月按 30 天算就是 3000 积分,够把日常的文档、表格、PPT 类任务跑上一段时间。但它的成本不在积分上,在你的注意力——每天记着点一下,这件事人天生做不好。
所以我把它拆成了三步:先搞清楚接口返回什么,再写一个幂等的领取脚本,最后挂到定时任务上。真正花时间的不是写脚本,是踩坑。
想自动化这个动作,大概有三种做法,我先都试了一遍思路:
路线 | 做法 | 问题 |
|---|---|---|
UI 点击 | 用自动化工具模拟点击头像 → 加油站 → 领取 | 入口位置会随版本活动变,促销卡和"立即领取"共用同一个控件 ID,很容易点成"购买积分" |
驱动渲染进程 | 开 CDP 调试端口,在页面里发同源请求 | 需要手动开调试端口,重启客户端后失效,等于每天要人守着 |
客户端内置 IPC | 走客户端自己的命名管道通道 | 通道只在客户端运行时存在,这是它唯一的限制 |

图 1|三条自动化路线对比:前两条都要先拿到令牌,第三条由客户端代为发送
第三条最不起眼,但它解决了最关键的问题:鉴权由客户端注入,脚本全程不接触任何登录凭证。
这一点值得多说一句。社区里早一批脚本走的是读本机登录信息、自己拼 Header 的路子,新版客户端把登录态换成了 AES-256-GCM 的加密信封($wbEncrypted 格式),明文读取那条路已经废了。就算没废,把令牌读出来放进脚本、再放进日志,本身就是个不该有的攻击面。能用宿主通道就不要自己搬凭证。
通道建立后,第一件事是读状态,而不是直接领。状态接口返回的字段很干净:
字段 | 含义 |
|---|---|
| 活动是否开启。为 false 时直接放弃,不要试领取 |
| 当期活动名与起止时间 |
| 今天是否已签,幂等判断全靠它 |
| 当前连续天数 |
| 单日基础积分 |
| 连签加码部分 |
| 账户侧的累计口径字段 |
我抓到的真实一次返回(数值保留,去掉账号相关信息):
{
"active": true,
"activity_name": "Buddy应用",
"start_time": "2026-09-30 00:00:00",
"end_time": "2026-10-31 23:59:59",
"today_checked_in": true,
"streak_days": 6,
"daily_credit": 100,
"streak_bonus_credit": 0
}注意 active 和活动起止时间是会变的——10 月这一期到 10-31 结束,换期之后活动名和周期都会换。所以脚本不能把活动名写死,也不能假设"活动永远开着",必须每跑一次先问状态。
核心逻辑只有三步:查状态 → 未签则领 → 再查一次复核。

图 2|三段式:顺序不能反,第三步的复核最不能省
下面是去掉非必要部分后的骨架,纯标准库:
import base64, json, sys
sys.path.insert(0, LIB_DIR) # 指向 WorkBuddy 内置 skills/library
from workbuddy_ipc import connect
STATUS = "/v2/billing/meter/checkin-activity-status"
CLAIM = "/v2/billing/meter/daily-checkin"
def main():
with connect(client_id="daily-checkin", client_kind="skill") as wb:
pipe = wb.get_pipe("wb.request")
def call(method, path):
resp = pipe.invoke("http.fetch", {
"method": method,
"path": path,
"headers": {"accept": "application/json",
"content-type": "application/json"},
"body_b64": base64.b64encode(b"{}").decode(),
}, timeout=35)
return json.loads(base64.b64decode(resp.get("body_b64") or b"e30="))
st = call("POST", STATUS).get("data", {})
if not st.get("active"):
print("活动未开启"); return 0
if st.get("today_checked_in"):
print("今日已签, streak =", st.get("streak_days")); return 0
call("POST", CLAIM)
ok = call("POST", STATUS).get("data", {}).get("today_checked_in") is True
print("复核:", ok)
return 0 if ok else 1connect() 会去读客户端写下的 endpoint.json 完成握手,之后所有请求都由宿主注入鉴权。脚本里没有一行和账号、令牌相关的东西——这是这条路线最大的好处,也是我最终选它的原因。

图 3|三个坑速览:都不是逻辑错,是环境错
第一版脚本我直接跑,报错:
ERROR: 未找到 WorkBuddy 内置库目录(workbuddy_ipc)。原因是它自动探测的候选路径只有两类——Program Files 和 %LOCALAPPDATA%\Programs。而我这台机器把 WorkBuddy 装在了 E 盘的自定义目录下,两个候选全落空。
解决办法是显式指路,用环境变量覆盖探测:
export WORKBUDDY_SKILL_LIB="E:/.../WorkBuddy/resources/app.asar.unpacked/resources/plugins/workbuddy-builtin/skills/library"如果你也把客户端装在 D 盘或 E 盘,这一步基本躲不掉。判断方法很简单:报的就是上面那句 未找到 ... workbuddy_ipc。
我本来想一次配两个时点(早上一次、晚上一次兜底),写了 BYHOUR=9,21,直接被拒:
invalid recurring rrule: BYHOUR must be an integer between 0 and 23.这个校验比我预想的严格——逗号分隔的多值在这里不成立,只认 0–23 的单个整数。最后的处理是:一个任务一个时点,把时间定在机器最可能开机且你还没开始干活的时候(我选了 09:05)。
顺带一个判断:别为了兜底配一堆时点。自动化每次触发都会真实消耗一点积分,签到本身是净赚的,但你配五个时点就变成五次模型调用,收益会被吃掉一部分。两个时点以内是合理的。
daily-checkin 是幂等接口,重复领会返回业务码 10001。但即便返回 200、即便 body 看着像成功,也不代表状态真的变了——网络重试、活动切换、状态写入延迟都可能导致"响应成功、实际没签"。
所以一定要二次查询复核 today_checked_in === true,而不是相信第一次领取的返回。这一步多一点代码,但省掉了"以为签了、其实断了"的代价——断签是要清零重算的。
自动化挂上去以后最大的风险不是它报错,是它静默地不执行。我的验证方式是每天看两件事:
streak_days 是不是比昨天大 1。只要连续天数在涨,就说明链路是通的。如果某天 today_checked_in 是 false 而 active 是 true,那基本就是自动化没跑,而不是接口问题。
还有一种预期内的情况要认:客户端没运行时通道不存在,脚本会直接退出,这时正确的做法是报"本次跳过"然后结束,不要重试风暴——你重试一百次,管道也不会凭空出现。
写完这套东西,我自己给划了三条线:
自动化真正省下的不是那 100 积分,是"每天记着点一下"这件事对注意力的占用。WorkBuddy 的定位是"你说一句,它把活干完"——签到这种动作,本来就不该占人的脑容量。
如果你也在用 WorkBuddy,欢迎在评论区讲讲你把哪些重复动作交出去了,我这边下一个准备自动化的是本地模型的定期健康检查。
标签:#WorkBuddy #人工智能 #自动化
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。