# 自动化签到稀土掘金,拥抱 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.jsonvscode代码格式
  • docs:文档
  • node_modules:依赖包
  • src/juejin/api.js:稀土掘金功能接口类
  • src/juejin/httpInstance.jsaxios实例,包括请求头和拦截器等
  • 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:主函数,入口函数
  • .gitignoregit忽略文件
  • package.json:包文件
  • README.md:简介

# 接口

  ;juejin目录主要包括axios实例、接口类和掘金类。

  ;httpInstance.js内部在axios实例的基础上封装了请求头和响应拦截器。另外请求头中添加了部分浏览器标识字段,简单避免服务器确认为机器人脚本。

  ;api.js内部接口类Api,内部封装了稀土掘金所有的接口,包括用户信息、签到、抽奖等。

  ;index.js内部掘金类Juejin,继承至接口类,并封装了登录方法。确认用户是否登录方式非常简单,携带上cookie去获取用户信息,若成功获取,则表示处在登录状态下,否则表示cookie过期。

# 工具函数

  目录utils内部多为消息通知的相关函数。

  ;pushMessage.js中用于接收消息类型和内容,消息类型type包括infoerror两类,由于各消息平台的内容格式要求不一致,内容message将会被处理为markdown或者HTML格式。

  ;dingding.js / feishu.js为机器人通知,注意生成的webhook地址一定要包含关键字签到

  ;pushplus为微信公众号推送函数。

  ;email.js为邮箱通知,suffix为邮箱服务后缀名,user为邮箱号,passPOP3/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 LinuxMicrosoft WindowsmacOS),用以执行用户自定义的工作流程。

  那么何为工作流程呢?就是一个以.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:表示执行的一项或多项任务,当前仅有一个任务growth
  • runs-on ...:任务growth运行的虚拟机为最新的Ubuntu Linux环境
  • steps:任务growth的运行步骤,当前有两个步骤,包括Setup nodeDepend install and serveSetup 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新增机密。

  注意不用担心机密泄露,因为初始派生的仓库仅你自己可以操作访问,另外GitHubActions secrets描述也非常清晰。

Secrets are environment variables that are encrypted. Anyone with collaborator access to this repository can use these secrets for Actions.
机密是加密的环境变量,任何对存储库有协作者访问权限的人都可以使用机密。

  添加环境机密名称COOKIEValue即稀土掘金的用户cookie

  如何获取呢?

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

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

# 邮箱

  以常用的QQ邮箱为例,添加环境机密EMAILValue为邮箱地址,例如xxx@qq.com

  登录邮箱,进入邮箱首页,点击设置。

  点击账户菜单。

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

  验证成功,复制授权码。

  在GitHub中添加环境机密AUTHORIZATION_CODEValue值即为授权码。

# pushplus

  ;pushplus (opens new window) 官网点击登录查看token

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

  ;GitHub创建环境机密PUSHPLUS_TOKENValue值即为token

# 钉钉

  移动端发起群聊,点击面对面建群,输入较复杂的数字进入群聊。

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

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

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

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

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

  然后在GitHub中添加环境机密名称DINGDING_WEBHOOKValue为复制的Webhook地址。

# 飞书

  ;PC端点击创建群组。

  输入群名称,点击创建。

  创建成功,选择设置。

  点击群机器人。

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

  输入机器人名称和描述。

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

  复制webhook地址,点击完成。然后在GitHub中添加环境机密名称FEISHU_WEBHOOKValue为复制的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) 同步更新,欢迎关注😉~

最后更新时间: 11/13/2022, 10:11:44 PM