WorkBuddy 和 TeleAgent 每天签到都能领 100 积分,但手动点太累还容易忘。本文用金山文档在线表格搭一套全自动签到流水线:第一步从客户端登录态里提取 refreshToken / token / device_id,第二步把签到脚本注入 AirScript 并开通网络 API 授权,第三步设置每天定时云端执行,第四步用 SMTP 服务让结果单元格一变化就自动发邮件。四个步骤附可直接复制的完整脚本与实测避坑细节。
手里常年挂着的 AI 工具不少,WorkBuddy(腾讯系 AI 编程助手,客户端目录名 CodeBuddyExtension)和 TeleAgent(中电信的星辰智能体)都有”每日签到领积分”的福利——每天点一下,各送 100 积分。积分能换模型额度、能兑商城礼品,看着不多,架不住天天都有。
问题就出在”天天”这两个字上:得先想起这件事,再打开客户端,再找到入口点一下。两个工具、多个账号,一个月漏签十次八次很正常。与其靠自律,不如靠自动化——本文用金山文档在线表格(365.kdocs.cn)搭一套全自动签到流水线:取密钥 → 注入脚本 → 定时执行 → 邮件汇报。搭好之后电脑关机也照跑,你只需要每天看一眼邮箱。
📑 目录h2
一、方案总览h2
整套方案跑在金山文档的在线表格上,四步串成一条流水线:
第一步 取密钥 第二步 注入脚本 第三步 定时任务 第四步 邮件通知────────────── ───────────────────── ────────────────── ──────────────────本机客户端里提取 金山文档新建表格 效率 - 高级开发 - 定时任务 结果单元格一变化refreshToken AirScript 粘贴签到脚本 每天 9:00 自动执行 自动发邮件到邮箱token + device_id 开通"网络 API"服务授权 云端执行 电脑关机也行 用 SMTP 服务实现 调试跑通拿到结果为什么选金山文档而不是本机脚本 + 系统计划任务?三个理由:
- 云端执行:定时任务由金山文档服务端触发,不依赖你的电脑开机、不依赖家里的网络,出差、断电、忘带电脑都不影响;
- 免费够用:AirScript 脚本能力 + 每天 4 次网络请求 + 一封邮件,全部在免费额度内;
- 自带邮件服务:AirScript 有现成的高级服务”SMTP API”,发邮件不用自己折腾邮件服务器。
先看最终成果——一张表格管完所有账号:
| 单元格 | 放什么 | 谁来写 | 说明 |
|---|---|---|---|
| B2 / B3 | WorkBuddy refreshToken | 手动粘贴,脚本自动轮转更新 | 两个 WorkBuddy 账号 |
| C2 / C3 | WorkBuddy 签到结果 | 脚本自动写入 | 带日期的结果文本 |
| B4 / B5 | TeleAgent token | 手动粘贴 | 两套 TeleAgent 账号 |
| D4 / D5 | TeleAgent device_id | 手动粘贴 | 与 B 列一一对应 |
| C4 / C5 | TeleAgent 签到结果 | 脚本自动写入 | 带日期的结果文本 |
| F1 | 上次邮件快照 | 通知脚本自动写入 | 用来判断”结果有没有变化” |
| F2 | 上次发信记录 | 通知脚本自动写入 | 排障用 |
二、第一步取密钥h2
签到脚本要替你向官方接口证明”我是登录状态”,所以先把两家的登录凭证从本机客户端里取出来。
2.1 WorkBuddy 的 refreshTokenh3
WorkBuddy 客户端把登录态存在一个 JSON 文件里,签到只需要其中的 auth.refreshToken 字段——一段约 700 字符的长字符串。
| 系统 | 登录态文件路径 |
|---|---|
| Windows | %LOCALAPPDATA%\CodeBuddyExtension\Data\Public\auth\workbuddy-desktop.info |
| macOS | ~/Library/Application Support/CodeBuddyExtension/Data/Public/auth/workbuddy-desktop.info |
方法一(推荐):让本机 AI 助手代取。 直接把下面这段提示词原样发给 TeleAgent 这类能读本地文件的 AI 助手,它会把完整值输出给你:
帮我提取WorkBuddy的refreshToken。读取客户端登录态文件,Windows路径是%LOCALAPPDATA%\CodeBuddyExtension\Data\Public\auth\workbuddy-desktop.info,macOS路径是 ~/Library/Application Support/CodeBuddyExtension/Data/Public/auth/workbuddy-desktop.info。只提取auth.refreshToken字段,完整输出约700字符的长字符串,不要截断、不要加引号或代码块。方法二:手动提取。 用记事本(或 VS Code)打开上面路径的文件,Ctrl+F 搜索 refreshToken,复制它后面引号内的完整值。
三个坑要避开:一是 700 字符很长,务必确认复制到了末尾,差一个字符这个凭证就废了;二是不要带上两端的引号;三是这段字符串是你的登录凭证,等于半把账号钥匙,别截图发群、别提交到仓库、别贴进公开文档。
2.2 TeleAgent 的 token 和 device_idh3
TeleAgent 这边复杂一点,签到要两个凭证配合:
- token:一段约 500 字符的 JWT,放在请求头
X-Token里; - device_id:一个 UUID 形态的设备标识,放在请求头
X-SuperAgent-Device-Id里,缺一不可。
TeleAgent 的登录态存在本机的 LevelDB 和加密凭证文件里(新版客户端在 app-auth 目录下还有一层系统级加密),手动翻文件基本不现实,所以推荐两种做法。
方法一:让 AI 助手读本机登录态。 在 TeleAgent 里直接发这段提示词:
帮我提取当前登录账号的token和device_id,完整输出,不要截断。如果你装过”teleagent-daily-points”每日签到技能,也可以让 AI 助手运行它自带的凭证提取逻辑。
方法二:用现成的提取脚本。 下面这个思路的脚本会自动定位本机 TeleAgent 数据目录(Windows 实测在用户目录下的 .config\TeleAgent 和 .local\share\TeleAgent 两个位置),把所有账号分组输出(含完整 token 和 device_id),保存为 get-teleagent-token.py 后这样运行:
$env:PYTHONIOENCODING="utf-8"; python get-teleagent-token.py脚本核心逻辑:
# 定位本机 TeleAgent 数据根目录(Windows 实测路径)HOME = os.path.expanduser("~")DATA_DIRS = [ os.path.join(HOME, ".config", "TeleAgent"), os.path.join(HOME, ".local", "share", "TeleAgent"),]
# 遍历每个账号分区,读取登录凭证# 1) 新版加密通道 users/<uid>/app-auth/token.json(DPAPI + AES-GCM 解密)# 2) 旧版 LevelDB 分区目录(正则提取 JWT 和 device_id)# 输出按账号分组:accountName / accountId / exp / 完整 token / device_id运行后输出长这样(示意,凭证值已脱敏):
---------- 账号 xxxxx (2084xxxxxxxxxxxxxx) ---------- device_id: 38b3xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx exp=2026-10-30T03:48:14 (剩余 696.0 小时) len=500 TOKEN: Em9xR4:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAi...取值规则照着下表填:
| 取什么 | 从输出里看哪里 | 填到哪 |
|---|---|---|
| token | 目标账号那一组的 TOKEN 行完整值 | B4 / B5 |
| device_id | 同一账号分组下的 device_id | D4 / D5 |
TeleAgent 这边有三个实测得出的注意点:其一,多账号机器会有残留——切换过账号的话,输出里会同时出现新旧几个账号,务必认准目标账号的 accountName 那一组,别把旧账号的凭证填进去;其二,device_id 按账号分区目录独立存储,不同账号的 device_id 可能相同也可能不同,以脚本实测输出为准;其三,token 有效期约 29 天,过期后脚本会在结果列提示 401,重新提取更新 B4/B5 即可。
2.3 凭证落表h3
回到金山文档,把上面取到的值粘进表格:
- WorkBuddy 的 refreshToken → B2、B3
- TeleAgent 的 token → B4、B5
- TeleAgent 的 device_id → D4、D5
- C 列全部留空,等脚本写入结果
粘贴时注意别带上隐藏空格和换行(从 AI 助手输出复制时偶尔会带上)。填好后这张表就”带电”了,后面三步全部围绕它转。
三、第二步注入签到脚本h2
3.1 打开脚本编辑器h3
在金山文档里打开刚才那张表格,顶部菜单找 效率 → 高级开发 → AirScript 脚本(不同版本入口名称略有差异,认准”AirScript”或”脚本编辑器”字样)。新建两个脚本文件,分别命名为 workbuddy-checkin 和 teleagent-checkin——两家脚本各自独立,互不干扰,后面定时任务也好分别管理。
3.2 WorkBuddy 签到脚本h3
完整代码直接粘贴到 workbuddy-checkin:
var API = "https://copilot.tencent.com";
function postJSON(url, headers) { var resp = HTTP.post(url, "{}", { headers: headers, timeout: 15000 }); return resp.json();}
function runCheckin(tokenCell, resultCell) { var rt = Application.Range(tokenCell).Text; if (!rt) { Application.Range(resultCell).Value2 = "失败:" + tokenCell + " 没有 refresh_token"; return; }
var r; try { r = postJSON(API + "/v2/plugin/auth/token/refresh", { "Content-Type": "application/json", "X-Refresh-Token": rt, "X-Auth-Refresh-Source": "plugin", "X-Domain": "copilot.tencent.com" }); } catch (e) { Application.Range(resultCell).Value2 = "刷新请求异常:" + e.message; return; }
if (r.code !== 0 || !r.data) { Application.Range(resultCell).Value2 = "刷新失败:" + r.msg; return; }
var at = r.data.accessToken; Application.Range(tokenCell).Value2 = r.data.refreshToken;
var msg; try { var c = postJSON(API + "/v2/billing/meter/daily-checkin", { "Content-Type": "application/json", "Authorization": "Bearer " + at }); if (c.code === 0) { msg = "签到成功 +100 积分"; } else if (c.code === 10001) { msg = "今日已签(自动跳过)"; } else { msg = "签到异常 code=" + c.code; } } catch (e) { msg = "签到请求异常:" + e.message; }
var now = new Date(); Application.Range(resultCell).Value2 = (now.getMonth() + 1) + "月" + now.getDate() + "日 " + msg;}
function main() { runCheckin("B2", "C2"); // 第一个密钥 → C2 runCheckin("B3", "C3"); // 新密钥 → C3}
main();脚本逻辑拆开讲:
- 凭证从表格读、结果往表格写:
Application.Range("B2").Text读 refreshToken,签到结果写进 C2/C3,还自动带上”几月几日”前缀,方便日后翻账; - 两段式请求:先用 refreshToken 调
/v2/plugin/auth/token/refresh换一个短时效的 accessToken(WorkBuddy 的签到接口不能直接拿 refreshToken 用);再用 accessToken 调/v2/billing/meter/daily-checkin真正签到; - refreshToken 自动轮转:这是最妙的一处——refresh 接口每次都会返回一个新的 refreshToken,脚本里
Application.Range(tokenCell).Value2 = r.data.refreshToken这行会把它直接回写进 B 列。也就是说 B 列里的凭证每次签到后都是最新的,日常不存在”过期要手动换”的问题(前提是表格保持脚本可写的状态,别给 B 列加单元格保护); - 幂等处理:服务端对重复签到返回
code=10001,脚本把它翻译成”今日已签(自动跳过)“,不会当成失败吓你一跳; - 防呆:B 列为空、网络异常、接口报错,全部会被捕获并写进 C 列,不会让脚本静默死掉——这也是第四步邮件告警能工作的基础。
3.3 TeleAgent 签到脚本h3
完整代码粘贴到 teleagent-checkin:
var API = "https://agent.teleai.com.cn/superCowork/sapi";var APP_VERSION = "2.2.3"; // 需与客户端实际版本一致(注册表 DisplayVersion 查询)
// UUID v7 风格随机串(与官方脚本 gen_nonce 同构)function genNonce() { var b = []; for (var i = 0; i < 16; i++) b.push(Math.floor(Math.random() * 256)); b[6] = (b[6] & 0x0f) | 0x70; // 版本位 = 7 b[8] = (b[8] & 0x3f) | 0x80; // 变体位 = 10 var h = b.map(function (x) { return ("0" + x.toString(16)).slice(-2); }).join(""); return h.slice(0, 8) + "-" + h.slice(8, 12) + "-" + h.slice(12, 16) + "-" + h.slice(16, 20) + "-" + h.slice(20, 32);}
function buildHeaders(token, deviceId) { return { "X-Timestamp": String(Math.floor(Date.now() / 1000)), "X-Nonce": genNonce(), "X-App-Version": APP_VERSION, "X-OS-Type": "windows", "X-SuperAgent-Device-Id": deviceId, "X-Token": token, "X-Channel-Id": "", "Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) TeleAgent/" + APP_VERSION };}
// TeleAgent 签到为 GET 接口;若运行时不提供 HTTP.get,回退 POST(需实测服务端是否接受)function httpGet(url, headers) { if (typeof HTTP.get === "function") { return HTTP.get(url, { headers: headers, timeout: 15000 }); } return HTTP.post(url, "{}", { headers: headers, timeout: 15000 });}
function todayText() { var now = new Date(); return (now.getMonth() + 1) + "月" + now.getDate() + "日";}
function runCheckin(tokenCell, deviceIdCell, resultCell) { var tk = Application.Range(tokenCell).Text; var dev = Application.Range(deviceIdCell).Text;
if (!tk) { Application.Range(resultCell).Value2 = "失败:" + tokenCell + " 没有 token(请粘贴提取结果)"; return; } if (!dev) { Application.Range(resultCell).Value2 = "失败:" + deviceIdCell + " 没有 device_id"; return; }
// 1) 先查今日签到状态(只读),今日已签则直接跳过,不发起签到请求 var s; try { s = httpGet(API + "/user/portal/companyStore/v2/checkDayTask", buildHeaders(tk, dev)).json(); } catch (e) { Application.Range(resultCell).Value2 = todayText() + " 查询异常:" + e.message; return; } if (s.code !== 200) { if (s.code === 401) { Application.Range(resultCell).Value2 = todayText() + " token 已失效,需重新提取(有效期约29天)"; } else { Application.Range(resultCell).Value2 = todayText() + " 查询失败:" + (s.msg || ("code=" + s.code)); } return; }
var dt = s.data && s.data.daily_task; if (dt && dt.claimed_today === true) { Application.Range(resultCell).Value2 = todayText() + " 今日已签(跳过),累计已领 " + (dt.total_claimed_points || "?") + " 积分,连续 " + (dt.total_claim_days || "?") + " 天"; return; }
// 2) 未签则执行签到(GET,幂等) var c; try { c = httpGet(API + "/user/portal/companyStore/checkTask?type=daily_login", buildHeaders(tk, dev)).json(); } catch (e) { Application.Range(resultCell).Value2 = todayText() + " 签到请求异常:" + e.message; return; } if (c.code === 200) { // 幂等兜底:data 为空数组表示实际已领(官方脚本注释:已领返回空数组) if (c.data && Array.isArray(c.data) && c.data.length === 0) { Application.Range(resultCell).Value2 = todayText() + " 今日已签(服务端幂等返回)"; } else { Application.Range(resultCell).Value2 = todayText() + " 签到成功 +100 积分"; } } else if (c.code === 401) { Application.Range(resultCell).Value2 = todayText() + " token 已失效,需重新提取(有效期约29天)"; } else { Application.Range(resultCell).Value2 = todayText() + " 签到异常 code=" + c.code + " " + (c.msg || ""); }}
function main() { runCheckin("B4", "D4", "C4"); // 第一套:B4=token,D4=device_id,C4=结果 runCheckin("B5", "D5", "C5"); // 第二套:B5=token,D5=device_id,C5=结果}
main();这段脚本比 WorkBuddy 的长,因为 TeleAgent 的接口校验更严格,几个关键点:
- 请求头要仿客户端:
X-Timestamp(秒级时间戳)、X-Nonce(UUID v7 风格随机数,genNonce手写实现了版本位和变体位)、X-App-Version、X-OS-Type、X-SuperAgent-Device-Id、X-Token、User-Agent一个都不能少。这套请求头与 TeleAgent 官方客户端内置的每日签到脚本同构,服务端按”这是个正经客户端”来放行; APP_VERSION要跟本机客户端实际版本对齐:客户端升级后版本号会变(Windows 下可在注册表DisplayVersion里查 TeleAgent 的版本号),版本对不上有被服务端拒绝的风险。这是这套方案里唯一需要偶尔手动维护的常量;- 先查后签:先调
/user/portal/companyStore/v2/checkDayTask只读查询今日状态,已签就直接跳过并顺便汇报”累计已领多少积分、连续多少天”;没签才调/user/portal/companyStore/checkTask?type=daily_login执行签到(幂等接口,重复调用也安全); - 401 语义:token 过期(约 29 天)会返回 401,脚本在 C 列明确写出”token 已失效,需重新提取”——配合第四步的邮件通知,到期那天你会收到一封提醒邮件,不会两眼一抹黑;
httpGet的回退:AirScript 的网络 API 提供HTTP.get;万一某个运行环境只开放了HTTP.post,代码会自动降级用 POST 打 GET 接口,实测服务端可接受。
3.4 服务授权,让脚本可以联网h3
这是整条流水线里最容易漏的一步,漏了脚本直接罢工:
- 点脚本编辑器里保存按钮旁边的”服务授权”按钮;
- 点添加服务;
- 把网络 API 加上,确认。
不加”网络 API”服务,脚本里的 HTTP 对象就是 undefined,一运行就报错。AirScript 官方文档对此有一句很直白的说明——开发者必须启用高级服务,才能在脚本中使用该服务,若跳过此步骤,会因为找不到该服务而抛出 undefined 错误。
官方文档里对应的概念叫”高级服务”,启用路径是”打开效率 - AirScript 编辑工具 - 点击上方的服务 - 添加服务 - 选择服务后确认”,和你实际操作的”服务授权”按钮是同一个东西。
3.5 点三角调试按钮,跑一次h3
加完网络 API 后,点三角形(运行/调试)按钮跑一次。首次运行会弹出网络授权对话框——描述这个脚本要访问网络——点”允许”。正常的话,C 列四格很快出现结果:
C2 10月1日 签到成功 +100 积分C3 10月1日 今日已签(自动跳过)C4 10月1日 签到成功 +100 积分C5 10月1日 token 已失效,需重新提取(有效期约29天)跑不通的话,对照这张排错表:
| 现象 | 原因 | 处理 |
|---|---|---|
报 HTTP is undefined | 没加”网络 API”服务 | 回 3.4 补上服务授权;注意改过服务配置后需重新运行并授权一次 |
| 一直转圈后超时 | 接口波动或频率限制 | 稍后再跑一次;确认 API 域名没有写错 |
| WorkBuddy 提示”刷新失败” | refreshToken 复制时截断或带了引号 | 重新完整提取,注意别带两端引号 |
| TeleAgent 返回 401 | token 过期(约 29 天)或填错账号 | 重新提取 token,认准目标账号的 accountName |
| TeleAgent 返回其他非 200 的码 | APP_VERSION 与客户端不一致 | 查本机客户端版本号,更新脚本第一行 |
| 单元格明明有值却读不到 | 粘贴时带了换行/空格 | 清空重贴,必要时把单元格格式设为常规 |
四、第三步定时任务h2
脚本手动跑通了,接下来让它自己每天跑。还在表格里操作:
- 顶部菜单 效率 → 高级开发 → 定时任务(部分版本在”AirScript 脚本”面板里有”定时任务”入口);
- 创建任务;
- 选择要运行的脚本(
workbuddy-checkin和teleagent-checkin各建一个任务); - 触发时间选一个你平时大概率不会开电脑的时间就行,比如每天早上 9 点——因为任务是金山文档云端触发的,你开不开电脑它都照跑;
- 周末也不用跳过,积分天天都能领。
两个注意点:
- 两个任务时间可以错开一两分钟(比如 9 点整和 9 点 02 分),避免同时执行偶发抢锁;不过同一张表格的脚本本来就是队列化执行的,设成同一时刻通常也没问题;
- 定时任务执行的是云端最新保存版的脚本,改完代码记得点保存,避免”编辑器里明明改了、定时任务还在跑旧版”的经典乌龙。
到这里,全自动签到的主体已经完成——从今天起,每天上午 9 点,两个工具四个账号自动领积分,你什么都不用做。
五、第四步邮件通知h2
最后一步解决”我怎么知道它今天签没签上”。需求很简单:C2、C3、C4、C5 任何一个发生变化,自动给我发一封邮件。
5.1 准备一个能发信的邮箱h3
以 QQ 邮箱为例:网页版登录 QQ 邮箱 → 设置 → 账户 → 找到 SMTP 服务 → 开启 → 按提示发短信 → 得到一个 16 位 SMTP 授权码。这个授权码就是脚本的发信密码(不是 QQ 密码)。其他邮箱(163、Outlook 等)同理,开启 SMTP 拿授权码,并记下它的 SMTP 服务器域名。
5.2 再加一个服务授权,SMTP APIh3
回到脚本编辑器的服务授权面板,点添加服务,这次把 SMTP API 加上。它和网络 API 同属 AirScript 高级服务,用法与内置函数几乎一样:SMTP.login 拿到一个 mailer 对象,再调 mailer.send 发信。
5.3 通知脚本,盯住 C2 到 C5h3
新建第三个脚本 checkin-notify,粘贴:
// 签到结果变化邮件通知:监控 C2/C3/C4/C5,内容与上次快照(F1)不同则发信
var SMTP_CONF = { host: "smtp.qq.com", // QQ 邮箱 SMTP 域名;163 是 smtp.163.com,以此类推 port: 465, // TLS 端口 secure: true, username: "你的QQ号@qq.com", // 发件邮箱 password: "你的SMTP授权码" // 设置-账户里生成的授权码,不是邮箱登录密码};var MAIL_TO = "收件邮箱@example.com"; // 收件人,一般填自己
function readResults() { var cells = ["C2", "C3", "C4", "C5"]; var names = ["WorkBuddy 1", "WorkBuddy 2", "TeleAgent 1", "TeleAgent 2"]; var lines = []; for (var i = 0; i < cells.length; i++) { var t = Application.Range(cells[i]).Text || "(空)"; lines.push(names[i] + ":" + t); } return lines.join("\n");}
function stamp() { var now = new Date(); return (now.getMonth() + 1) + "月" + now.getDate() + "日 " + now.getHours() + ":" + ("0" + now.getMinutes()).slice(-2);}
function main() { var current = readResults(); var last = Application.Range("F1").Text;
if (current === last) { // 和上次一模一样(今天已经通知过):不重复打扰 Application.Range("F2").Value2 = stamp() + " 无变化,跳过发信"; return; }
try { var mailer = SMTP.login(SMTP_CONF); mailer.send({ from: SMTP_CONF.username, to: MAIL_TO, subject: "【签到通知】WorkBuddy + TeleAgent 每日积分报告", text: current, html: "<pre style='font-family:Consolas,monospace'>" + current + "</pre>" }); Application.Range("F1").Value2 = current; // 发信成功才更新快照 Application.Range("F2").Value2 = stamp() + " 已发送通知邮件"; } catch (e) { Application.Range("F2").Value2 = stamp() + " 发信失败:" + e.message; }}
main();工作原理:
- 快照对比:把 C2~C5 四格的当前内容拼成一段文本,与 F1 里存的上次快照对比。完全一致说明今天已经通知过(或脚本重复执行),直接跳过;有任何不同——包括”签到成功”,也包括”token 已失效”这类异常——就发信,然后把新内容存回 F1;
- 实际效果是”每天一封签到日报”:因为签到结果带”X月X日”前缀,每天第一轮执行后内容必然和昨天不同,所以你会稳定收到一封汇总邮件;同一天里无论脚本重复跑多少次,都只发第一封;
- 异常天然自带告警:某天 TeleAgent token 到期,那格会从”签到成功”变成”token 已失效”,邮件里一眼就能看出来,这时按第二步重新提取凭证更新 B4/B5 就行;
- 发信失败不会丢快照:
F1只在邮件真正发出后才更新,SMTP 偶发抽风时下一轮会自动重试。
给这个脚本也建一个定时任务,时间排在两个签到脚本之后,比如 9 点 05 分——它是来”汇报战果”的,得等签到脚本先把 C 列写完。
收到的邮件长这样:
主题:【签到通知】WorkBuddy + TeleAgent 每日积分报告
WorkBuddy 1:10月1日 签到成功 +100 积分WorkBuddy 2:10月1日 今日已签(自动跳过)TeleAgent 1:10月1日 签到成功 +100 积分TeleAgent 2:10月1日 token 已失效,需重新提取(有效期约29天)5.4 只想收到异常怎么办h3
如果嫌每天一封日报烦,可以只在出问题时才收信:把 readResults 里的结果先归一化——“签到成功”、“今日已签”这类正常状态统一替换成”正常”两个字,再拿去和快照对比。这样只有出现”失败”、“异常”、“失效”字样时快照才会变化、才触发发信。改法提示:在拼接前对每行文本做一次判断,包含”成功”或”已签”就归一为”正常”,其余原样保留。
六、日常维护与安全h2
方案跑起来之后,日常要操心的只有四件事:
凭证生命周期:WorkBuddy 的 refreshToken 由脚本每次签到自动轮转回写,日常不用管;TeleAgent 的 token 约 29 天过期,收到 401 提醒邮件后重新提取、更新 B4/B5 即可,两分钟的事。唯一例外是长期(数月)完全不跑脚本,refresh 链条断掉后 WorkBuddy 的 refreshToken 也需要重新取一次。
版本号对齐:TeleAgent 客户端升级后,顺手把 teleagent-checkin 脚本第一行的 APP_VERSION 更新成新版本号。
凭证安全:这张表格里躺着四个账号的登录凭证,务必做到三条——文档不开”任何人可查看”的公开分享链接;不把这张表发给任何第三方;不运行来路不明的别人写的脚本(“服务授权”机制的存在意义就在于此:每个脚本能调哪些服务、动哪些数据,你授权时都看得到)。
平台限制:AirScript 官方文档明说了几条使用限制——网络请求禁止直接用 IP 地址、禁止带端口发起请求(所以本文脚本里的接口全是域名);响应体最大 2M;过高频率调用高级服务会抛错。本文方案一天 5 个请求 + 1 封邮件,离限制线非常远,但如果你打算把这套表格改造成更激进的自动化(比如每小时轮询),心里要有这条红线。
七、写在最后h2
回顾整条流水线:
- 取密钥:WorkBuddy 从登录态文件提 refreshToken,TeleAgent 提 token + device_id;
- 注入脚本:两段签到脚本粘进金山文档 AirScript,开通”网络 API”服务授权,调试跑通;
- 定时任务:每天 9 点云端自动执行,电脑关机也不耽误,周末照领;
- 邮件通知:SMTP 服务 + 快照对比,结果一变就发信,正常时是日报,异常时是告警。
搭建成本大约 30 分钟,之后是零维护的被动收益。更重要的是,这套”表格 + 脚本 + 定时任务 + 邮件”的架构本身就是个万能模板——把脚本里的接口和请求头换掉,任何”每日签到送福利”的服务都能套进来。
Comments