一次追蹤最新疫情數據的嘗試-每日郵件

寫在前面

這段時間疫情還在持續,你們出門記得戴口罩javascript

靈感來源: 爲抗擊新肺炎貢獻一份技術力量html

訪問網址:前端

從而有了文中網站和這篇文章,說來~寫文章花的時間可能比項目自己還要多點vue

一點感覺:

此次疫情來勢洶洶,從街上的反應,家裏長輩也都戴上口罩等情形看來,狀況比想象中更要嚴峻一些,如今也到了關鍵的十來天,但願能儘快將控制住,待一切安好java

關於這個網站的原型網上已經有不少版本了,決定開寫一方面來自於假期的庸長與慌悶,另外一方面也但願能引發更多人的重視,多一個渠道也好,多一份關注的力量node

數據來源:

網站內數據來源於丁香醫生,央視新聞等官方渠道,數據與官方渠道保持更新git

介紹

本網站開發主要採用Javascript語言,數據採集後端採用上文提供的接口基礎上進行開發,增長郵件管理方面的接口,郵件發送採用nodemailer庫,網站前端則採用了vue和element-ui這倆常見組合。程序員

網站頁面

PC端 移動端
iPhone
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

項目結構

後臺 前端
項目後端結構
在這裏插入圖片描述

關於郵件

關於天天疫情的數據採集,省市數據,闢謠等部分,可參考原做者@普通程序員 連接:juejin.im/post/5e2c6a…. 寫的時候原做者還沒放出郵件部分的代碼,因此我嘗試着寫了下,沒有原做者寫的規範全面,不過基本的郵件發送和訂閱管理(主要是添加,取消,查詢)也是實現了,而且能經過網站前端進行訂閱的相關操做,可供參考npm

主要思路

  1. 分開兩個進程,一個定時任務,讀取郵件列表發送郵件,一個http服務
  2. http服務感知用戶的增/刪/查操做
  3. 對郵件列表Json進行相應操做

因爲兩個進程分離開來,用戶前端請求不會影響郵件列表的維護,反之亦然,進程守護一樣採用原文中的pm2 讀取郵件部分比較簡單,直接貼代碼了,關鍵代碼在json和nodemailer接收的數據格式轉換,須要從數組轉爲字符串(line 6),其餘部分按照nodemailer配置來就能夠element-ui

async function sendMailForHtml(title, text) {
	// 當天日期
	let now = moment();
	let today = now.clone().add(0, 'days').format('YYYY-MM-DD');
	let toListFile = await fs.readJSON('data/mail.json')
	let toListInit = toListFile.toList.join(',') // array轉str 
	let mailOptions = {
		from: emailName, // 發件地址
		to: toListInit, // 收件列表
		subject: `${title}(${today})`, // 標題 
		html: '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'+ text // html 內容
	};

	transporter.sendMail(mailOptions, function(error, info) {
		if(error) {
			return console.log('郵件發送出錯', error);
		}
		console.log('Message sent: ' + info.response);
	});
}
複製代碼

至於郵件的發送,相比原做者的「diff」推送方式,我採用了相對簡單粗暴的定時發送方式

// 每週1-7的6點和12點,18點執行
let rule = new schedule.RecurrenceRule();
rule.dayOfWeek =[1,2,3,4,5,6,7];
rule.hour =[6,12,18];
rule.minute =0;
rule.second =0;
schedule.scheduleJob( rule, () => {
    readyMail()
  })
複製代碼

能夠看到,經過node-schedule庫的定時函數,設定爲天天的3個時段運行,你們若是有不一樣的定時需求,直接修改這個任務函數便可

關於郵件訂閱的管理

對於郵件訂閱的一些需求,我寫了三個對應的處理,分別爲基本的添加,取消還有查詢,請求處理方式沿用了原文的koa路由方式,邏輯主要集中在對郵件格式的驗證和去重方面,這裏以刪除爲例,添加和查詢的處理寫法也大都類似,詳細可見 本項目源碼

// GET 刪除郵箱名 status=>10(出現錯誤) status=>2(正常)
router.get('/mail/cut/:mail', async (ctx, next) =>{
    let mail = ctx.params.mail || ''
    let reg = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
    let isEmail = reg.test(mail) ? true : false
    let checkResult = await checkMail(mail) 
    console.log('格式', isEmail)     
    // 檢查格式 
    if(!isEmail) {
        ctx.response.body = { error: '郵件格式不正確,攔截請求', status: 10 }    
        return
    }     
    // 不存在則跳過
    if ( !checkResult ){
        ctx.response.body = { warn: '郵箱名不存在,攔截請求', status: 10  }
        return
    }
    let fileData = await fs.readJSON('./resource/mail.json')
    let mailList = fileData.toList
    let index = mailList.findIndex( item => item === mail ) // 肯定索引
    if(index>-1){
        mailList.splice(index, 1)
        let resultObj = { "toList": mailList }
        await fs.writeJSON('./resource/mail.json', resultObj )     //保存MAIL數據
        ctx.response.body = { data: '刪除mail ok', status: 2 }
    }else{
        ctx.response.body = { data: '刪除mail 失敗 不存在郵箱/未知錯誤', status: 10 }
    }      
});
複製代碼

順帶說下,這裏的status是我在這個項目里人爲約定的狀態,與http協議狀態無關,因項目規模小,約定了僅有0,1,10,2這幾種狀態,分別表明了有/無,出錯和成功這幾種狀況供前端識別。

如何自定義郵箱發送方

目前網站已支持郵件的訂閱發送和取消等管理,若是須要將本身的郵箱做爲發送方的小夥伴,能夠這裏看下項目裏面須要配置的地方

主要的配置入口在項目根目錄的mail.js裏

const transporter = nodemailer.createTransport({
	service: 'qq',
	port: 465, // SMTP 端口
	secureConnection: true, // 使用 SSL
	auth: {
		user: emailName,
		pass: emailPassword
	}
});
複製代碼

這裏以Q Q郵箱爲例,採用其餘郵箱的小夥伴可能要自行更改協議端口了 具體的emailName和password,以及接收郵件名,我採用了外置的配置文件和批量發送的方式。 外置的配置文件位於 resource/mailConfig.js下,而 resource/mail.json裏面的郵件列表則做爲真正要發送的郵箱列表,至於鏈接二者的橋樑在於sendMailForHtml函數中

下面截取了這段函數中對二者的鏈接代碼

let toListFile = await fs.readJSON('./resource/mail.json')
	let toListInit = toListFile.toList.join(',') // array轉str 
	let mailOptions = {
		from: emailName, // 發件地址
		to: toListInit, // 收件列表
		...            }
複製代碼

實際部署中,利用前面說到的http請求方式便可添加/刪除對應郵箱,而須要手動更改的時候直接修改 resource/mail.json裏面的郵箱列表便可

如何愉快的跑起來

部署這塊其實相對簡單,前提是系統環境,項目依賴都裝好沒問題的前提下,這裏貼下我目前服務器部署的基本環境供你們參考

Node.js=>10.15.0

pm2=>3.2.9

npm=> 6.4.1

確保環境和依賴安裝好後,接下來就是進入項目根目錄下經過pm2啓動相應進程

pm2 start app.js
pm2 start server.js
複製代碼

亦可經過原文中的PM2配置文件方式啓動,建議在開發環境下,像上面那樣單獨啓動較爲合適,方便隨時停用程序和作調試等等

關於前端和結語

本項目後臺源碼已發佈 連接 gitee.com/dunye/nCov_…

跟項目配套的前端網站也已上線,網址: cookcloud.club

小夥伴們能夠直接在上面的網站上添加取消訂閱,前端源碼在整理當中稍後會更新在這篇文章的下方,有須要的小夥伴能夠先本身部署後臺的程序,至於前端其實能夠有不少的實現方式,這個項目的關鍵也在於後臺的處理,你們能夠嘗試用不同的頁面風格去對接上項目後臺。

對於項目的相關問題,小夥伴們能夠在下方評論區留言 ~ 一塊兒探討學習進步

相關文章
相關標籤/搜索