NodeJs发送定时邮件

  • 首先初始化项目
    npm init -y
  • 首先安装本次所需要用到的所有的依赖包。
    npm install superagent cheerio art-template node-schedule nodemailer pm2 pm2-windows-service
  • 第三方依赖包的简单介绍

项目依赖包

依赖包名称 功能描述 npm 项目地址
superagent HTTP请求 查看npm项目地址
cheerio 解析HTML 查看npm项目地址
art-template 模版引擎 查看npm项目地址
nodemailer 发送电子邮件 查看npm项目地址
node-schedule 定时任务 查看npm项目地址
pm2 后台运行脚本 查看npm项目地址
pm2-windows-service / pm2-windows-startup 开机自启动

开始编码

  • 首先来看一下效果图


    效果图
  • 然后再看一下实际的模板


    模板

所以只需要将模板上对应的数据对应的填入进去即可

  1. 日期,就以编码的时间为开始时间,随后求出当次发送的时间,计算得出。
/**
 * 计算认识的天数
 */
 function getDayDate() {
   return new Promise( (resolve, reject) => {
     // 获取 当前时间
     let current = new Date()

     // 获取认识时间
     let known = new Date('2019-5-10')

     // 获取认识的时间
     let res = Math.ceil((current - known) / 1000 / 60 / 60 / 24)
     
     const format = current.getFullYear() + ' / ' + (current.getMonth() + 1).toString().padStart(2, '0') + ' / ' + (current.getDate()).toString().padStart(2, '0')

     const data = {
       countDay: res,
       currentTime: format 
     }

     resolve(data)
    })
 }
  • 随后是天气的获取 利用 superagent 和 cheerio 来进行数据爬取,爬取的网站为墨迹天气 选择自己对应的城市
 function getWeatherData(url){
   return new Promise( (resolve, reject) => {
    superagent.get(url).end( (err, res) => {
      if (err) {
       console.error('请求失败,请检查url') 
       return
      }
 
      const $ = cheerio.load(res.text)
 
      // 图标
      const icon = $('.wea_weather span img').attr('src')
      // 天气
      const weather = $('.wea_weather b').text()
      // 温度
      const temperature = $('.wea_weather em').text()
      // 提示
      const tips = $('.wea_tips em').text()
 
      const weatherData = {
        icon,
        weather,
        temperature,
        tips
      }
      resolve(weatherData)
    })
   })
 }

//  getWeatherData('https://tianqi.moji.com/weather/china/sichuan/meishan')
  • 最后是图文数据的爬取,爬取one首页的第一张轮播图片 和 下面的 文字

function getOneData() {
  return new Promise( (resolve, reject) => {
    superagent.get('http://wufazhuce.com/').end( (err, res) => {
      if (err) {
        console.error('One获取失败')
        return
      }

      // 解析加载 模板
      const $ = cheerio.load(res.text)

        
      // 获取图片链接
      const imgUrl = $('.carousel-inner>.item>img, .carousel-inner>.item>a>img').eq(0).attr('src')
      // 获取文本
      const text = $('.fp-one .fp-one-cita-wrapper .fp-one-cita a ').eq(0).text()

      const oneData = {
        imgUrl,
        text
      }
      resolve(oneData)
    })
  })
}

  • 随后将获取到的 数据 对模板进行渲染
async function renderTemplate() {
  // 获取数据
  const dayDate = await getDayDate();
  const weatherData = await getWeatherData('https://tianqi.moji.com/weather/china/sichuan/meishan');
  const oneData = await getOneData();

  // console.log(dayDate)
  // console.log(weatherData)
  // console.log(oneData)
  
  // 加载模板
  return new Promise( (resolve, reject) => {
    const html = template(path.join(__dirname, './love.html'), {
      dayDate,
      weatherData,
      oneData
    })
    resolve(html)
  })
}

应为这些都是异步操作,所有使用到 async

  • 模板生成完毕后 就可以用当前模板发送邮件
async function sendNodeMail() {
    // HTML 页面内容
    const html = await renderTemplate()
    // console.log(html);
    // 使用默认SMTP传输,创建可重用邮箱对象
    let transporter = nodemailer.createTransport({
        host: "smtp.qq.com",
        port: 465,
        secure: true, // 开启加密协议,需要使用 465 端口号
        auth: {
            user: "*******@qq.com", // 用cls户名
            pass: "********" // 授权密码
        }
    });

    // 设置电子邮件数据
    let mailOptions = {
        from: '"Aeolus" <**********@qq.com>', // 发件人邮箱
        to: "*********@qq.com", // 收件人列表,多个逗号隔开
        subject: "see you again!", // 标题
        html: html // html 内容
    };

    transporter.sendMail(mailOptions, (error, info = {}) => {
        if (error) {
            console.log(error);
            sendNodeMail(); // 再次发送
        }
        console.log("邮件发送成功", info.messageId);
        console.log("静等下一次发送");
    });
}

这里对邮箱的设置,需要开启邮箱的 IMAP/SMTP服务,拿到对应的授权码,使用对应的邮箱端口号

邮箱端口号
  • 到这一步基本功能已经实现,接下里可以开启定时服务,使用node-schedule
// 6.1 创建定时器任务
schedule.scheduleJob("0 59 23 * * *", function() {
  // 时间到了,执行发送邮件的任务
  sendNodeMail();
  console.log("定时任务的邮件发送成功");
});

第一个参数事件字符串'* * * * * *' 分别代表,秒、 分、 时、 天、 月、年 *代表每一次

  • 接下来运行既可以开启定时任务,但是这样就出现了一个问题,我们这个脚本必须要一直后台运行,才能在到达指定时间点后,发送我们指定的邮件。那么你每次开机都需要去 启动这个脚本,这是非常烦的事。这时候就可以使用另外一个非常 强大的库来帮我们托管任务 pm2
  • 全局安装pm2npm install pm2 -g
  • 启动当前任务 pm2 start main.js

这样就可以后台托管这个项目 可以打开 cmd 输入 $ pm2 list查看当前所有pm2 托管的任务

  • 随后还需要做最后一件事件,那么就是每次开机,让pm2自动启动先前托管的任务

    • 报存当前状态 $ pm2 save
    • 设置开机自启动脚本 $ pm2 startup
  • 如果是window用户需要使用其他库来生成

    • pm2-windows-service
    • pm2-windows-startup
> npm install pm2-windows-startup -g
> pm2-startup install

至此即可!

你可能感兴趣的:(NodeJs发送定时邮件)