
語言 🇹🇼 繁體中文
Val Town 安裝
為 Val Town 應用程式新增即時評論功能
Val Town 在 Deno 上執行 TypeScript,因此 val 是一個真實的伺服器。這使它非常適合 FastComments:小工具是頁面上的 script 標籤,任何需要機密的功能,如 Secure SSO 或驗證 webhook,都可以在同一個 val 的伺服器端執行。
本指南說明如何將評論小工具加入 HTTP val、在索引頁面顯示評論計數、使用他們已擁有的 Val Town 帳號登入使用者,以及接收評論 webhook。
您不需要帳號即可試用。範例使用 tenantId: "demo",這是一個共享的 sandbox,第二步說明如何切換到您自己的環境。
步驟 1:新增小工具 
The widget is a script tag and a container element, so it drops into whatever your val already renders. This example uses Hono JSX, which is what Val Town's HTTP templates use.
Run 
在上線前選擇 urlId
urlId decides which thread a comment lands in. Leave it unset and it defaults to a cleaned version of the current page URL, which is exactly the thing that changes on Val Town: a val has a long *.web.val.run hostname until you claim a subdomain, branches get their own URLs, and renaming a page changes the path. Each variation silently becomes a separate, empty thread, and the symptom reads as "my comments disappeared".
Set it to something stable that you control, like the post slug or a database id, as above. Pass url too, so notification emails and the moderation tools can link back to the real page.
在沒有 JavaScript 時保留評論
FastComments renders a full thread server-side, which a val can drop into a <noscript> block:
Run 
URL-encode the parameters. The server-side version supports anonymous and logged-in commenting, SSO, and nested replies.
步驟 2:使用您自己的帳戶 
tenantId: "demo" 是一個共享的公共沙盒。它無需註冊即可運作,這也是範例使用它的原因,但其他所有使用 FastComments 的人都會寫入相同的討論串,且任何人都可以對其進行審核。請在發布任何重要內容之前切換。
您的租戶 ID 位於 API 密鑰頁面。
租戶 ID 是公開的,應放在瀏覽器程式碼中。API 密鑰則不應如此,且本頁面不需要任何 API 密鑰。
從環境變數讀取
Val Town 的 vals 在免費層是公開的,因此它們的來源是全世界可讀的。請將任何敏感資訊放在環境變數中,使用 Deno.env.get 讀取:
Run 
這在 Val Town 上尤為重要,原因有二:重新混合一個 val 會複製環境變數的鍵名,但不會複製其值。 放在環境變數中的密鑰不會隨你的 val 進入他人的帳戶。寫入檔案的密鑰則會。
回退到 "demo" 可讓該 val 在任何人在設定自己的租戶之前重新混合時仍能正常運作。
EU 帳戶
一個帳戶、其資料與金鑰都位於同一區域。如果您的帳戶是在 eu.fastcomments.com 建立的,則每個小工具設定也需要 region: "eu",且腳本會從 cdn-eu.fastcomments.com 載入。否則請保持兩者不變。
索引頁面的評論計數 
在索引頁面上,不要為每一列渲染單一的 comment-count 小部件。這會對每篇文章產生一次請求。請使用批量計數,它只需要對整個頁面發出一次請求。
在每一列上標記其線程使用的 urlId,然後一次性載入批量小部件:
Run 
此腳本會在頁面上尋找所有 .fast-comments-count 元素,並填入相應的計數。
data-fast-comments-url-id 必須與文章評論小部件使用的 urlId 相匹配。如果小部件使用 slug,標記也使用 slug。若不匹配,則即使線程中有評論也會顯示為零。
此腳本會輪詢 window.FastCommentsBulkCountConfig,因此無論您在 script 標籤之前或之後設定配置都沒關係。
使用 std/oauth 進行安全單一登入 
如果您的 val 已經知道訪客是誰,Secure SSO 會將該身份交給小工具,讓他們永遠不會看到第二次登入。無需建立任何端點,也不需要在執行時呼叫任何東西:您在伺服器端計算三個值,並將它們傳入小工具設定中。
Val Town 內建零設定登入功能,使用 std/oauth,因此訪客可以使用他們已有的 Val Town 帳號登入。您可以將其替換為您應用程式使用的任何方式;FastComments 部分則保持不變。
在伺服器上建立 Payload
API 密鑰會對 payload 進行簽名,且絕不能出現在瀏覽器程式碼中。從 npm 安裝 SDK,即可直接在 Val Town 的 Deno 執行環境中使用:
Run 
getPayload() 會回傳 { userDataJSONBase64, verificationHash, timestamp }。這三個值就是傳遞到瀏覽器的全部內容。密鑰會對它們簽名,之後即被丟棄,因此頁面中沒有任何東西可以讓讀者偽造其他使用者。
將其傳入小工具
Run 
oauthMiddleware 會為您新增 GET /auth/login、GET /auth/callback 與 POST /auth/logout。請注意,登出是 POST,而小工具會以 GET 方式導向 logoutURL,因此請將 logoutURL 指向您自行實作的、會送出 POST 的小路由。
當訪客已登出時,僅傳入包含 loginURL 的 sso。小工具隨即顯示登入提示,而非匿名留言框。
常見問題
timestamp 為 epoch 毫秒,不能是未來的時間,也不能超過兩天前。請在伺服器端於計算雜湊的同一個請求中產生它。在瀏覽器端產生是典型的失敗情形:產生的值與雜湊時使用的值不同,導致所有留言皆被拒絕。
千萬不要從身分提供者設定 isAdmin 或 isModerator。使用 Val Town 帳號登入並不代表該使用者應該擔任站點的管理員或版主。
請參閱 SSO guide 以取得完整欄位清單、群組限制的討論串以及徽章資訊。
接收 Webhook 
A val 是一個自然的 webhook 接收器:它具有穩定的 URL、能驗證簽名,且內建 SQLite 與 blob 儲存。
FastComments 使用您帳戶的 API 密鑰對 ${timestamp}.${body} 進行簽名,並傳送兩個標頭:
Run 
此方法攜帶事件:對於新建或更新的評論使用 PUT,對於已刪除的評論使用 DELETE。
Run 
兩個常見的陷阱
驗證原始位元組。 解析 JSON 並重新序列化會改變鍵的順序與空白,導致雜湊不同,所有傳遞都會失敗且沒有明顯原因。這通常是 webhook 接收器「根本無法運作」的原因。
以恆定時間比較。 對簽名使用普通的 === 會洩漏匹配的位元組數量,足以一次偽造一個位元組。
處理事件
快速回應。FastComments 會在非 2xx 回應時重試,且持續失敗的端點最終會自動被停用,因此應在回應後再執行實際工作,而非內嵌於回應中。
使其在評論 ID 上具備冪等性。重試時會使用新的時間戳重新簽名,同一評論 ID 在編輯與刪除時會再次到達,因此沒有穩定的依據可用於去重。
範例值 
Four public vals you can remix, each covering one piece of this guide.
Blog with comments (live) 是一個 Markdown 部落格,每篇文章下都有討論串,索引頁顯示大量評論計數。它在您 remix 的瞬間即可運作,且只需一個環境變數即可指向您自己的帳號。
SSO demo (live) 使用訪客的 Val Town 帳號登入,並將該身份傳遞給小部件,因而不需要第二次登入。
Webhook receiver (live) 在每次傳遞時驗證 HMAC 簽名,並將事件儲存於 SQLite。它有一個按鈕可簽署測試 payload 並自行傳送,讓您在設定真實 webhook 前看到驗證成功。
Agent skills (live) 是一個 FastComments 代理技能庫,涵蓋小部件、SSO、REST API、審核以及從 Disqus 遷移。Remix 它後,Val Town 的代理 Townie 會自動從 skills/ 取得這些技能,讓您的代理知道如何設定評論,而不必把文件貼到聊天中。
The same skills install anywhere else with npx skills add fastcomments/skills.
網域錯誤 
一旦關閉 demo 租戶,元件可能會因授權錯誤而無法載入。這是因為 FastComments 不知道它應該允許您的帳戶在該域名上使用。
Val Town 值得再看一次,因為一個 val 可能可以透過多個主機名稱存取:
- 每個 HTTP val 都有一個較長的預設端點,
<org>--<id>.web.val.run。 - 申請自訂子域名會新增
<name>.val.run。 - 一個自訂域名會再新增一個。
- 分支會有自己的 URL。