WPS 签到脚本:我的第一个百星项目
一切的起点,其实只是因为懒。
大三那年的某段时间,我每天早上的固定流程是这样的:按掉闹钟,在床上翻个身,半眯着眼睛解锁手机,然后像完成某种机械式的打卡任务一样,依次点开十几个 App。点开哔哩哔哩,进入个人中心,点击签到。退出。点开网易云音乐,左划,点击签到。退出。接着是贴吧、爱奇艺、甚至一些平时根本不怎么用的云盘应用。
这些 App 的签到按钮往往藏在层层叠叠的二级菜单里,周围还围着一圈诱导点击的广告。每天重复这套动作,大概要消耗掉我早晨宝贵的五到十分钟。时间久了,一种荒谬感油然而生。作为一名软件工程专业的学生,我每天在做的事情,居然和流水线上的计件工人没有本质区别。人类发明计算机是为了自动化,而我却在被手机里的程序当作肉鸡一样自动化地消耗着注意力。
于是我开始想,能不能写个脚本把这事自动搞定。
最开始的想法是写个 Python 脚本挂在服务器上。但看看干瘪的钱包,为了一个签到脚本去租一台云服务器,似乎有点杀鸡用牛刀。后来在做某个课设的时候,我偶然点开了金山文档。在那个网页版的 WPS 里,我发现了一个叫 AirScript 的功能。
仔细看了看文档,它的本质其实就是一个运行在云端的 JavaScript 环境。你可以直接在里面写脚本,最关键的是,它自带了定时执行的触发器,而且完全免费。不用配环境,不用买服务器,不用操心进程守护。这对我当时的需求来说,是一个近乎完美的载体。
核心逻辑其实非常简单。说白了,你在手机上点击“签到”按钮,本质上也就是客户端向服务器发送了一个带有你身份凭证的 HTTP 请求。我要做的,就是用代码把这个过程重放一遍。
那天晚上,广商的宿舍里只有敲击键盘和室友打游戏的鼠标声。我打开 Chrome 浏览器,按下 F12 进入开发者工具,在网页端登录了 B 站,然后手动点了一下签到。Network 面板里立刻跳出了一堆请求。我熟练地在一堆眼花缭乱的抓包数据里找到了那个名为 sign/in 的接口。
拿到 URL,提取出 Request Headers 里的 Cookie,剩下的就是顺理成章的体力活了。在 WPS 的代码编辑器里,我敲下了这个项目最初的几行代码。
// 以 B 站为例
function biliSign() {
const url = "https://api.bilibili.com/x/member/web/sign/in"
const headers = { Cookie: BILI_COOKIE }
const resp = HTTP.get(url, { headers })
return JSON.parse(resp.text())
}
点击运行,控制台打印出 {"code":0,"message":"0","ttl":1}。看了看 B 站网页端,经验值确实增加了。那一刻,屏幕微弱的蓝光打在脸上,心里有一种微妙的踏实感。困扰我几个月的早晨琐事,被这几行简单的代码彻底终结了。
有了第一个成功的例子,接下来的事情就变成了顺水推舟。我开始把日常用的平台一个个加进去。
做到后来,脚本里支持了十几个平台。爱奇艺、全民K歌、有道云笔记、百度贴吧、Bilibili、V2EX、AcFun、天翼云盘、Fa米家、小米运动,甚至还有百度搜索资源平台。
在这个过程中,我发现每个平台的开发团队在设计签到接口时,都有着完全不同的脑回路。有的平台很老实,只要带上 Cookie 就能直接请求成功。有的则需要走一套繁琐的 OAuth 流程,先拿 code 换 token,再拿 token 去请求。V2EX 比较讲究,每次签到还需要先请求一次网页,用正则匹配出当天的一个动态 token 才能提交。
最折腾的要数百度系的接口。他们似乎有一套非常复杂的风控策略,接口规则隔三差五就会变。有时候是加了一个时间戳参数,有时候是换了加密算法,甚至有时候会要求处理滑块验证码。有好几次,我早上醒来,看到 WPS 推送的执行日志里,百度贴吧的签到赫然飘红。于是只能无奈地再次打开 F12,重新抓包,像个解密者一样去猜测他们又改了什么逻辑。
写完这个脚本并在自己账号上稳定运行了一周后,我把它传到了 GitHub 上。仓库名叫 wps_script。
最初的日子里,这个仓库就像沉入大海的石头,没有任何波澜。这也是绝大多数个人开源项目的常态。直到半个月后的某天早晨,我习惯性地打开邮箱,发现里面躺着一封来自 GitHub 的通知。有人给我的仓库点了一个 Star。
那个头像是只卡通猫的陌生人,大概是在搜索某个平台的自动签到时,偶然发现了我的代码。这是一种很奇妙的连接感。在广州黄埔区的这间大学宿舍里写下的几百行代码,此刻正安静地躺在某个未知城市、某台未知电脑的浏览器里,替另一个人节省着每天早晨的五分钟。
慢慢地,Star 数开始往上涨。从几个,到十几个,再到几十个。
随之而来的,是 Issue 区开始有了动静。有人提问:“大佬,能不能加上 XX 平台的签到?”有人反馈:“今天爱奇艺的签到好像失败了,日志报 401 错误是怎么回事?”还有人连 Cookie 是什么都不知道,在 Issue 里问得非常基础。
面对这些,我开始学着去完善项目。我花了一整个下午的时间,把原本简陋的 README 重新写了一遍,详细说明了如何获取每个平台的 Cookie,如何配置 WPS 的环境变量,如何设置定时任务。我开始学着在代码里加入更完善的错误处理和日志输出,以防别人在运行时遇到问题不知所措。
后来,我收到了人生中的第一个 Pull Request。一位开发者帮我修复了一个由于平台接口变更导致的 bug,顺便还重构了一小段冗余的代码。我仔细地看了他的 diff,点击了 Merge 按钮。看着他的代码正式合入主分支,我突然意识到,这可能是我大学四年里,最接近真实软件工程的一次体验。
在学校里,我习惯了应对各种考试和课设。我拿到了 4.02 的绩点,拿了两次国家奖学金。这些成绩单上的数字和证书,是系统给我的反馈,证明我是一个符合标准的学生。但 GitHub 上的这些 Issue 和 PR,是真实世界给我的反馈。它们不在乎你是来自 985 还是民办三本,它们只在乎你的代码能不能跑通,能不能解决实际问题。这种脱离了象牙塔评分体系的认可,带给我的是一种截然不同的成就感。
现在,打开 wps_script 的页面,右上角的 Star 数停留在 139。
对于那些动辄几万 Star 的开源大神来说,这只是一个微不足道的数字。但对于我来说,这是我写过的被最多人使用的代码。每当想到在每天凌晨的某个时刻,云端有上百个进程同时启动,默默地执行着我写下的逻辑,替那些和我一样“懒”的人完成打卡,我就会觉得写代码这件事情,确实是有几分浪漫的。
回过头来看,这一切的起点并没有什么宏大的愿景。我没有想过要改变世界,也没有想过要造福多少开发者。我只是单纯地觉得每天手动签到很烦,想要解决自己生活中的一个小痛点。
也许很多事情都是这样。最好的开源项目,或者说最有生命力的工具,往往并不诞生于某种高瞻远瞩的规划,而是始于你自己的某一个微小的痒点。当你低下头,认真地把自己的这个痒点挠舒服了,你抬起头时可能会发现,原来周围有那么多人,也都在被同样的问题困扰着。
而你要做的,只是把那把挠痒痒的耙子,递给他们。