Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.
адрес нажмите здесьгитхаб-адрес, добро пожаловать звезда
демонстрационная карта
задний план
Я думал о создании небольшого инструмента, который регулярно отправляет сообщения объектам каждый день, но я никогда не хотел покупать сервер. Однажды, как раз в разгар рыбалки, я нашел функцию на гитхабе.github actions
, что эквивалентно непрерывной конструкции конструкции со своим собственным сервером, и она может выпустить запланированные задачи, и каждый месяц есть несколько минут бесплатной проституции. Разве это не то, что я хочу? Снять ~
идеи
Общая разработка основана на узле, и представлены три библиотеки 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
// 配置信息 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
Вы можете использовать мою учетную запись напрямую или подать заявку на учетную запись самостоятельно, каждый день есть бесплатная квота.См. этот документ для идентификатора области запроса погоды Zephyr:Dev.Q Weather.com/docs/API/…
Например, чтобы запросить Пекин:Geo API.Q Weather.com/V2/city/Ooh…
Если вы проверяете другие области, просто замените местоположение позади
-
Просто отправьте настроенный код в свой собственный репозиторий.
Советы: при локальном тестировании вы можете напрямую запустить сервер запуска npm, чтобы увидеть эффект почты.Не забудьте позволить объекту открыться.微信
внутреннийQQ邮箱提醒功能
. Основываясь на этой идее, вы также можете разработать некоторые другие гаджеты.Если у вас есть хорошие идеи, добро пожаловать в общение~