【程序员的浪漫】使用node每天定时给女友发送浪漫邮件

先看效果

其中的内容包含了当前时间、与女友的纪念日、当天天气、每日一句话和生活小常识(爱从小事做起)

    

所用到的包

   "cheerio": "^1.0.0-rc.3",        //爬取网站内容

    "node-schedule": "^1.3.2",      //定时器

    "nodemailer": "^6.3.1",      //发送邮箱

    "nodemailer-smtp-transport": "^2.7.4",

    "superagent": "^5.1.0"

目录结构

整体思路

主要分为三步:

1.爬取数据和通过API获取数据

2.处理数据,整合成要发送的模板

3.设置发送时间,发送邮件

一、获取数据

本案例中的数据来源有两个,其中的“每日一句”是通过爬取ONE的web版往网站获取的(网址:http://wufazhuce.com/

天气信息和健康小知识是通过天行API获取的(网址:https://www.tianapi.com/signup.html?source=474284281),使用前需要去申请apikey。

config/confi.js中为配置信息

module.exports = {
    MEMORIAL_DAY: '2016-09-17',  //与女朋友的纪念日
    TXAPIKEY: '', //此处须填写个人申请的天行apikey,请替换成自己的 
    
    //邮箱配置(qq邮箱)
    emailUser: "@qq.com", // 账号   你自定义的域名邮箱账号
    emailPass: "",    // 密码   你自己开启SMPT获取的密码
    toEmailList: ['[email protected]'],    // 收件列表,可同时发送给多个人
    emailSubject: '来自馒头耙耙的每日关心',   //邮件标题
}

 这里需要说明一下,上面的emailPass不是指的你的邮箱登陆密码,而是你的邮箱开启SMTP服务的密码,这里以QQ邮箱为例。

登陆QQ邮箱,点击设置->账户

往下翻,找到SMTP服务,点击开启后会弹出你的服务密码

config/superagent.js爬取页面信息

const superagent = require('superagent')

//请求
function req(url,method, params, data, cookies) {
  return new Promise(function (resolve,reject) {
	superagent(method, url)
		.query(params)
		.send(data)
		.set('Content-Type','application/x-www-form-urlencoded')
		.end(function (err, response) {
		  if (err) {
			reject(err)
		  }
		  resolve(response)
		})
  })
}

module.exports = {
  req
}

utils/cheerio.js中为获取数据,内容如下:

const cheerio = require('cheerio');
const superagent = require('../config/superagent');
const ONE = 'http://wufazhuce.com/'; // ONE的web版网站
const TXHOST = 'http://api.tianapi.com/txapi/'; // 天行host
const config = require('../config/config')

async function getOne() {
    // 获取每日一句
    try {
        let res = await superagent.req(ONE, 'GET');
        let $ = cheerio.load(res.text);
        let todayOneList = $('#carousel-one .carousel-inner .item');
        let todayOne = $(todayOneList[0])
            .find('.fp-one-cita')
            .text()
            .replace(/(^\s*)|(\s*$)/g, '');
        return todayOne;
    } catch (err) {
        console.log('错误', err);
        return err;
    }
}

async function getTXweather() {
    // 获取天行天气
    let url = TXHOST + 'tianqi/';
    try {
        let res = await superagent.req(url, 'GET', {
            key: config.TXAPIKEY,
            city: '重庆'
        }); 
        let content = JSON.parse(res.text);
        if (content.code === 200) {
            let todayInfo = content.newslist[0];
            return todayInfo;
        } else {
            console.log('获取接口失败', content.code);
        }
    } catch (err) {
        console.log('获取接口失败', err);
    }
}
async function getTXhealthtip() {
    // 获取健康小提示
    let url = TXHOST + 'healthtip/';
    try {
        let res = await superagent.req(url, 'GET', {
            key: config.TXAPIKEY,
        }); 
        let content = JSON.parse(res.text);
        if (content.code === 200) {
            let healthtip = content.newslist[0].content;
            return healthtip;
        } else {
            console.log('获取接口失败', content.code);
        }
    } catch (err) {
        console.log('获取接口失败', err);
    }
}

module.exports = {
    getOne,
    getTXweather,
    getTXhealthtip
}

二、处理数据

处理时间:utils/dateTime.js(获取当天时间、计算当天与女友纪念日的差值、格式化时间)

function getDay(date) {
  var date2 = new Date();
  var date1 = new Date(date);
  var iDays = parseInt(
    Math.abs(date2.getTime() - date1.getTime()) / 1000 / 60 / 60 / 24
  );
  return iDays;
}

function getToday(){
  let today = new Date()
  var year = today.getFullYear();
  var month = today.getMonth() + 1;
  var day = today.getDate();
  return `今天是${year}年${month}月${day}日`
}

function formatDate(date) {
  var tempDate = new Date(date);
  var year = tempDate.getFullYear();
  var month = tempDate.getMonth() + 1;
  var day = tempDate.getDate();
  var hour = tempDate.getHours();
  var min = tempDate.getMinutes();
  var second = tempDate.getSeconds();
  var week = tempDate.getDay();
  var str = '';
  if (week === 0) {
    str = '星期日';
  } else if (week === 1) {
    str = '星期一';
  } else if (week === 2) {
    str = '星期二';
  } else if (week === 3) {
    str = '星期三';
  } else if (week === 4) {
    str = '星期四';
  } else if (week === 5) {
    str = '星期五';
  } else if (week === 6) {
    str = '星期六';
  }
  if (hour < 10) {
    hour = '0' + hour;
  }
  if (min < 10) {
    min = '0' + min;
  }
  if (second < 10) {
    second = '0' + second;
  }
  return year + '-' + month + '-' + day + '日 ' + hour + ':' + min + ' ' + str;
}

module.exports = {
  getDay,
  formatDate,
  getToday
};

处理发送邮件信息:utils/email.js

// 引入email 模块
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
const config = require('../config/config')

// 开启一个 SMTP 连接池
var transport = nodemailer.createTransport(smtpTransport({
    host: "smtp.qq.com", // qq邮箱主机
    secure: true, // 使用 SSL
    secureConnection: true, // 使用 SSL
    port: 465, // SMTP 端口
    auth: {
        user: config.emailUser, // 账号   你自定义的域名邮箱账号
        pass: config.emailPass    // 密码   你自己开启SMPT获取的密码
    }
}));

function sendEmail(htmlcon) {
    // 设置邮件内容  可以拼接html 美化发送内容
    var mailOptions = {
        from: config.emailUser, // 发件地址
        to: config.toEmailList, // 收件列表
        subject: config.emailSubject, // 标题
        text: "text",
        html: htmlcon // html 内容
    }
    transport.sendMail(mailOptions, function (error, response) {
        if (error) {
            console.log("fail: " + error);
            console.log("发送失败");
        } else {
            console.log("发送成功");
        }
        transport.close(); // 如果没用,关闭连接池
    });
}

module.exports = {sendEmail}

三、设置发送时间及发送邮件

设置发送时间:utils/schedule.js

const schedule = require('node-schedule')
// date 参数

//其他规则见 https://www.npmjs.com/package/node-schedule
// 规则参数讲解    *代表通配符
//
// *  *  *  *  *  *
// ┬ ┬ ┬ ┬ ┬ ┬
// │ │ │ │ │  |
// │ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
// │ │ │ │ └───── month (1 - 12)
// │ │ │ └────────── day of month (1 - 31)
// │ │ └─────────────── hour (0 - 23)
// │ └──────────────────── minute (0 - 59)
// └───────────────────────── second (0 - 59, OPTIONAL)

// 每分钟的第30秒触发: '30 * * * * *'
//
// 每小时的1分30秒触发 :'30 1 * * * *'
//
// 每天的凌晨1点1分30秒触发 :'30 1 1 * * *'
//
// 每月的1日1点1分30秒触发 :'30 1 1 1 * *'
//
// 每周1的1点1分30秒触发 :'30 1 1 * * 1'

function setSchedule(date,callback) {
  schedule.scheduleJob(date, callback)
}
module.exports = {
  setSchedule
}

index.js入口文件

const Email = require('./utils/email')
const Schedule = require('./utils/schedule')
const DateTime = require('./utils/dateTime')
const Cheerio = require('./utils/cheerio')
const config = require('./config/config')


async function run(){
    let oneText = await Cheerio.getOne()
    let weather = await Cheerio.getTXweather()
    let healthtip = await Cheerio.getTXhealthtip()
    let today = DateTime.getToday()
    Email.sendEmail(`<div style="position:relative;background:-webkit-linear-gradient(-45deg,  #5edac1 0%,#327dda 100%,#1a7a93 100%);width:100%;padding-bottom: 30px;" >
    <div style="padding: 15px;color: #237ecc;">
        <p style="font-size: 18px;margin: 10px 0;">${today}&nbsp;&nbsp;&nbsp;&nbsp;${weather.week}</p>
        <p style="font-size: 28px;color: #2a8bde;margin: 10px 0;">和馒头耙耙相恋的第<span style="color: #dabf5e;"> ${DateTime.getDay(config.MEMORIAL_DAY)} </span>天</p>
    </div>
    <div style="padding: 10px 25px;color: #fff;">
        <div>
            <span style="font-size: 48px;font-weight: 700;">${weather.lowest}~${weather.highest}</span>&nbsp;
            <img style="position: relative;top: 8px;height: 30px;" src="https://www.dzyong.com/emailBot/images/${weather.weatherimg}" alt="">
            <span>${weather.weather}</span>&nbsp;&nbsp;<span>${weather.wind}${weather.windspeed}</span>
        </div>
        <p>
            ${weather.tips}
        </p>
    </div>
    <P style="color:#fff;font-weight:900;text-align:center;bottom:100px;width: 100%;font-size: 30px;text-shadow:3px 2px 2px rgba(1,138,110,.6);margin: 50px auto;">
       ${oneText}
    </P>
    <div style="margin: 5px 45px;padding: 10px; margin-top: 55px;line-height: 1.8em;background: rgba(240,240,240,.2);border-radius: 8px;">
        <span style="color: bisque;">生活小常识:</span>
        <span style="color: #e6dbdb;">
            ${healthtip}
        </span>
    </div>
    </div>
</div>`)
}

Schedule.setSchedule("0 17 * * * *",function(){
    run()
})

最后执行 node index.js,女朋友就会在指定的时间收到来自你的每日关系啦,当然如果想要每天发送需要部署到云服务器上,这样你就不用管它了,到点自动发送

后期我会对该项目新增更多功能(可在网站随时修改发送人、收件人、发送时间等信息,可自定义发送内容等功能),感兴趣的小伙伴可以点个关注。

源码:https://github.com/DengZhanyong/emailBot    (觉得还不错的话就给我个star,你们的支持是我进步的动力)

本人个人博客网站:www.dzyong.com

发布了64 篇原创文章 · 获赞 45 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/DengZY926/article/details/103143798