使用 Github Actions 和 Node.js 实现定时发送穿衣建议邮件

1,434 阅读6分钟

前言

GitHub ActionsGitHub 官方提供的 CI/CD 工具,用于实现开发中的自动化流程。

GitHub actions.png

本文会介绍如何使用 Github Actions 结合 Node.js ,实现每天定时发送穿衣建议邮件。

Github Actions 简介

我们可以把 Github Actions 与前端的常用的事件监听类比。

当我们需要点击一个按钮,并执行相应的操作时,主要做了以下两件事:

  1. 监听这个按钮的 click 事件 。

  2. 一旦触发 click 事件,执行相应的函数。

Github Actions 也是同样的道理。只不过 Github Actions 监听的事件是一些常见的 Github 操作 ,包括 pushpullfork 等。一旦我们触发了这些事件,就会执行预设好的任务。这些任务包括测试,打包,发布,调用第三方服务等。

GitHub 把以上的整个流程统称为工作流( workflow ),有专门的配置文件对工作流进行配置。

下面我们就一起来新建一个配置文件。

创建配置文件

首先,我们需要在代码仓库的 Actions 一栏选择 New workflow

1617679829418.jpg

这样我们就会进入到配置文件模板页。我们可以选择使用这些模板,或者自己编写。

1618136575590.jpg

这些配置文件使用的是 YAML 格式,以 .yml 后缀结尾。以下是一个配置文件示例。

name: Build and Deploy
# 触发器
on: 
  push:
# 任务  
jobs:
  build-and-deploy:
  	# 环境
    runs-on: ubuntu-latest
    steps:
    - name: Checkout 
      uses: actions/checkout@v2.3.1
      
    - name: Install node
      uses: actions/setup-node@v2
      with:
        node-version: '14'

    - name: Add packages
      run: npm install

这个配置文件的作用是监听 push 操作,一旦我们推送代码,就会触发这个工作流。GitHub Actions 会提供的整套服务器环境,在服务器环境中读取仓库中的代码,安装 Node.js 环境并执行 npm install 命令。

结合我们之前的类比,在这个配置文件中,on 代表需要监听的事件 ,jobs 代表需要执行的任务。 Jobs 通常包含有大量内容,需要分步完成。组成 Jobs 的步骤被称为 StepsSteps 可以由多条独立的命令组合而成,这些命令被统称为 Actions

除了自己创建 Actions 之外,Github Actions 还支持引用其他开发者发布的 Actions。我们可以在 GitHubMarketplace 中找到已经发布的 Actions。也就是说常用的功能有现成的轮子可以用,就不用自己写了。这在方便开发者的同时也降低了我们的学习成本。

关于发送邮件也有现成的 Actions 可以调用,这会在后面讲到。

当我们编辑好 YAML 文件之后,选择 commit new file ,即可新建一个 YAML 文件。这个文件位于 .github/workflow 目录下。

1618138184562.jpg

现在我们已经新建了一个配置文件,可以使用 Github Actions 执行一些自动化操作了。接下来就要考虑如何发送邮件了。

发送邮件的步骤与注意事项

首先我们需要考虑两点:

  1. 如何使用 Github Actions 发送邮件。
  2. 如何获取需要发送的穿衣建议和天气信息。

关于第一点,有现成的 Actions 可以调用。

- name: Send mail
  uses: dawidd6/action-send-mail@v2
  with:
  	# smtp 服务器地址
    server_address: smtp.gmail.com
    server_port: 465
    # 账号密码
    username: ${{secrets.MAIL_USERNAME}}
    password: ${{secrets.MAIL_PASSWORD}}
    # 标题
    subject: Github Actions job result
    # 发送的内容
    body: file://README.md
    # 目标邮箱
    to: obiwan@example.com,yoda@example.com
    from: Luke Skywalker # <user@example.com>
    content_type: text/html

这个 Actions 使用了软件服务商提供的 SMTP 服务。SMTP 是指简单邮件传送协议,允许我们将邮件发送到指定的邮件服务器。腾讯,网易等邮件服务商一般会提供这种服务。我们可以去网上搜索这些软件服务商提供的 SMTP 服务器地址,将其配置在这个 Actions 中。这里的账号和密码是你使用的软件服务商的账号密码( 网易就是 163 邮箱,腾讯就是 qq 邮箱 )。为了避免将这些敏感信息暴露在代码中的尴尬,我们可以将这些信息写在仓库的 secrets 中。可以在下图所示位置配置。一切配置完成后,我们便可以发送邮件了。

1618280688921.jpg

而关于第二点,有两个坑需要注意。

第一个是使用邮件发送 html 内容被称为 html mail,这样发送的 html 文件会被屏蔽掉其中的 script 标签,也就是说,所有 JavaScript 代码都会被禁止。为了绕开这个限制,我们需要在服务端获取数据,并返回一个静态页面( SSR )。在这里我使用了 Node.js 作为服务端语言。

第二个是国内的 API 很少有能免费提供穿衣建议信息的,我找到唯一免费的 API 是和风天气的 API 。但是在 Github Actions 提供的服务器环境中,调用和风天气的 API 会报错( 可能是因为网络原因 )。为了绕开这个坑,我选择直接从中国天气网上爬取信息,这里的信息应该是准确可靠的。我们可以在中国天气网上查询到各个城市的天气信息和穿衣建议,下图红框中的内容就是成都某一天的天气信息和穿衣指数,也是我们需要获取的数据。

1618149131843.jpg

为了获取这些数据,首先我们需要获取网页的源代码。我们可以通过 axiosHTTP 库请求这个页面的 url 来拿到页面源代码,源代码是一段 html 字符串。

1618147044601.jpg

拿到源码后,我们需要分析天气信息和穿衣指数是否已经在源码中。如果不在的话,那这些数据应该是通过调用接口获取的。我们就需要在 chrome 的开发者工具中找到这些接口,再去请求这些接口获取数据。具体数据获取的代码可以查看这里

这样一来,所有的问题都解决了。以下是整个功能完整的 YAML 文件。

name: Build and Deploy
on: 
  push:
  # 定时器 可以指定时间触发工作流
  # https://crontab.guru/examples.html 有一些例子可供参考
  schedule: 
    - cron: '0 22 * * *'
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout 🛎️
      uses: actions/checkout@v2.3.1

    - name: Install node
      uses: actions/setup-node@v2
      with:
        node-version: '12'
	# 触发 node 命令
    - name: Get suggestion
      run: npm install && npm run suggestion

    - name: Send mail ✉️
      uses: dawidd6/action-send-mail@v2
      with:
      	# smtp 服务器地址
        server_address: smtp.163.com
        # smtp 服务器端口
        server_port: 465
        username: ${{secrets.MAIL_USERNAME}}
        password: ${{secrets.MAIL_PASSWORD}}
        subject: 今日穿衣建议
        body: file://index.html
        to: 598777720@qq.com
        from: hgwxxdd
        content_type: text/html
        convert_markdown: true

这个工作流会在每天早上调用 npm run suggestion 命令,从中国天气网获取信息,再使用 Node.jsfs 模块,这些信息输出到 index.html 中。随后再调用网易的 stmp 服务,将 index.html 作为邮件内容发送到我们指定的邮箱。这样一来,我们的目标便完成了。

总结

上文对使用 Github ActionsNode.js 实现定时发送穿衣建议邮件的方法进行了概述,完整的代码放在了这里

如果这篇文章对你有所帮助,或者有所启发的话,求关注!求点赞!各位的支持和认可,就是我写作的最大动力 😊