# 自动化签到稀土掘金,拥抱 GitHub Actions 吧

# 前言
最近儿童节刚过不久,就收到了腾讯云的扣费短信,原来是之前部署在腾讯云的SCF没有免费额度,开始付费了。根据短信提示呢,结掉了长达一天的逾期费用。比较纳闷的是,快到期了不提前通知吗,或者说临时暂停云函数都可。但是呢,不,就不,一定要先强制扣费,然后才发通知。
之前部署的腾讯云,仅仅用在简单且普遍的功能上,例如自动化脚本,或者提供功能函数等。实际上,腾讯云函数的功能还有些问题,部分配置参数没有文档,只能与在线客服沟通解决,过程中也提交了很多的改进建议。总体来说,非常繁琐,也浪费了时间,于是干脆注销了腾讯云,拥抱更加强大的 GitHub Actions (opens new window)。
以下将依赖GitHub Actions,简介自动化签到工具 稀土掘金助手 (opens new window)。
# 正文
# 目录结构
以下为各目录和文件。
├── .github
│ ├── workflows
│ │ ├── action.yml
├── .vscode
│ ├── settings.json
├── docs
├── node_modules
├── src
│ ├── juejin
│ │ ├── api.js
│ │ ├── httpInstance.js
│ │ ├── index.js
│ ├── utils
│ │ ├── dingding.js
│ │ ├── feishu.js
│ │ ├── email.js
│ │ ├── pushMessage.js
│ │ ├── pushplus.js
│ │ ├── utils.js
│ ├── ENV.js
│ ├── main.js
├── .gitignore
├── package.json
├── README.md
其中src为源码部分。
.github/workflow/action.yml:自动化定时执行代码.vscode/settings.json:vscode代码格式docs:文档node_modules:依赖包src/juejin/api.js:稀土掘金功能接口类src/juejin/httpInstance.js:axios实例,包括请求头和拦截器等src/juejin/index.js:稀土掘金类src/utils/dingding.js:钉钉机器人src/utils/feishu.js:飞书机器人src/utils/email.js:邮件src/utils/pushMessage.js:消息通知函数src/utils/pushplus.js:微信公众号pushplus推送src/utils/utils.js:工具函数,如延时函数和随机数src/ENV.js:环境变量,如COOKIE等src/main.js:主函数,入口函数.gitignore:git忽略文件package.json:包文件README.md:简介
# 接口
;juejin目录主要包括axios实例、接口类和掘金类。
;httpInstance.js内部在axios实例的基础上封装了请求头和响应拦截器。另外请求头中添加了部分浏览器标识字段,简单避免服务器确认为机器人脚本。
;api.js内部接口类Api,内部封装了稀土掘金所有的接口,包括用户信息、签到、抽奖等。
;index.js内部掘金类Juejin,继承至接口类,并封装了登录方法。确认用户是否登录方式非常简单,携带上cookie去获取用户信息,若成功获取,则表示处在登录状态下,否则表示cookie过期。
# 工具函数
目录utils内部多为消息通知的相关函数。
;pushMessage.js中用于接收消息类型和内容,消息类型type包括info和error两类,由于各消息平台的内容格式要求不一致,内容message将会被处理为markdown或者HTML格式。
;dingding.js / feishu.js为机器人通知,注意生成的webhook地址一定要包含关键字签到。
;pushplus为微信公众号推送函数。
;email.js为邮箱通知,suffix为邮箱服务后缀名,user为邮箱号,pass为POP3/SMTP服务的授权码。另外verify方法用于验证邮箱是否可用。
// src/utils/email.js
...
const suffix = /@(?<suffix>.*)/.exec(EMAIL).groups.suffix
const options = {
host: `smtp.${suffix}`,
auth: {
user: EMAIL,
pass: AUTHORIZATION_CODE,
},
}
const transporter = nodemailer.createTransport(options)
await transporter.verify()
;utils.js工具函数提供了延时函数wait和随机数函数getRandomArbitrary。
# 主函数
主函数main.js中执行main函数将依次完成签到、沾喜气、抽奖、BugFix。若运行出现错误,都会被catch捕获到,发送消息到各个平台。
;BugFix部分是模拟用户收集Bug,间隔一秒左右持续收集。
// src/main.js
const notCollectBug = await juejin.getNotCollectBug()
if (notCollectBug.length > 0) {
const requests = notCollectBug.map(bug => {
return async () => {
await juejin.collectBug(bug)
await wait(getRandomArbitrary(1000, 1500))
}
})
for (const request of requests) {
await request()
...
}
...
}
注意map内的回调函数切不可用为async的方式,此方式将立即并行所有的async函数,由于都运行了,将无法达到间隔请求的目的。
const requests = notCollectBug.map(async bug => {
await juejin.collectBug(bug)
await wait(getRandomArbitrary(1000, 1500))
})
# GitHub Actions
;GitHub Actions (opens new window) 即是一个免费的虚拟机,提供了三种可选的操作系统(Ubuntu Linux、Microsoft Windows和macOS),用以执行用户自定义的工作流程。
那么何为工作流程呢?就是一个以.yml为后缀的文件(YAML语法),注意此文件要放置在代码仓库中的目录.github/workflows下才会生效。
注意对于每个工作流程,
GitHub都会在预先配置好的全新虚拟机中执行
以下为对应的工作流。
name: Growth
on:
schedule:
# UTC 时间 0 点运行一次
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
growth:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: '16.14.2'
- name: Depend install and serve
env:
COOKIE: ${{ secrets.COOKIE }}
EMAIL: ${{ secrets.EMAIL }}
AUTHORIZATION_CODE: ${{ secrets.AUTHORIZATION_CODE }}
PUSHPLUS_TOKEN: ${{ secrets.PUSHPLUS_TOKEN }}
DINGDING_WEBHOOK: ${{ secrets.DINGDING_WEBHOOK }}
FEISHU_WEBHOOK: ${{ secrets.FEISHU_WEBHOOK }}
run: |
npm install
npm run serve
相关含义为。
name: ...:工作流程的名称on: ...:流程执行条件,schedule指定条件为时间,0 0 * * *即每天的UTC时间0点运行一次。workflow_dispatch可在GitHub仓库手动运行用于测试jobs:表示执行的一项或多项任务,当前仅有一个任务growthruns-on ...:任务growth运行的虚拟机为最新的Ubuntu Linux环境steps:任务growth的运行步骤,当前有两个步骤,包括Setup node和Depend install and serve。Setup node用于 检出 (opens new window) 仓库代码,安装 (opens new window)node环境。Depend install and serve用于安装依赖并执行脚本,其中env下为环境变量,可在GitHub仓库设置中指定,用于传入到node脚本中的process.env上
# 指南
# 派生仓库
派生(fork)仓库 (opens new window)。

创建一个同名的派生仓库,派生后仓库可自由修改。

派生成功。

# 环境机密
点击仓库的Settings菜单项,选择侧边Secrets/Actions菜单,点击New respository secret新增机密。

注意不用担心机密泄露,因为初始派生的仓库仅你自己可以操作访问,另外GitHub对Actions secrets描述也非常清晰。
Secrets are environment variables that are encrypted. Anyone with collaborator access to this repository can use these secrets for Actions.
机密是加密的环境变量,任何对存储库有协作者访问权限的人都可以使用机密。
添加环境机密名称COOKIE,Value即稀土掘金的用户cookie。

如何获取呢?
浏览器进入稀土掘金首页,键入F12开启控制台。清空Network控制信息,点击用户头像下菜单中的成长福利。

找到get_counts接口,复制全部cookie,粘贴到刚才的Value中。

# 邮箱
以常用的QQ邮箱为例,添加环境机密EMAIL,Value为邮箱地址,例如xxx@qq.com。
登录邮箱,进入邮箱首页,点击设置。

点击账户菜单。

点击开启POP3/SMTP服务,根据提示发送短信验证。

验证成功,复制授权码。

在GitHub中添加环境机密AUTHORIZATION_CODE,Value值即为授权码。
# pushplus
;pushplus (opens new window) 官网点击登录查看token。

微信扫码关注pushplus推送加公众号,关注成功后一键复制token。

;GitHub创建环境机密PUSHPLUS_TOKEN,Value值即为token。
# 钉钉
移动端发起群聊,点击面对面建群,输入较复杂的数字进入群聊。

;PC端找到群设置,点击智能群助手。

添加机器人后,点击配置按钮。

选择自定义机器人并添加。

输入机器人名字,安全设置选择自定义关键词,注意关键词一定要为签到,否则将无法收到通知。

添加成功,复制生成的Webhook地址。

然后在GitHub中添加环境机密名称DINGDING_WEBHOOK,Value为复制的Webhook地址。
# 飞书
;PC端点击创建群组。

输入群名称,点击创建。

创建成功,选择设置。

点击群机器人。

点击添加机器人按钮,选择自定义机器人。

输入机器人名称和描述。

安全设置选择自定义关键词,注意关键词一定要为签到,否则将无法收到通知。

复制webhook地址,点击完成。然后在GitHub中添加环境机密名称FEISHU_WEBHOOK,Value为复制的webhook地址。
# 启用
初始派生的仓库,点击Actions菜单的I understand my workflows, go ahead and enable them开启。

选择Growth工作流,提示中GitHub默认禁用了工作流,点击Enable workflow启用工作流。

启用成功,点击Run workflow手动运行一次工作流。

刷新页面,Growth工作流正在运行,点击查看。

点击查看growth任务。

点击Depend install and serve。

启用成功,以后GitHub将每天定时运行脚本,北京时间9点左右,时间上不是很准时,存在一定的延迟。

# 效果预览
;QQ邮箱邮件。

微信公众号pushplus。

钉钉。

飞书。

# 🎉 写在最后
🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star (opens new window) ✨支持一下哦!
手动码字,如有错误,欢迎在评论区指正💬~
你的支持就是我更新的最大动力💪~
GitHub (opens new window) / Gitee (opens new window)、GitHub Pages (opens new window)、掘金 (opens new window)、CSDN (opens new window) 同步更新,欢迎关注😉~