/** * 视频归档定时任务触发API * 用于 Cron Job 定时调用,执行视频归档任务 * * 使用方法: * 1. 配置环境变量 CRON_SECRET * 2. 在 Vercel Cron 或外部 Cron 服务中配置定时触发 * 3. 每小时执行一次:0 * * * * */ import { NextResponse } from "next/server"; import { runVideoArchiveJob } from "@/lib/jobs/video-archive-job"; import { getVideosToArchive } from "@/lib/jobs/video-archive-job"; /** * 验证请求授权(防止未授权调用) */ function verifyAuthToken(request: Request): boolean { const authHeader = request.headers.get("authorization"); const token = authHeader?.replace("Bearer ", ""); // 与环境变量中的密钥比对 const cronSecret = process.env.CRON_SECRET; // 如果未配置 CRON_SECRET,则允许所有请求(开发环境) if (!cronSecret) { console.warn("[VideoArchiveAPI] ⚠️ CRON_SECRET 未配置,允许所有请求"); return true; } return token === cronSecret; } /** * POST /api/jobs/archive-videos * 执行视频归档任务 */ export async function POST(request: Request) { try { // 1. 验证授权 if (!verifyAuthToken(request)) { return NextResponse.json( { error: "Unauthorized" }, { status: 401 } ); } // 2. 执行归档任务 const result = await runVideoArchiveJob(); // 3. 返回成功响应 return NextResponse.json({ success: result.success, message: result.message, stats: { total: result.total, succeeded: result.succeeded, failed: result.failed, }, timestamp: new Date().toISOString(), }); } catch (error: any) { console.error("[VideoArchiveAPI] ❌ Job execution failed:", error); return NextResponse.json( { success: false, error: error.message, timestamp: new Date().toISOString(), }, { status: 500 } ); } } /** * GET /api/jobs/archive-videos * 查询待归档视频统计 */ export async function GET(request: Request) { try { // 验证授权 if (!verifyAuthToken(request)) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } // 查询待归档视频 const videos = await getVideosToArchive(); return NextResponse.json({ pendingCount: videos.length, videos: videos.map((v) => ({ id: v.id, createdAt: v.createdAt, temporaryVideoUrl: v.temporaryVideoUrl, })), timestamp: new Date().toISOString(), }); } catch (error: any) { console.error("[VideoArchiveAPI] ❌ Query failed:", error); return NextResponse.json( { success: false, error: error.message, timestamp: new Date().toISOString(), }, { status: 500 } ); } }