部落格搭建詳解(三)-Node.js+自動化部署+郵件提醒

RyzeYang發表於2020-06-27

我的個人網站 www.ryzeyang.top

內容概覽
在阿里雲伺服器上使用node.js搭建webhook服務,實現自動部署和郵件提醒。

Node.js

簡介

Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
Node.js
Node.js中文網

特點

  1. 事件驅動
    • 這個是Node.js設計的核心思想
    • 事件驅動就是 當某個事件發生時,才去執行這個回撥函式,而註冊的回撥函式都是非同步執行的,這樣充分利用了計算機的資源。
  2. 非同步,非阻塞IO
  3. 單執行緒
    • 我們寫的程式碼都在一個主執行緒裡面,其他的都線上程池裡,這樣保證了執行緒的安全。
  4. 實時性

使用

  1. 安裝
    下載地址 https://nodejs.org/zh-cn/download/
    博主的版本是node-v12.14.0-linux-x64,執行下面的程式碼解壓檔案,

    xz -d node-v12.14.0-linux-x64.tar.xz
    tar -xf node-v12.14.0-linux-x64.tar
    

    接著執行以下程式碼 建立軟連線(根據自己Node.js文件的路徑)

    ln -s ~/node-v12.14.0-linux-x64/bin/node /usr/bin/node
    ln -s ~/node-v12.14.0-linux-x64/bin/npm /usr/bin/npm
    ln -s ~/node-v12.14.0-linux-x64/bin/npm /usr/bin/npx
    

    在其他目錄下輸入node -v可以看到版本資訊即安裝成功。

  2. npm
    npm是Node.js的包管理工具,隨著node.js一起安裝的。
    使用淘寶映象安裝模組會更快(同步頻率目前為10分鐘一次以保證儘量與官方服務同步。)
    npm install -g cnpm --registry=https://registry.npm.taobao.org

Node.js有很多框架可以使用,如Express,Koa,Socket Stream等等。

自動化部署的實現

資料準備

可以看看上篇博文中關於gitee webhook這一塊,還有下面兩個文件
WebHook 推送資料格式說明
WebHook 金鑰驗證和驗證演算法

加密演算法
不可逆 : MD5、SHA1、SHA256、SHA512
可逆 :對稱加密和非對稱加密

git 更新指令碼

在阿里雲伺服器上建個指令碼 pull.sh
內容如下

# cd到部落格目錄
#git fetch 指令是下載遠端倉庫最新內容,不做合併 
#git reset 指令把HEAD指向master最新版本
cd ~/hexo_blog  
git fetch --all
git reset --hard origin/master

格式化時間指令碼

dateFormat.js

function dateFormat(fmt, date) {
    let ret;
    const opt = {
        "Y+": date.getFullYear().toString(),        // 年
        "m+": (date.getMonth() + 1).toString(),     // 月
        "d+": date.getDate().toString(),            // 日
        "H+": date.getHours().toString(),           // 時
        "M+": date.getMinutes().toString(),         // 分
        "S+": date.getSeconds().toString()          // 秒
        // 有其他格式化字元需求可以繼續新增,必須轉化成字串
    };
    for (let k in opt) {
        ret = new RegExp("(" + k + ")").exec(fmt);
        if (ret) {
            fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
        };
    };
    return fmt;
}
module.exports=dateFormat;

自動化部署指令碼

webhook.js

/**
author: Ryzeyang
description:  node.js實現自動化部署,同時使用qq郵箱通知部落格更新情況
*/
var http=require("http");
var dateFormat=require("./dateFormat");
var execSync = require('child_process').execSync; //同步
var nodemailer = require('nodemailer');

// npm install nodemailer --save  

var transporter = nodemailer.createTransport({
    //https://github.com/andris9/nodemailer-wellknown#supported-services 支援列表
    service: 'qq',
    port: 465, // SMTP 埠
    secureConnection: true, // 使用 SSL
    auth: {
        user: 'qq@qq.com',
        pass: 'smtp密碼'  //不是qq密碼,是你設定的smtp密碼
    }
});
		
var status='failed';
var message='';
	
http.createServer(function(req,resp){
    var headers=req.headers; //獲取請求頭中的資訊
    var agent=headers['user-agent'];  //拿到UA
    if(agent=='git-oschina-hook'){ //判斷是不是來自gitee

        var timestamp=headers['x-gitee-timestamp'];  
        var token=headers['x-gitee-token'];  
        
        /**
        *  加密演算法的實現  HmacSHA256演算法(不可逆的)
        */
        const crypto = require('crypto');
        const secret="webhook上的祕鑰"; 
        var hmac=crypto.createHmac("sha256",secret);
        var content=hmac.update(timestamp+"\n"+secret);
        var cryptoContent=content.digest("base64");
        
        //console.log("sha256(Hmac方式)加密後結果:%s",cryptoContent);
        var s ='';
        if(token==cryptoContent){
            
            s=execSync('./pull.sh').toString(); //執行更新倉庫的指令碼
            console.log(s.toString());
            status='successfully';
        }

        message="call webhook  at "+dateFormat("YYYY-mm-dd HH:MM", new Date()) ;
        console.log(message);
        
        var mailOptions = {
            from: '@qq.com', // 發件地址
            to: '@qq.com', // 收件列表
            subject: 'Update blog '+status, // 標題
            //text和html兩者只支援一種
            //  text: 'Hello world ?', // 標題
            html: '<b>'+message+'</b> <br> <b>'+s+'</b>' // html 內容
        };
        
        transporter.sendMail(mailOptions, function(error, info){
            if(error){
                return console.log(error);
            }
            console.log('Message sent: ' + info.response);
        });
    }
    resp.writeHead(200,{"Content-Type":"text/plain"});
    resp.end("ok\n"); 
}).listen(8080);
console.log("Server run at 8080 at %s",dateFormat("YYYY-mm-dd HH:MM", new Date()) );

啟動命令

將三個指令碼放在同個資料夾下,執行以下命令即可。
nohup node webhook.js & //後臺執行 log會記錄在當前資料夾中的nohup.out

相關文章