[Научите вас действиям на github] Отправляйте обычные электронные письма подругам каждый день

внешний интерфейс GitHub
[Научите вас действиям на github] Отправляйте обычные электронные письма подругам каждый день

Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.

адрес нажмите здесьгитхаб-адрес, добро пожаловать звезда

демонстрационная карта

WechatIMG3409.png

WechatIMG1047.png

задний план

Я думал о создании небольшого инструмента, который регулярно отправляет сообщения объектам каждый день, но я никогда не хотел покупать сервер. Однажды, как раз в разгар рыбалки, я нашел функцию на гитхабе.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

как использовать

  1. Пучокполный кодтянуть вниз

  2. Измените в нем файл конфигурации 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…

    Если вы проверяете другие области, просто замените местоположение позади

  3. Просто отправьте настроенный код в свой собственный репозиторий.


Советы: при локальном тестировании вы можете напрямую запустить сервер запуска npm, чтобы увидеть эффект почты.Не забудьте позволить объекту открыться.微信внутреннийQQ邮箱提醒功能. Основываясь на этой идее, вы также можете разработать некоторые другие гаджеты.Если у вас есть хорошие идеи, добро пожаловать в общение~