原文连接: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 代码,总以为对格式有种不能彻底控制源码的束缚感。