DIY 靜態留言板

May 19, 2024

做完自己的Blog一陣子後,想說應該放一個留言的地方,自作多情的想,或許有人想留言,就來找找有哪些現成的東西。

  • DISQUS 有廣告,直接出局,還想偷我資料,哼
  • Giscus 誰想為了留言,還特地登入Gihub或是申請一個新的帳號。

由於Blog是靜態生成,開始思考能不能留言也能是靜態,或是99%靜態,因為只有1%的時候是寫入留言,其他時間只有讀取,也無需用一台主機處理讀取留言的部分。

難免會被機器人亂留言,也需要管理機制與阻擋大量留言,所以需要DB,還有條件限制。

正好在摸索 Cloudflare那就來試試看他的serverless服務,之前Blog就是build成靜態後放到他的 Pages,挑選了一下能使用的服務。

Workers

edge function,主要是用來寫入留言,本來想都寫成一支一支的function,想到之前看到的輕量框架,查了一下沒想到支援,就使用了 hono,這樣部署了一次,就可以同時寫好幾個API,資料驗證用了 zod

1. 針對文章留言

Blog的網址是用英文的title,把它轉成小寫,空白則用-取代,行話似乎叫做slug,所以用 slug當作唯一值,伴隨著留言需要填寫的資料,欄位如下

timestamp:留言時間 slug: 文章標題 message: 留言內容 name: 人名 contact_type: 聯絡方式 line, fb, email contact_content: 聯繫帳號 whoUsed: 留言者IP enabled: 顯示/隱藏

ORM採用了drizzle純TS寫的,雖然Prisma還蠻好用,但似乎在edge function好像會...有點麻煩(它的轉譯是用rust),DB用以file為主的sqlite,在cloudflare裡面稱為D1,同時會計算同一個ip在某段時間只能留N個留言,超過就會讓他等等,減少被攻擊的機會。

2. 產生token

雖然是可以匿名留言,但也不能脫光給人家打,還是做了一個簡單的token。

D1

Cloudfalre的serverless資料庫,技術是以file base的sqlite,上限為2G大小,反正應該沒這麼多人留言啦

R2

類似S3的服務,用來把每次留言後,以slug為檔名,把留言依照時間 新>舊的排序,放到一個 json檔裡面,讓Blog可以自己去讀,有就長出來。

LINE Notify

當有人留言的時候

  1. 打API
  2. 寫入D1
  3. 資料放到R2
  4. 最後就用Line通知我。 我就可以看到留言內容與留言文章網址,可以很快的過去看。

前端

使用 React和Vite,簡單寫一個頁面,用iFrame的方式嵌入,走極簡陽春風格,用tailwindcss,call api用 useQuery

可改進空間

目前刪除留言與產生新檔案還是以比較土炮的方式,未來可能會寫個bot去做刪除與產生新的留言,管理機制還需要加強。

寫一個Side project,貪心地把想玩的技術塞一塞一次滿足還蠻舒服的....小小東西疊了這麼多技術,軟體這領域的博大精深

Ekman Hsieh

文字工作者,寫作時間常常在人類與電腦之間拉鋸,相信閱讀,相信文字與思想所構築的美麗境界