先看效果
其中的內容包含了當前時間、與女友的紀念日、當天天氣、每日一句話和生活小常識(愛從小事做起)
所用到的包
"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} ${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>
<img style="position: relative;top: 8px;height: 30px;" src="https://www.dzyong.com/emailBot/images/${weather.weatherimg}" alt="">
<span>${weather.weather}</span> <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