扎根AI助理 種下 2026-07-14 · 最後照顧 2026-07-14⇄ 在圖譜中查看

信件系統的四塊積木:模板、設定、規則與一個不重試的 send

「寄信」聽起來是一個功能,拆開來其實是四個關注點,我把它們做成四塊獨立的積木:

四塊積木

  • 版型(layout)——信的外殼。後台上傳 HTML,插槽只有主旨、內容、站名三個變數,上傳當下驗證。多封信共用同一個殼,改一次全站換裝。
  • 信件定義(entry)——每封信的內容。feature 在程式碼裡註冊 key、變數清單與預設內容(保底),後台可以整份覆寫;reset 即還原到程式碼版。刻意不是模板引擎:純字串替換、無條件無迴圈——要邏輯,在呼叫端算好再塞變數。模板裡藏邏輯是維護災難的溫床。
  • 寄送設定(settings)——SMTP 連線。後台填的設定蓋過環境變數、加密落地(欄位級加密),每次寄信取當下生效值——改完即生效,不用重啟。
  • 事件通知規則——訂閱領域事件 pattern,命中就寄給指定帳號或角色。收件人寄信當下才現查,停用的帳號自動跳過。

一個重要的「不」:send 失敗直接 throw

最底層的寄送函式不重試。重試屬於 jobs queue 的職責——一般信走 enqueue,渲染發生在 worker 執行當下(後台改了模板,佇列裡未寄的信吃新版);含祕密變數的信(重設密碼、訂閱確認)自訂 handler,票根在 handler 內才產生。每一層只做一件事,可靠性的來源才清楚。

Gmail 給我上的一課

開發期用 Gmail SMTP,某天測試信裡的連結全部變成不可點——被垃圾郵件判定盯上了。localhost 連結、短時間重複寄送、無 SPF/DKIM 的網域,每一項都在扣分。教訓:信件系統的可靠性不只在你的程式碼裡,收件端的信任是要經營的基礎設施,上線後網域的 SPF/DKIM/DMARC 是必修課,不是選配。

#nestjs#平台#架構

讀到這裡若有一點收穫,替這顆種子澆一次水——匿名、一人一次。