【SMTP】如何用Emil信箱收到網站訪客填表的內容

這篇文章記錄了如何使用Resend服務,及網域主機商提供的Email來接收網站上的訪客填表訊息

什麼是SMTP?

SMTP(Simple Mail Transfer Protocol)是一種用於傳送電子郵件的網路協定,它定義了電子郵件如何在網絡中傳輸並進行交換。SMTP 服務提供了一個標準的方式,讓電子郵件客戶端(如電子郵件應用程式、網站等)能夠發送郵件到郵件伺服器,並由伺服器負責將郵件傳遞到接收者的郵件伺服器。

流程及概念

  1. 註冊Resend
  2. 更改網域的DNS並進行驗證
  3. 新增API
  4. 撰寫程式碼

1. 註冊Resend

首先,前往 Resend 官網進行註冊,並登入管理介面。

點選右上角的 Docs↗ 按鈕,可以選擇不同框架的應用說明文件,或繼續閱讀本篇 Node.js 框架的操作說明。

在左側邊欄中點選 Domains,然後按下 + Add Domain 以新增網域。

SMTP-RESEND-新增網域
新增網域時不能填寫 localhost 或免費供使用者部署的域名(例如:github.io、vercel.app)。 必須使用你自己付費註冊的網域,因為寄信時需要使用『實際存在的信箱』,而你購買的網域能提供這個服務。

不知道如何自行創建信箱嗎?
請參考【主機管理】如何在C-panel管理介面新增信箱

填入你購買的網域,並按下新增按鈕。
成功新增後,畫面上會顯示三串文字,分別為一個 MX 記錄和兩個 TXT 記錄。

SMTP-RESEND-記錄三個record並驗證

接著往下看,我們將要把這三個紀錄,新增到DNS當中。

2. 更改網域的DNS並進行驗證

以下以Namecheap的介面為例,若網域管理仍為預設值『Namecheap Web Hosting DNS』,改成『Namecheap BasicDNS』後打勾存檔,進階管理分頁才會出現可填寫Record的欄位。

SMTP-DNS要改成Basic才能自行設定

更改完成後,點選上方的Advanced DNS(進階DNS)分頁,會看到HOST RECORDS欄位,新增兩個TXT Record類型並從Record把Value(值)複製貼上。

SMTP-設定DNS紀錄的位置

剩下的MX Record填寫位至於下方MAIL SETTINGS欄位,選擇CUSTOM MX,一樣新增並將值複製貼上。

SMTP-MX RECORD位於EMAIL的位置

回到Resend的網域管理畫面並按下驗證按鈕,如果有偵測到3個Record,過一段時間就會轉為綠色,DNS設定就大功告成。

改用Namecheap BasicDNS時,DNS設定有可能是空的,這會導致網頁沒辦法出現,記得新增一個A record類型,Host name為@,值為主機的IP位址,然後新增Cname record類型,Host name為www,值填寫你的購買的網域。

3.新增API

再次回到Resend後台的左側側邊欄,找到API Keys並點選進入管理畫面。

SMTP-RESEND-創建新的API Key
SMTP-RESEND-按下創建按鈕

按下右上角『創建API Key(+Create API key)』按鈕。
只填寫第一欄API名稱,剩下欄位維持預設值,按下新增(Add)。

最後,出現寫著API Key的彈窗,立刻按下右邊複製按鈕,把這串API Key儲存下來。

API Key生成後只有一次複製機會,若忘了複製又關掉彈窗,只能刪除舊的再重新建立。
SMTP-RESEND-API Key只會出現一次立刻複製

於環境變數文件(.env)新增一個名為『RESEND_API_KEYS』的變數,並將剛剛複製的API Key貼上,作為『RESEND_API_KEYS』的值。

SMTP-RESEND-把API Key貼到環境變數文件

完成上述步驟後,就可以把API Key的彈窗關掉了。

4.撰寫程式碼

首先,打開專案目錄,並用 npm 安裝 Resend:

npm install resend

安裝完成後,打開路由管理文件,引入 Resend 模組:

const { Resend } = require("resend");
const resend = new Resend(process.env.RESEND_API_KEYS);

預計在 /contact 路徑進行發送新表單時(POST)使用 Resend,程式碼如下:

app.post("/contact", async (req, res) => {
  try {  
  const { data, error } = await resend.emails.send({
    from: "網站名稱 <填寫你註冊的網域的email,例如support@domain.com>",
    to: ["<填寫你希望收到信的信箱,例如youraccount@gmail.com>"],
    subject: "信件主旨",
    html: "信件內容",
  });  
    req.flash("success_msg", "已寄出!");
    console.log({ data });
  } catch (error) {
    req.flash("error_msg", "發生錯誤,無法寄出!");
    console.log({ error });
  }  
});

如果你想在信件中顯示網站訪客的填表訊息,請看以下範例:

app.post("/contact", async (req, res) => {
  try {
  let { name, phone, email, content } = req.body;
  const { data, error } = await resend.emails.send({
    from: "網站名稱 <填寫你註冊的網域的email,例如support@domain.com>",
    to: ["<填寫你希望收到信的信箱,例如youraccount@gmail.com>"],
    subject: `聯絡表單|來自${name}的問題`,
    html: `<h3>稱呼:${name}</h3>
    <h3>聯絡電話:${phone}</h3>
    <h3>聯絡信箱:${email}</h3>    
    <h3>洽詢內容:</h3><p>${content}</p>
    `,
  });  
    req.flash("success_msg", "已寄出!");
    console.log({ data });
  } catch (error) {
    req.flash("error_msg", "發生錯誤,無法寄出!");
    console.log({ error });
  }  
});

req.body 中取得 namephoneemailcontent 欄位的值,並用反引號(模板字符串)及 ${} 代入變數,即可在信件中直接顯示訪客的填表訊息。