首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >用 WorkBuddy 搭一条个人自动化流水线:定时签到 + 车次查询 + 结果推送到微信(附完整代码)

用 WorkBuddy 搭一条个人自动化流水线:定时签到 + 车次查询 + 结果推送到微信(附完整代码)

原创
作者头像
用户12763151
发布2026-09-14 22:01:13
发布2026-09-14 22:01:13
50
举报

1. 背景:我要解决的三个重复劳动

我平时有三件事一直在重复做,说大不大,但都很烦:

  1. WorkBuddy 每天的积分签到,经常忘,一断签连签天数就归零
  2. 偶尔要查 12306 的班次,手动翻页、还要自己筛站点
  3. 分析结果生成完之后,人不在电脑前就看不到

第三点最难受——分析完了但看不见,等于白做。

所以我想把它们串成一条流水线:定时触发 → 自动执行 → 结果推送到手机

2. 方案设计

整体结构很简单:

代码语言:py
复制
定时触发器
   ↓
① 签到:直连官方接口(不点界面)
   ↓
② 查询:12306 数据抓取 + 清洗
   ↓
③ 推送:结果发到微信
   ↓
失败才告警(成功不打扰)

3. 实操步骤

3.1 第一个坑:别让 AI 去点按钮

我的初始思路很自然:让 WorkBuddy 每天帮我点一下客户端的签到按钮。

这条路一开始就是死的。 WorkBuddy 的自动化是文字型 Agent,看不见桌面窗口,也没有点击 GUI 的能力。我不该在"怎么点"上耗时间,而该换个角度想问题。

转折点是想明白一件事:签到这个动作,本质就是一次带登录态的 HTTP 请求。 点按钮只是它外面包的一层皮。

想通之后,方案就变成直连接口,好处是压倒性的:

  • 不依赖窗口是否打开
  • 不怕客户端改版
  • 不需要装浏览器和任何第三方库

3.2 找到接口:读客户端自己的配置文件

关键一步是拿到正确的域名和登录态。

登录态文件在这里:

代码语言:py
复制
%LOCALAPPDATA%\CodeBuddyExtension\Data\Public\auth\workbuddy-desktop.info

里面有三个字段有用:

  • auth.accessToken —— 身份凭证
  • account.uid —— 用户 ID
  • auth.domain —— 接口域名

这里有个大坑。 网上大部分教程写的域名是 copilot.tencent.com,我照着试直接 404。

正确做法是:别信教程,去读客户端自己写的值。 客户端连哪个域名,就跟着用哪个。版本会变,教程会过期,但客户端自己的配置永远是对的。实测是 www.codebuddy.cn

用到的接口:

用途

方法

路径

查询签到状态

POST

/v2/billing/meter/checkin-activity-status

执行签到

POST

/v2/billing/meter/daily-checkin

查询积分余额

POST

/billing/meter/get-user-resource-summary

获取邀请码

GET

/activity/workbuddy/invitation/v2/my-code

核心代码(纯标准库,零依赖):

代码语言:python
复制
import json, os, urllib.request

path = os.path.expandvars(
    r"%LOCALAPPDATA%\CodeBuddyExtension\Data\Public\auth\workbuddy-desktop.info")
d = json.load(open(path, encoding="utf-8"))
token = d["auth"]["accessToken"]
uid   = d["account"]["uid"]
base  = "https://" + d["auth"]["domain"]

def post(p, method="POST"):
    req = urllib.request.Request(base + p, data=b"{}", method=method)
    req.add_header("Content-Type", "application/json")
    req.add_header("Authorization", "Bearer " + token)
    req.add_header("X-User-Id", uid)
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.loads(r.read().decode("utf-8"))

st = post("/v2/billing/meter/checkin-activity-status")
print(st["data"]["streak_days"], st["data"]["total_credits"])

返回的字段比想象中丰富:streak_days 是连续天数,total_credits 是本期累计,还有 start_time / end_time 能看出活动周期,action_button 会推送当期活动入口。

3.3 第二条流水线:12306 车次查询

同样的思路。12306 需要先建立会话拿 Cookie,再调查询接口:

代码语言:bash
复制
# 1. 先访问初始化页面拿会话
curl -c ck.txt "https://kyfw.12306.cn/otn/leftTicket/init" -H "User-Agent: Mozilla/5.0"

# 2. 注意:查询接口是 queryG,不是 query
curl -b ck.txt "https://kyfw.12306.cn/otn/leftTicket/queryG?leftTicketDTO.train_date=2026-09-11&leftTicketDTO.from_station=FZS&leftTicketDTO.to_station=XMS&purpose_codes=ADULT"

两个坑:

  1. 接口名是 queryG,用 query 会被提示跳转,白折腾半天
  2. 返回的 result 数组是管道符分隔的字符串,不是 JSON 对象,要按 | 切分取字段

还有一个业务层面的坑:查"福州"会同时返回福州站和福州南站的车次,必须按始发站字段二次过滤,否则给用户的时间表是错的。我第一版就漏了这个,差点给出错误的出行建议。

3.4 最后一公里:推送到微信

个人微信没有开放的消息接口,但可以用 Server酱 这类服务补上:微信扫码关注,拿到 SendKey,之后任何脚本发一个 HTTP 请求,消息就进微信了。

代码语言:python
复制
import urllib.request, urllib.parse

def push(title, content):
    url = "https://sctapi.ftqq.com/%s.send" % SENDKEY
    data = urllib.parse.urlencode({"title": title, "desp": content}).encode()
    urllib.request.urlopen(urllib.request.Request(url, data=data), timeout=30)

返回 {"code":0} 就是成功。Markdown 格式的表格在微信里也能正常渲染。

4. 踩坑与解法汇总

现象

解法

让 AI 点按钮

根本做不到

改走 HTTP 接口

域名照抄教程

404

读登录态里的 auth.domain

12306 接口名

提示跳转

queryG

返回非 JSON

解析报错

\| 切分字符串

同名站点混淆

结果混入福州南

按始发站二次过滤

每天推送成功通知

通知变噪音被忽略

只在失败时推送

最后一条值得展开说。成功不推送,失败才推送。 每天一条"签到成功"很快就会变成背景噪音,人会自动忽略它——而一旦习惯了忽略,真正重要的失败通知也就跟着一起被漏掉了。

5. 效果对比

事项

之前

之后

每日签到

靠记忆,平均每周漏 2 天

定时自动,连续 10 天未断

查车次

手动翻页约 5 分钟

一条命令,10 秒出结果

看分析结果

必须回到电脑前

手机直接收

异常感知

发现时已断签好几天

失败当天推微信告警

6. 一个必须守住的安全底线

accessToken 等同于登录密码。

很多教程喜欢教人"打印前 15 位 + 后 8 位"来调试,说这样不算泄露。这是错的——尾部几位也是真实字符,配合已知的 token 结构,依然构成有效泄露。

我的处理是:脚本从头到尾一个真实字符都不打印,调试输出统一显示"已加载(内容已隐藏)"。写这篇文章时也检查过,token 没有出现在任何要公开的内容里。

另外脚本严格只读登录态文件,不修改、不删除、不切换账号。

7. 几点体会

  1. 先判断这条路存不存在,再动手。 让 AI 点按钮、让脚本模拟鼠标,很多时候是方向性错误,不是技术问题。方向错了,再努力也没用。
  2. 别信教程里的域名和参数,去读客户端自己写的值。 版本一变教程就过期,但客户端的配置永远是对的。
  3. 幂等性要自己保证。 接口虽然幂等,脚本层也要先查状态再决定要不要发请求。
  4. 通知的敌人是噪音。 只在该打扰的时候打扰。

全部代码为 Python 标准库实现,不需要安装任何第三方包,Windows / macOS 通用。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 1. 背景:我要解决的三个重复劳动
  • 2. 方案设计
  • 3. 实操步骤
    • 3.1 第一个坑:别让 AI 去点按钮
    • 3.2 找到接口:读客户端自己的配置文件
    • 3.3 第二条流水线:12306 车次查询
    • 3.4 最后一公里:推送到微信
  • 4. 踩坑与解法汇总
  • 5. 效果对比
  • 6. 一个必须守住的安全底线
  • 7. 几点体会
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档