第七章:貼心的高級功能 - 串接 Nodemailer 自動寄發確認信

當客人在我們的「不遠露營山莊官網」成功預約並刷卡後,如果網頁只跳出一個「預約成功」,客人心裡一定很不踏實。 這時候,如果他的信箱能立刻收到一封精美的「預約確認信 (包含訂單編號、日期、金額)」,他對我們的品牌信任度絕對會大增!

🎯 本章目標

  1. 了解什麼是 Nodemailer 以及 SMTP 原理。
  2. 申請免費的 Google App Password (應用程式密碼) 以便發信。
  3. 使用 Vibe Prompt 讓 AI 幫我們寫一支寄信 API。

📬 什麼是 Nodemailer?

寄 Email 其實是一件很複雜的事,你需要跟郵件伺服器 (SMTP Server) 打交道。 在 Node.js (Astro 的後台環境) 裡,最出名、最好用的寄信套件就叫做 Nodemailer。 只要你給它一組 Gmail 帳號密碼,它就能假裝是你,自動幫你寄信給客人!


🔑 第一步:申請 Gmail 應用程式密碼

為了安全起見,Google 不允許你直接把真正的 Gmail 密碼寫在程式碼裡。你必須申請一組專門給程式用的「應用程式密碼」。

  1. 前往你的 Google 帳戶安全性設定
  2. 確保你已經開啟了 兩步驟驗證 (2FA)
  3. 尋找 應用程式密碼 (App Passwords) 的選項 (有時候會藏在兩步驟驗證選單的最下方,或是可以在頂部搜尋框搜尋「應用程式密碼」)。
  4. 建立一組新的密碼,名稱取名為 Not Far Web
  5. 畫面上會出現一組 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 });
  }
}

![Gmail 收信截圖]([SCREENSHOT_PLACEHOLDER: 在 Gmail 收件匣中,收到一封帶有綠色標題和精美排版的確認信截圖])


✅ 本章小結

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

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!