跳至主要內容
技術

第 7 章:信收得到了,但能用它「寄」信嗎?

第 7 章:信收得到了,但能用它「寄」信嗎?
買域名的慘痛教訓:從 bobochen.ai 到 .dev 的真實故事 第 7 / 7 篇 ,前往系列總覽

本篇是「買域名的慘痛教訓:從 bobochen.ai 到 .dev 的真實故事」系列的第 7 / 7 篇。你可以從系列總覽開始閱讀,也可以直接接著看本文。

上一章我用 Cloudflare Email Routing 免費五分鐘搞定了客服信箱,autolaunch@bobochen.dev 寄一封測試信,Gmail 幾秒就「叮」一聲收到。我那時心想:完美,結案。

結果隔幾天,第一封真實客訴進來了。我在 Gmail 裡按下「回覆」,打完字正要送出,眼角瞄到寄件者那一欄——

寄件人:mygmail@gmail.com

不是 autolaunch@bobochen.dev

對方會收到一封「客服信箱寄出問題、卻是用某個陌生 Gmail 回覆」的信。整個品牌感瞬間漏氣。我才意識到:我只解決了「收」,根本還沒解決「寄」。

發現過程:Email Routing 是「單行道」

我回頭去翻 Cloudflare 的設定,想找「寄信」的開關——找不到。因為它根本沒有。

Cloudflare Email Routing 的設計就是單向的:只負責「把寄到你網域的信轉進你的 Gmail」,不負責「讓你用這個網域地址寄出去」。

為什麼?因為收信和寄信是兩套完全不同的機制:

  • 收信MX 紀錄——告訴全世界「寄到 @bobochen.dev 的信要送去哪台伺服器」。Email Routing 解決的就是這一半,它把信收下來再轉發。
  • 寄信靠的是一台能對外送信的 SMTP 伺服器,而且收件方還會反過來查 SPF / DKIM / DMARC,確認「這封信真的有資格代表 bobochen.dev 寄出」。

Cloudflare Email Routing 不提供對外 SMTP。所以「寄」這一半,你得自己補。

換句話說,所謂「雙向」根本不是一個功能,而是兩個獨立機制拼起來

收信(上一章已完成):
  別人 → autolaunch@bobochen.dev → Cloudflare MX → 轉進你的 Gmail

寄信(這一章要補):
  你在 Gmail 以 autolaunch@bobochen.dev 的身分撰寫 → 經外部 SMTP 送出 → 對方

解法:Gmail「Send mail as」+ Resend

我的需求很單純:在 Gmail 裡按回覆,對方收到的寄件者是 autolaunch@bobochen.dev。不想離開 Gmail、不想另外養一個信箱介面。

對應的標準作法是 Gmail 的「Send mail as」功能 + 一個交易型 email 服務的 SMTP

我選 Resend。原因:對開發者友善、免費額度 3,000 封/月(客服回信綽綽有餘)、同時提供 SMTP 和 API,而且我部落格其他文章(D1 + Resend 自架電子報)本來就在用它,生態一致。

不想用 Resend 也可以:Brevo(免費 300 封/天)、Amazon SES(極便宜)、MailerSend、SMTP2GO 都行,設定邏輯一模一樣,只是 SMTP 主機和 DNS 記錄換成各自的。

3 分鐘快速上手

Step 1:在 Resend 驗證你的網域

  1. 註冊 Resend → 左側 DomainsAdd Domain → 填 bobochen.dev(填根網域,理由跟上一章一樣——autolaunch.bobochen.dev 是子網域,不是獨立 zone)。
  2. Resend 會給你一組要加進 DNS 的記錄:一筆 MX(給回信用,可選)、一筆 SPF(TXT)、幾筆 DKIM(CNAME/TXT)。

Step 2:把記錄加進 Cloudflare DNS(注意 SPF 不能重複)

DKIM 直接照貼即可。SPF 是這整件事最容易爆的雷——後面獨立一段講,先照做:把 Resend 的 include 併進你「現有那一筆」SPF,不要新增第二筆。

Step 3:在 Resend 拿 SMTP 憑證

Resend → SMTP(或 API Keys)→ 取得:

Host: smtp.resend.com
Port: 587 (TLS)
User: resend
Pass: <你的 API key>

Step 4:在 Gmail 設定「Send mail as」

Gmail → ⚙️ → 查看所有設定帳戶和匯入 → 「Send mail as / 以這個地址寄信」→ 新增另一個電子郵件地址

  1. 名稱填 AutoLaunch 客服,地址填 autolaunch@bobochen.dev取消勾選「視為別名」(這樣回信才會用對的身分)。
  2. SMTP 伺服器填上 Step 3 那組(smtp.resend.com / 587 / resend / API key)。
  3. Gmail 會寄一封驗證碼到 autolaunch@bobochen.dev——因為上一章的 Email Routing 已經會把它轉進你的 Gmail,所以你在同一個收件匣就能拿到驗證碼,貼上去完成。

設定完,撰寫新信或回覆時,寄件者下拉就能選 autolaunch@bobochen.dev。收→寄的迴圈這才真正閉合。

🔍 Step 4 卡在「收不到驗證碼」? 那其實是「收信」沒通,不是寄信的問題——而且我光這一步就卡了快一小時。除錯順序我整理在上一章:先看 Cloudflare Activity Log 的 Result(Forwarded 代表 Cloudflare 沒事、問題在 Gmail 端),再排除兩個 Gmail 陷阱:①「從目的地自己寄給自己」會被去重② 目的地帳號的 POP「下載後封存/刪除」設定把信吃掉(信送達後幾秒被某個 POP 用戶端清走;換一個不同供應商的終點信箱就能隔離)。完整除錯路徑見 第 6 章:沒收到信?照這個順序查

那個會讓整封信進垃圾桶的 SPF 雷

這是我覺得最值得單獨拉出來講的一段,因為它不會報錯,只會默默讓你的信進垃圾桶

規則是:一個網域只能有「一筆」SPF 記錄。 多筆會直接讓 SPF 驗證失效。

問題來了——上一章啟用 Email Routing 時,Cloudflare 已經幫你寫了一筆 SPF:

v=spf1 include:_spf.mx.cloudflare.net ~all

現在 Resend 又要你加一筆它的 SPF。如果你手滑新增成第二筆,兩筆 SPF 並存,驗證就壞了。正確做法是把兩個 include 合併進同一筆

v=spf1 include:_spf.mx.cloudflare.net include:amazonses.com ~all

(Resend 底層走 Amazon SES,所以 include 是 amazonses.com;以 Resend 後台實際顯示的為準。)

加上 DKIM 和 DMARC,寄信的「信任三件套」才齊:

  1. SPF(上面那筆,合併版)——授權哪些伺服器能代表你網域寄信。
  2. DKIM——用 Resend 給的 CNAME/TXT 記錄,幫每封信加數位簽章,證明沒被竄改。
  3. DMARC——加一筆 _dmarc TXT。最保守的起手式是先用 p=none 觀察,確認對齊後再收緊:
    _dmarc  TXT  "v=DMARC1; p=none; rua=mailto:autolaunch@bobochen.dev"

新網域其實可以更大膽——直接把 p 設嚴一點。

p=none 的保守哲學是「先觀察、別誤擋信」,那是給舊網域用的——已經用很久、你也搞不清楚還有哪些系統在拿這個網域寄信,貿然收緊怕把正常信也擋掉。但你手上這顆是全新買來的:根本沒有任何歷史寄信流量會被誤殺,那就沒理由留一扇後門給冒名者。只要先確認自己的 SPF / DKIM 真的對齊(用 rua 報告或 mail-tester 驗一遍),就可以一開始直接上 p=reject

_dmarc  TXT  "v=DMARC1; p=reject; rua=mailto:autolaunch@bobochen.dev"

p=reject 是最強等級——任何冒名 bobochen.dev 的信,收件方伺服器會「直接拒收」,連垃圾桶都不進,是防釣魚/冒名最有效的一道。bobochen.dev 我自己就是這樣設的。唯一前提是對齊要先綠燈,否則會連自己的信一起擋掉;真不放心,就先用 p=quarantine(冒名信丟垃圾桶、但不退信)過渡,觀察幾天 rua 報告沒問題再升 p=reject

三件套都綠燈,你的客服回信才不會被 Gmail / Outlook 丟進垃圾桶。設定完,去 mail-tester.com 寄一封測,拿到 10/10 再上線。

那如果是程式要自動寄信?

如果你的需求不是「人在 Gmail 點回覆」,而是 App 後端要自動發驗證信、通知、電子報,那就不走 Gmail,直接用 API:

  • Resend API(同一個帳號,呼叫一個 endpoint 就送出)
  • Cloudflare Email Sending / Email Workers(信件邏輯直接跑在 Worker 裡)

這屬於另一個主題,我寫在這兩篇:Email Workers:程式化處理電子郵件自建 transactional email:D1 + Resend 完整流程

具體數據 / 結果

項目只用 Email Routing補上 Resend 後
收信✅ 免費轉發✅ 免費轉發
寄信(以網域身分)❌ 做不到✅ Gmail 直接回
操作介面Gmail還是 Gmail(同一個)
額外成本$0$0(Resend 免費 3,000 封/月)
需要設定MX + SPF多加 DKIM + DMARC + SMTP

一樣是 $0,只是多花十分鐘設 DNS 和 Gmail。對「能收也能回的客服信箱」這個需求,剛好夠用。

反思

技術面:「收」和「寄」永遠是兩件事

這一章其實是上一章那句「收信和寄信是兩套機制」的具體下場。我上一章寫的時候是當理論講,這一章是真的被它咬了一口。

  • 收信免費又簡單(MX 一鍵),會讓你誤以為「信箱搞定了」。
  • 寄信才是真正麻煩的那一半——不是技術難,是 deliverability(能不能不進垃圾桶)難,而它全押在 SPF / DKIM / DMARC 這三筆你看不到效果的 DNS 記錄上。

還有上一章那個「Email Routing 只認根網域(zone)」的限制,在 Resend 驗證網域時再次出現:你驗證的是 bobochen.dev 這個 zone,不是子網域。同一個觀念,換個場景又來敲你一次。

心態面:免費方案的「邊界」要先搞懂,別等出事才補

免費工具最危險的不是它要錢,是它只做一半、而你以為它做了全部。Email Routing 把「收信」做得又快又免費,反而讓我輕忽了「寄信」根本不在它的守備範圍。

更陰險的是 deliverability:信進垃圾桶不會跳任何錯誤,你自己測試(寄給自己)還常常正常,等到真實客戶收不到、客訴你「都沒回我」,才發現 DMARC 沒設好。這種「沉默的失敗」最該在上線前主動驗一遍——所以我才會押著自己去 mail-tester 跑到 10/10 才收工。

有趣發現:這個系列又長出一章

上一章結尾我才自嘲「我又幫這個系列加了一章」,沒想到一語成讖——光是一個客服信箱,就拆成了「收」(第 6 章)和「寄」(第 7 章)兩章。

域名這條路大概就是這樣,你以為閉環了,它總有辦法讓你發現環只接了一半。所以如果第 5 章的「五個建議」要再補一條:

建議七:信箱別只測「收得到」,也要測「寄得出、且不進垃圾桶」。收信靠 Email Routing 免費搞定,寄信要另外接 SMTP(Resend 之類)並設好 SPF / DKIM / DMARC——而且 SPF 全網域只能有一筆,記得用 include 合併,別開第二筆。

留言討論

esc
輸入關鍵字搜尋文章...
查看收藏 →