Serverless 排程:Vercel Cron Jobs 實戰
在這個 AI 與現代 Web 開發的時代,我們幾乎都是使用 Next.js 等框架撰寫全端網站,並將其部署到 Vercel 平台上。
過去,如果你把 Next.js 部署到 Vercel,想要做「每晚 12 點統計資料庫數據」的任務,你必須像我們第二章教的那樣,自己去註冊 cron-job.org 來戳 API。但 Vercel 官方聽到了開發者的心聲,現在他們原生推出了 Vercel Cron Jobs 功能!
使用 Vercel Cron Jobs 的好處是:與專案深度整合、免註冊外部服務、自帶強大的資安防護。
實作 Vercel Cron Jobs 的三大步驟
在 Next.js (App Router) 中實作 Vercel Cron 非常簡單。我們只需要準備一個普通的 API 端點,並在設定檔中告訴 Vercel 何時去呼叫它即可。
步驟 1:建立 API Route
首先,在你的 Next.js 專案中建立一個專門給 Cronjob 呼叫的 API 端點。
例如建立檔案 src/app/api/cron/daily-report/route.ts:
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// 檢查安全性 (後面步驟會解釋)
const authHeader = request.headers.get('authorization');
// 為了安全起見,這裡先印出被呼叫的時間
console.log(`[Cron Job Triggered] Time: ${new Date().toISOString()}`);
try {
// ============================================
// 在這裡寫你的業務邏輯!
// 例如:從 Supabase 撈取昨日訂單,寄送 Email 報表
// await generateAndSendDailyReport();
// ============================================
return NextResponse.json(
{ success: true, message: 'Daily report processed successfully' },
{ status: 200 }
);
} catch (error) {
console.error('Cron job error:', error);
return NextResponse.json(
{ success: false, message: 'Failed to process job' },
{ status: 500 }
);
}
}
步驟 2:加入 Vercel.json 設定檔
接下來,在你的專案根目錄(與 package.json 同層)建立一個名為 vercel.json 的檔案。
這個檔案是 Vercel 的專屬設定檔,我們在裡面宣告我們的 cron 排程:
{
"crons": [
{
"path": "/api/cron/daily-report",
"schedule": "0 8 * * *"
}
]
}
這裡的設定非常直觀:
path:告訴 Vercel 時間到了要去呼叫哪個相對路徑的 API。schedule:一樣是使用 Crontab 語法。這裡設定每天早上 8 點 (這裡的時區同樣預設為 UTC,請記得自行換算!台灣早上 8 點 = UTC0 0 * * *)。
[!TIP] Vercel Hobby (免費版) 的限制 如果你是免費版帳號,Vercel 規定一天最多只能執行一次 Cron job (也就是每天的限制額度為 1 次)。 如果你的腳本需要每小時執行,你必須升級至 Vercel Pro (每月 $20),或者退而求其次,乖乖回去使用我們教過的
cron-job.org。
步驟 3:安全性防護 (CRON_SECRET)
這是 Vercel Cron Jobs 最貼心的一點!
如果你的 API URL (如 /api/cron/daily-report) 暴露在網路上,任何人都可以自己發送請求來觸發你的報表生成,這非常危險。
為了解決這個問題,當 Vercel 讀取到你的 vercel.json 並為你建立 Cronjob 時,它會自動在你的專案環境變數中,注入一個超級複雜的密碼:CRON_SECRET。
每次 Vercel 自動觸發你的 API 時,它的 HTTP Header 都會帶著這個金鑰:
Authorization: Bearer <你的_CRON_SECRET>
所以,我們必須修改我們步驟 1 的 API,加入這層無堅不摧的防護:
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// 1. 取得請求中的 Authorization Header
const authHeader = request.headers.get('authorization');
// 2. 確保 Vercel 環境中有設定 CRON_SECRET
const cronSecret = process.env.CRON_SECRET;
// 3. 嚴格比對!如果金鑰不對,直接拒絕存取
if (!cronSecret || authHeader !== `Bearer ${cronSecret}`) {
return NextResponse.json(
{ success: false, message: 'Unauthorized Request' },
{ status: 401 }
);
}
// 4. 金鑰正確,放行執行核心邏輯
console.log("授權成功,開始執行排程任務...");
return NextResponse.json({ success: true });
}
測試與上線
當你把程式碼推送到 GitHub,Vercel 自動部署完成後,你可以進入 Vercel 的專案儀表板。
點擊上方選單的 "Settings" -> 左邊的 "Cron Jobs"。
在這裡,你會看到你剛剛在 vercel.json 裡面設定好的任務清單。Vercel 還貼心地提供了一個 "Run" 的手動測試按鈕,點擊它就能馬上觸發你的 API,方便你測試 CRON_SECRET 有沒有正確生效!
透過 Vercel Cron Jobs,只要簡簡單單一個設定檔,你就能打造出擁有銀行等級安全防護的全端自動化服務!