小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
地址戳这里github地址,欢迎star
演示图
背景
一直考虑做一个每天定时给对象发信息的小工具,但是一直没舍得买服务器。某天,正当我热火朝天地摸鱼时,发现了github上的一个功能github actions
,相当于一个自带服务器的持续构建功能,并且既可以发布定时任务,每个月又有白嫖的分钟数,岂不是正和我意?起飞~
思路
整体基于node开发,并且引入三个npm库:
nodemailer
发送邮件node-fetch
请求接口数据dayjs
计算日期
主要逻辑代码如下:
// index.js
const fetch = require('node-fetch');
const dayjs = require('dayjs');
const utc = require('dayjs/plugin/utc');
const timezone = require('dayjs/plugin/timezone');
const sendEmail = require('./sendEmail');
const emailHtml = require('./emailHtml');
// 给dayjs添加时区选项
dayjs.extend(utc);
dayjs.extend(timezone);
const {
fromDisplayText,
fromDisplaySubText,
user,
to,
weatherKey,
location,
type,
tianXingKey,
startDay,
} = require('./config');
async function init() {
try {
// 获取天气信息
const weatherRes = await fetch(
`https://devapi.qweather.com/v7/weather/3d?key=${weatherKey}&location=${location}`
);
const weatherData = await weatherRes.json();
// 获取天气生活指数
const lifeRes = await fetch(
`https://devapi.qweather.com/v7/indices/1d?key=${weatherKey}&location=${location}&type=${type}`
);
const lifeData = await lifeRes.json();
// 获取one一个文案及图片
const oneRes = await fetch(
`http://api.tianapi.com/txapi/one/index?key=${tianXingKey}`
);
const oneData = await oneRes.json();
const { word, imgurl } = oneData.newslist[0];
// 计算日期
const lovingDays = dayjs(dayjs().tz('Asia/Shanghai')).diff(
startDay,
'days'
);
// 用邮件模版生成字符串
const htmlStr = emailHtml(weatherData, lifeData, word, imgurl, lovingDays);
// 发送邮件;
sendEmail({
from: fromDisplayText,
to,
subject: fromDisplaySubText,
html: htmlStr,
});
} catch (e) {
// 发送邮件给自己提示
sendEmail({
from: '报错啦',
to: user,
subject: '定时邮件-报错提醒',
html: '请查看github actions',
});
}
}
init();
复制代码
主要就是请求接口数据,然后用接口数据生成需要的html,最后发送邮件。
1、生成需要的邮件
function fn(weatherData, lifeData, word, imgurl, lovingDays) {
const { daily: weatherDataDaily } = weatherData;
const { daily } = lifeData;
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div>
<!-- 天数 -->
<div>
<p>今天是在一起的第${lovingDays}天!</p>
</div>
<!-- 图片 -->
<div>
<img
style="width: 100%; max-width: 768px"
src="${imgurl}"
alt="图片"
/>
</div>
<!-- 每日一句 -->
<div>
<p style="font-size: 14px; text-indent: 2em; font-style: italic;">
${word}
</p>
</div>
<!-- 天气 -->
<div>
<p>
<b>今日气温:</b>
<span>${weatherDataDaily[0].tempMin}°C - ${weatherDataDaily[0].tempMax}°C</span>
</p>
<ul>
<li style="margin-bottom: 10px">
${daily[1].name}(${daily[1].category}):
${daily[1].text}
</li>
<li style="margin-bottom: 10px">
${daily[2].name}(${daily[2].category}):
${daily[2].text}
</li>
<li style="margin-bottom: 10px">
${daily[0].name}(${daily[0].category}):
${daily[0].text}
</li>
</ul>
</div>
</div>
</body>
</html>
`;
}
module.exports = fn;
复制代码
2、发送邮件
const nodemailer = require('nodemailer');
const { user, pass } = require('./config');
const sendMail = async (data) => {
let transporter = nodemailer.createTransport({
host: 'smtp.qq.com',
port: '465',
secureConnection: true,
auth: {
user,
pass,
}
});
data.from = `"${data.from}" ${user}`;
await transporter.sendMail(data);
};
module.exports = sendMail;
复制代码
3、指定定时任务
需要在根目录创建一个.github
文件夹,然后在.github
文件夹中再新建一个workflows
文件夹,然后在里面任意创建一个yml
格式的文件,文件内容如下:
name: ccy-helper
on:
schedule:
- cron: "00 23 * * *" # 该时间为UTC时间,比北京时间晚8个小时,每天早上7点自动执行(需要注意该时间不准时,会有不同程度的分钟数的延迟)
jobs:
send:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- name: Run Project
run: npm install && npm run server # 安装依赖并执行server
复制代码
如何使用
-
把完整代码拉下来
-
修改其中的config.js配置文件
扫描二维码关注公众号,回复: 13165016 查看本文章// 配置信息 module.exports = { fromDisplayText: '阳哥', // 收件箱展示的来件人名字 fromDisplaySubText: '每日提醒', // 收件箱展示的次级标题 user: 'xxx', // 发送者邮箱 pass: 'xxx', // 发送者邮箱MTP协议密码(很简单,进邮箱设置下就有了) to: 'xxx', // 发送到谁,填邮箱 weatherKey: '33369e365fe84eb68876f52a2ae51cca', // 和风天气key location: 'xxx', // 和风天气-地区的id,如:101270119 type: '1,3,9', // 和风天气-生活指数type tianXingKey: 'eb75297818f2413f24e1f1f76662bccd', // 天行数据的key startDay: '2015-09-29', // 在一起的日期 } 复制代码
和风天气key
和天行数据的key
可以直接用我的,也可以自己申请个账号,每天都有免费的额度。和风天气查询地区的id可以看该文档:dev.qweather.com/docs/api/ge…
例如查询北京的:geoapi.qweather.com/v2/city/loo…
查其他地区的话,替换后面的location就好
-
将配置好的代码提交到自己的仓库就好了
Tips:本地测试的时候直接执行npm run server就可以看邮件效果,记得让对象打开微信
里的QQ邮箱提醒功能
。基于此思路你也可以开发一些其他的小工具,要是你有好的想法,欢迎一起交流~