美文网首页
NodeJs发送定时邮件

NodeJs发送定时邮件

作者: 了凡和纤风 | 来源:发表于2019-05-23 12:52 被阅读0次
    • 首先初始化项目
      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用户需要使用其他库来生成

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

    至此即可!

    相关文章

      网友评论

          本文标题:NodeJs发送定时邮件

          本文链接:https://www.haomeiwen.com/subject/udjvzqtx.html