第七章:貼心的高級功能 - 串接 Nodemailer 自動寄發確認信
當客人在我們的「不遠露營山莊官網」成功預約並刷卡後,如果網頁只跳出一個「預約成功」,客人心裡一定很不踏實。 這時候,如果他的信箱能立刻收到一封精美的「預約確認信 (包含訂單編號、日期、金額)」,他對我們的品牌信任度絕對會大增!
🎯 本章目標
- 了解什麼是 Nodemailer 以及 SMTP 原理。
- 申請免費的 Google App Password (應用程式密碼) 以便發信。
- 使用 Vibe Prompt 讓 AI 幫我們寫一支寄信 API。
📬 什麼是 Nodemailer?
寄 Email 其實是一件很複雜的事,你需要跟郵件伺服器 (SMTP Server) 打交道。 在 Node.js (Astro 的後台環境) 裡,最出名、最好用的寄信套件就叫做 Nodemailer。 只要你給它一組 Gmail 帳號密碼,它就能假裝是你,自動幫你寄信給客人!
🔑 第一步:申請 Gmail 應用程式密碼
為了安全起見,Google 不允許你直接把真正的 Gmail 密碼寫在程式碼裡。你必須申請一組專門給程式用的「應用程式密碼」。
- 前往你的 Google 帳戶安全性設定。
- 確保你已經開啟了 兩步驟驗證 (2FA)。
- 尋找 應用程式密碼 (App Passwords) 的選項 (有時候會藏在兩步驟驗證選單的最下方,或是可以在頂部搜尋框搜尋「應用程式密碼」)。
- 建立一組新的密碼,名稱取名為
Not Far Web。 - 畫面上會出現一組 16 碼的英文字母 (例如
abcd efgh ijkl mnop)。請把它複製起來!這就是你的發信金鑰!
[!WARNING] 這組密碼非常重要,一旦離開畫面就再也看不到了。千萬不要把它提交到 GitHub 上,請一定要寫在
.env檔案裡!
在專案根目錄的 .env 加入這兩行:
GMAIL_USER="你的信箱@gmail.com"
GMAIL_PASS="你剛申請的16碼應用程式密碼(不要有空格)"
✉️ 第二步:用 Vibe 生成發信 API
現在我們來到最魔法的部分!
[!TIP] Vibe Prompt (請複製並發送給 AI):
我正在開發 Astro 專案。我需要寫一支可以自動寄發 Email 的 API。1. 請給我 npm 安裝 nodemailer 的指令。2. 請幫我在 src/pages/api/send-email.ts 建立一個 Astro API API Route (POST 方法)。3. 請使用 nodemailer 搭配 Gmail SMTP (讀取 process.env.GMAIL_USER 與 GMAIL_PASS)。4. 當前端 POST 過來 { email, name, date } 時,請寄一封標題為 "【不遠露營山莊】預約成功確認信" 的信給客人。5. 信件內容 (html) 請幫我用簡單的 HTML 與 CSS 設計得溫馨、有質感一點。
AI 會教你安裝套件:
npm install nodemailer
npm install -D @types/nodemailer
然後生成類似這樣的高級發信邏輯:
import nodemailer from 'nodemailer';
import type { APIRoute } from 'astro';
export const POST: APIRoute = async ({ request }) => {
const body = await request.json();
const { email, name, date } = body;
// 設定郵件伺服器 (Gmail 專用設定)
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: import.meta.env.GMAIL_USER, // Astro 讀取環境變數的寫法
pass: import.meta.env.GMAIL_PASS,
},
});
// AI 幫你寫的超美 HTML 模板
const htmlContent = `
<div style="font-family: sans-serif; padding: 20px; border: 1px solid #ddd; border-radius: 10px;">
<h2 style="color: #2F855A;">🏕️ 期待在不遠山莊見到您!</h2>
<p>親愛的 <strong>${name}</strong> 您好:</p>
<p>我們已經收到您的預約,詳細資訊如下:</p>
<ul>
<li>預約日期:${date}</li>
</ul>
<p>請記得攜帶保暖衣物,我們山上見!</p>
</div>
`;
// 執行寄信
try {
await transporter.sendMail({
from: '"不遠露營山莊" <noreply@notfar.com>',
to: email, // 寄給客人
subject: "【不遠露營山莊】預約成功確認信",
html: htmlContent,
});
return new Response(JSON.stringify({ message: "發信成功" }), { status: 200 });
} catch (error) {
return new Response(JSON.stringify({ error: "發信失敗" }), { status: 500 });
}
}

✅ 本章小結
這就是所謂的「商業級細節」! 多了一封自動確認信,不僅減少了客服人員回覆「請問我有預約成功嗎?」的時間,更讓你的專案看起來非常高級。 目前為止,Not Far Web 專案的教學已經大功告成,從架設環境、資料庫、會員登入一直到自動寄信,你已經具備了接案級的全端開發能力了!