原文連接:https://ssshooter.com/2019-01...javascript
偶然看到經過語雀 webhook 發佈文章到 Hexo 靜態博客,很方便,實現過程也頗有意思。一樣的原理能夠運用到 Gatsby.js 博客上。java
由於使用了 netlify,自動部署的事情就不用本身擔憂了,本文講述的有一下兩點:node
除了以上兩個重點,整個流程是:ios
在語雀發佈文章 -> 觸發語雀 webhook -> express(node.js)接收到文章推送 -> 請求信息中抽取文章內容和必要信息 -> 調用 GitHub api 更新倉庫 -> netlify 自動部署 -> 文章在博客發佈git
語雀webhook文檔 自帶完整指引,如下講講關鍵步驟。web
官方推薦使用 ngrok,ngrok 能讓你的本地服務暴露到外網,方便測試。express
個人配置:npm
app.post('/yuque/webhook', function(req, res) { console.log(req.body.data) })
此時在語雀發佈文章,接口就會收到推送的文章信息。json
使用 api 更新 GitHub 倉庫的方法能夠參考:使用 Github API 更新倉庫axios
var updateGitHubRes = function(blob, path) { var commitSha var commitTreeSha return getRef() .then(({ data }) => { commitSha = data.object.sha return getCommit(commitSha) }) .then(({ data }) => { commitTreeSha = data.tree.sha return createBlob(blob) }) .then(({ data }) => { var blobSha = data.sha return createTree(commitTreeSha, path, blobSha) }) .then(({ data }) => { var treeSha = data.sha return createCommit(commitSha, treeSha) }) .then(({ data }) => { var newCommitSha = data.sha return updataRef(newCommitSha) }) .catch(err => { console.log(err) }) } var getRef = function() { return axios.get(`/${owner}/${repo}/git/refs/heads/master`) } var getCommit = function(commitSha) { return axios.get(`/${owner}/${repo}/git/commits/${commitSha}`) } var createBlob = function(content) { return axios.post(`/${owner}/${repo}/git/blobs`, { content, encoding: 'utf-8' }) } var createTree = function(base_tree, path, sha) { return axios.post(`/${owner}/${repo}/git/trees`, { base_tree, // commit tree 的 sha tree: [ { path, // 文件路徑 mode: '100644', // 類型,詳情看文檔 type: 'blob', sha // 剛纔生成的 blob 的 sha } ] }) } var createCommit = function( parentCommitSha, tree, message = ':memo: update post' ) { return axios.post(`/${owner}/${repo}/git/commits`, { message, parents: [parentCommitSha], tree }) } var updataRef = function(newCommitSha) { return axios.post(`/${owner}/${repo}/git/refs/heads/master`, { sha: newCommitSha, force: true }) }
把接受 webhook 請求的功能和 GitHub 更新流程組合起來,有以下代碼:
app.post('/yuque/webhook', function(req, res) { console.log('web hook') var postData = req.body.data if (!postData) { console.log('nothing append') return res.json({ msg: 'nothing append' }) } var title = postData.title var date = postData.created_at var content = postData.body var tagsReg = new RegExp(/(?<=<tags>).*(?=<\/tags>)/) var removeTagsReg = new RegExp(/<tags>.*<\/tags>/) var pathReg = new RegExp(/(?<=<path>).*(?=<\/path>)/) var removePathReg = new RegExp(/<path>.*<\/path>/) var replaceBrReg = new RegExp(/<br \/>/g) var tags = content.match(tagsReg) content = content.replace(removeTagsReg, '') var postPath = content.match(pathReg) content = content.replace(removePathReg, '') content = content.replace(replaceBrReg, '\n') tags = tags && tags[0] postPath = postPath && postPath[0] var tagsString = JSON.stringify(tags.split(',')) var contentHeader = `--- path: "${postPath}" date: "${date}" title: "${title}" tags: ${tagsString} --- ` updateGitHubRes( contentHeader + content, `src/pages/${date.substring(0, 10)}-${postPath.substring(1)}/index.md` ).then(({ data }) => { console.log('finish') return res.json({ msg: 'finish' }) }) })
由於語雀沒有 tag 之類的選項,只能本身用特定標記寫到文章裏再在後端提取,而且添加信息頭部。內容組合好調用更新 api 便可完成整個流程。
若是你本身有服務器,正常部署便可,若沒有,可使用 Heroku。Heroku 能夠爲你提供免費的程序部署服務。你能夠先把上面寫好的功能上傳到 GitHub,而後從選擇從 GitHub 拉取倉庫。拉取倉庫後 Heroku 會自動運行 npm start
。
npm start
映射到 node index.js
就能夠了。
值得注意的是,heroku 的端口是系統分配的,因此須要使用環境變量提供的端口:
const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Our app is running on port ${ PORT }`); });
在語雀發佈文章便可在博客同時發佈,這確實比手寫 md 再 push 發佈只方便了一點,可是更讓人期待的是語雀移動端的上線!那麼以後就能直接在手機更新靜態博客了!不過有點地方仍是想吐槽,語雀的 md 編輯器有時候會語法失效,並且不能直接看到 md 代碼,總以爲對格式有種不能徹底控制源碼的束縛感。