先打臉#
之前寫的通過語雀發布博客根本沒什麼用,然後在拿到 iPhone 13 pm 之後想起 iOS 似乎有一個很厲害的效率應用 Shortcuts(拿著錘子容易看到釘子?),於是整了這麼一個活,不需要寫 iOS 客戶端,直接用 iPhone 發布靜態博客。
前置知識#
用 API 更新 GitHub 倉庫#
實現這個流程首先必須知道怎麼用 API 更新 GitHub 倉庫,這個問題之前也提過,更新一個文件還是挺好理解的。
這裡再來複習一遍吧,這個步驟跟之前的文章寫的差不多不過改進了一下:
- 獲取 Ref:Ref 指 Git 的引用,Ref 指向一個 commit 會讓你更容易找到這個 commit,否則你就要用它的 SHA-1 值來尋找。例如
heads/master
就是一個 Ref,這樣你就可以用這個 Ref 找到 master 最新的提交,而不是記一串哈希值。換言之獲取 Ref 這一步做的就是獲取 最新 commit 的哈希值。 - 獲取 Commit 信息:用於獲取當前 Commit 的 tree 的 sha,在第 5 步生成 tree 的時候需要用到老 tree 的信息。
- 生成 Blob:相當於正常本地提交的 add 操作。
- 生成 Tree:構建一個新的 tree。這裡需要用到的參數 base_tree 就是來自第 2 步的 Commit 信息。(其實
/git/trees
接口允許你在這一步直接傳入 content,系統會自動幫你生成 blob,也就是少調第 3 步的一個接口) - 生成 Commit:用新的 tree 創建 commit,至此已經完成提交。
- 更新 Ref:使 master 的 Ref 指到你剛剛提交的版本。
核心代碼(函數都是調接口)差不多是這樣的:
const updateGitHubRes = async function ({
blob,
encoding,
path,
commitMessage,
}) {
const ref = await getRef()
const commitSha = ref.object.sha
const commitInfo = await getCommitInfo(commitSha)
const commitTreeSha = commitInfo.tree.sha
const blob = await createBlob(blob, encoding)
const tree = await createTree(commitTreeSha, path, blob.sha)
const newCommit = await createCommit(commitSha, tree.sha, commitMessage)
await updataRef(newCommit.sha)
}
以前的 GitHub api 文檔裡面更新倉庫的步驟是分開多個頁面的,現在看是聚合到了單個頁面,更方便查閱。另外提一下,調接口需要一個 personal access token,然後在請求頭加上 Authorization: 'token ' + process.env.GH_TOKEN
。
偷懶的方式#
後來我才在文檔中找到了更方便的更新接口 ——/repos/{owner}/{repo}/contents/{path}
用這個接口可以不管 git 提交原理直接更新 GitHub 倉庫,圖方便可以用這個。
Serverless Function#
Serverless 簡單來說就是寫個函數掛在某個地址,這個地址被訪問的時候就會跑對應的函數,在這個函數中可以獲取到請求的各種信息,處理完數據返回即可,就是一個輕量化的接口。
在這個場景中,Serverless 簡直不能再完美了,因為用 personal access token 不需要登錄系統,不存在狀態問題;而且涉及到 GitHub 的接口,用國外的服務總比自己在國內開伺服器要快。
提供 Serverless Function 的廠商很多,我還是選比較熟悉的 vercel吧,每月有白嫖額度,畢竟正常這個需求也不會用到收費的量(除非瘋狂上傳圖片)。
快捷指令#
原名 Workflow,後來成為 iOS 自帶 App,算是一個可視化的腳本工具吧。不難懂,但是需要一定時間熟悉操作(而且在 iPhone 操作有點別扭,而且經常觸發頁面抽搐 bug,感覺 iPad 會舒服多了)。
實現發布功能的核心是裡面的 Get contents of URL
步驟,基本等同於一個 Ajax 請求,可以隨意請求網絡接口,有了這個東西,玩法可以說無限多了。
除了請求網絡接口,也可以運用 url-scheme 直達本機程序藏得比較深的入口,例如可以做到一鍵打開健康碼、支付碼、掃描等功能。
指令 3 则#
下面正式分享 3 條直接在 iPhone 發博的指令,需要的 App 除了自帶的快捷指令(shortcuts)和圖庫,還有 markdown 編輯器 Taio,不需要訂閱(如果你要用記事本來寫 markdown 的話 Taio 也不需要安裝)。
新建 markdown#
本著追求高效的精神,建文件必不可能是手動的,通過下面 5 步可以簡單做到:
- 詢問文件名
- 準備一個文件模板
- 用 Taio 創建文件(可用其他編輯工具替換)
- decode 一個 url(這一步必須備註一下,不知道是 bug 還是咋地,不 decode 直接用 url 的話會提示第一步拿到的文件名不能放到 url 裡,我就納悶了,那個文件名明明就是個 text 而且都是英文,咋就不行了)
- 使用 decode 的 url 通過 Taio 打開剛創建的文件,然後完善一下信息直接開寫就可以了
上傳 markdown#
- 輸入來源是 share sheet,也就是分享功能(需要在右上角選項裡勾上在 share sheet 展示的選項)
- 填入你的發布接口地址
Get contents of URL
實際就是發 ajax 請求,數據自己決定,我是用了當前時間、文件內容、文件路徑 3 個數據- 最後是展示接口返回結果,這步也是可以沒有,因為請求報錯的話上一步就會停下來並提示你
其實還有一點可以改進,上傳的時候可以動態修改文章信息的 date,刷新文章更新時間,稍微用一點正則知識就可以了。
上傳圖片#
有人要問了,那圖片怎麼辦?有了上面的積累,這還不簡單?
在 PC 大家都很常使用 PicGo 加 jsdelivr 當圖床,在 iOS 也是一樣的。上面都已經說明了傳文件的原理,用這個接口傳圖片也是完全沒問題的,在 createBlob
的時候可以選擇 base64 即可。
流程如下:
- 在圖庫選擇圖片
- 詢問文件名
- 壓縮成 jpg(不壓的話文件非常大,而且 heic 文件可能會有的應用打不開?)
- jpg 轉 base64 傳到接口
- 填入你的發布接口地址
- 發布 base64,創建 blob 時 encoding 記得選 base64
- 展示接口返回結果
安卓呢#
在用安卓的時候確實沒有想過這個問題,但是似乎 Shortcut Maker 可以做到部分功能。但是跟其他 App 的聯動自由度估計受限。
或者直接用 github.dev,不過缺點是要科學上網,而且編輯區域窄了一點點。
寫在最後#
其實我明白,這只是整活,說不定以後這也是跟語雀發布一樣被打臉,根本用不上。
直接用手機更新的場景真的多嗎?在手機上寫一大段文字的需求確實不多,但是寫短的,又感覺沒有必要發 “博客”,充其量就是個 “微博”。
那麼要不要在這個靜態博客裡再加一個微博功能呢(其實看到很多個人博客都有這個功能)?要實現功能簡單,但是總覺得靜態頁面發一句話就跑一次構建性價比有點低,要不要直接內嵌新浪微博頁面就算了呢?
類似的還有分享圖片的問題,這個靜態博客的图区已經幾百年沒更新了,就是覺得更新體驗有點欠缺,而且缺乏圖片和文字的聯動。要不要也另外找個圖博解決這個問題?為此註冊了 Flickr 和 500px,發現免費用戶上傳圖片都有數量限制,雖然事實上也不一定能用完額度,但總覺得收到束縛。最完美的選擇 ——Instagram 也有唯一致命缺點,需要科學上網,哎,難受。
再花點時間想想吧,以前想用自己的評論系統,現在覺得用第三方的說不定更方便;以前覺得圖片都集中放在同一個項目裡管理方便,後來覺得打包浪費時間不如圖床;現在想要在博客裡做微博、把圖片放到其他社區,未來就真的不會打臉嗎?真的不知道,老是黑產品經理需求時時變,其實自己就是這麼善變。