歡迎來到階段四:進階功能與 AI 功能整合!在完成階段三前端體驗的極致雕琢後,今天我們要為我們的 「AI 智慧個人財務追蹤器 (Smart Finance Tracker)」 賦予商業化的靈魂。
我們將整合現代開發者最愛的 Resend 電子郵件服務,實現「每週財務週報」與「異常消費警示」自動寄送功能!
在 Next.js App Router 中整合 Resend SDK 與 React Email。
讓 AI 生成具備響應式設計且視覺精美的 HTML Email 範本。
掌握在 Vibe Coding 下如何引導 AI 處理 Webhook、API Key 安全防護以及 Resend 的非同步寄送狀態。
使用傳統方法寫 HTML Email 簡直是前端工程師的噩夢(要用 刻排版、處理各大 Email Client 的樣式相容性)。現在利用 React Email + Resend 搭配 AI,幾分鐘就能產出極具現代感的郵件範本!
我們正在 Next.js (App Router) 專案中整合 Resend 與 React Email。
請幫我建立一個週報郵件元件 src/emails/WeeklyReportEmail.tsx 與對應的 API Route src/app/api/send-report/route.ts。
要求:
WeeklyReportEmail 使用 @react-email/components 撰寫,接收 userName, totalExpense, topCategory 三個 Props。resend SDK 發送郵件,並從 .env.local 讀取 RESEND_API_KEY。// src/app/api/send-report/route.ts
import { NextResponse } from 'next/server';
import { Resend } from 'resend';
import { WeeklyReportEmail } from '@/emails/WeeklyReportEmail';
const resend = new Resend(process.env.RESEND_API_KEY);
export async function POST(req: Request) {
try {
const { email, userName, totalExpense, topCategory } = await req.json();
const data = await resend.emails.send({
from: 'Finance Tracker <onboarding@resend.dev>',
to: email,
subject: '您的本週財務週報已送達!',
react: WeeklyReportEmail({ userName, totalExpense, topCategory }),
});
return NextResponse.json(data);
} catch (error) {
return NextResponse.json({ error: error.message }, { status: 500 });
}
}
這段 Code 在本機測試時,一發送 API 請求,控制台立刻噴出連串錯誤,郵件完全寄不出去:
Error: React.createElement: type is invalid -- expected a string or a class/function but got:
React Email JSX 傳參語法錯誤:
在 Resend SDK 中,react: 屬性應該接收一個 JSX 元素(即 <WeeklyReportEmail userName={userName} ... />),但 AI 卻將它寫成了函式呼叫 WeeklyReportEmail({...})。這直接打破了 React 的渲染機制!
缺少 API Key 未設定的防禦性檢查:
如果 .env.local 沒有設定 RESEND_API_KEY,Resend SDK 在初始化或呼叫時會拋出非常晦澀的內部錯誤,AI 產出的程式碼完全沒有在最上層做環境變數檢查。
預設寄件者網域限制(Domain Sandbox):
Resend 測試階段預設只能寄給「帳號註冊者自己的 Email」,如果發送給任意第三方測試信箱,Resend 會回傳 403 Forbidden。AI 沒有在語法中捕獲此特定錯誤提示,導致前端只拿到模糊的 500 Internal Server Error。
我整理了錯誤訊息,並向 Cursor 下達修復指令:
修正 Prompt:
「1. resend.emails.send 中的 react 欄位請改為正確的 JSX 語法 <WeeklyReportEmail ... />。
2. 請在 route.ts 頂部加入 process.env.RESEND_API_KEY 的檢查,若缺失則回傳 500 告知環境變數未設定。
3. 請使用 Zod 驗證 Request Body,並處理 Resend API 回傳的錯誤物件(Resend 的 error 不會觸發 Catch,需手動檢查 data.error)。」
經過調整後,我們獲得了一套具備生產環境強度(Production-ready)的 API 與郵件寄送邏輯:
// src/app/api/send-report/route.ts
import { NextResponse } from 'next/server';
import { Resend } from 'resend';
import { z } from 'zod';
import WeeklyReportEmail from '@/emails/WeeklyReportEmail';
// 1. Zod 嚴格驗證輸入欄位
const sendReportSchema = z.object({
email: z.string().email('無效的 Email 格式'),
userName: z.string().min(1, '用戶姓名不能為空'),
totalExpense: z.number().nonnegative(),
topCategory: z.string(),
});
export async function POST(req: Request) {
// 2. 環境變數檢查
if (!process.env.RESEND_API_KEY) {
return NextResponse.json({ error: '伺服器未設定 RESEND_API_KEY' }, { status: 500 });
}
const resend = new Resend(process.env.RESEND_API_KEY);
try {
const body = await req.json();
const validationResult = sendReportSchema.safeParse(body);
if (!validationResult.success) {
return NextResponse.json({ error: validationResult.error.flatten() }, { status: 400 });
}
const { email, userName, totalExpense, topCategory } = validationResult.data;
// 3. 正確使用 JSX 語法傳遞 React Email 組件
const { data, error } = await resend.emails.send({
from: 'Smart Finance <weekly@yourdomain.com>',
to: [email],
subject: '您的本週財務週報已送達!',
react: <WeeklyReportEmail userName={userName} totalExpense={totalExpense} topCategory={topCategory} />,
});
// 4. Resend 的 API 錯誤處理(Resend 不會直接 throw error,而是回傳 error 物件)
if (error) {
console.error('Resend API Error:', error);
return NextResponse.json({ error: error.message }, { status: 400 });
}
return NextResponse.json({ success: true, messageId: data?.id });
} catch (error: any) {
console.error('Server Unhandled Error:', error);
return NextResponse.json({ error: error.message || '伺服器內部錯誤' }, { status: 500 });
}
}
SDK 錯誤處理的兩大派系(Throw vs. Return Object):
傳統 SDK(如 Stripe、OpenAI)在發生錯誤時通常會直接 throw new Error(),需要用 try-catch 捕獲;但許多現代輕量化 SDK(如 Resend、Supabase)則偏好回傳 { data, error } 物件。AI 常常會混淆這兩種模式,開發者必須保有明確的判斷能力。
React Email 與 Server Component 的交集:
React Email 的妙處在於能讓我們用撰寫 React UI 的方式寫 Email。但在 Server 端渲染 Email JSX 時,要確保傳入的是編譯後的合法 React Node,否則會破壞 SSR/Node 的模組解析。
今天我們成功把 Resend 電子郵件服務整合進專案中,讓我們的財務追蹤器具備了與使用者保持互動的通知機制!
明日 Day 20,我們將進入本階段的重頭戲 —— 在 Web 中整合 LLM API(OpenAI / Anthropic SDK),正式開啟專案的「AI 智慧分析」核心功能!敬請期待!