import { NextResponse } from "next/server"; import { prisma } from "@/lib/db"; import { authErrorResponse } from "@/lib/auth/api"; import { requireSessionUser } from "@/lib/auth/session"; import { requireActiveThreadsAuth } from "@/lib/services/threads-auth-guard"; import { replyViaThreadsApi } from "@/lib/threads-api"; import { getActiveThreadsCredentials } from "@/lib/services/threads-credentials"; export async function POST( _request: Request, { params }: { params: Promise<{ id: string }> } ) { try { await requireSessionUser(); const authCheck = await requireActiveThreadsAuth(); if (!authCheck.ok) { return NextResponse.json({ error: authCheck.error }, { status: 401 }); } const { id } = await params; const draft = await prisma.outreachDraft.findUnique({ where: { id }, include: { outreachTarget: { include: { scanItem: true } } }, }); if (!draft) return NextResponse.json({ error: "找不到獲客留言草稿" }, { status: 404 }); const externalId = draft.outreachTarget.scanItem.externalId; if (!externalId) { return NextResponse.json({ error: "目標貼文缺少 Threads media id,請改用複製後手動留言" }, { status: 400 }); } const credentials = await getActiveThreadsCredentials(); if (!credentials) return NextResponse.json({ error: "Threads API 尚未連線" }, { status: 401 }); const result = await replyViaThreadsApi(credentials, { replyToId: externalId, text: draft.text, }); if (!result.success) { return NextResponse.json({ error: result.error ?? "發布留言失敗" }, { status: 500 }); } await prisma.$transaction([ prisma.outreachDraft.update({ where: { id }, data: { status: "PUBLISHED", publishedAt: new Date() }, }), prisma.outreachTarget.update({ where: { id: draft.outreachTargetId }, data: { status: "COMMENTED" }, }), ]); return NextResponse.json({ success: true, result }); } catch (error) { const authRes = authErrorResponse(error); if (authRes) return authRes; const message = error instanceof Error ? error.message : "發布留言失敗"; return NextResponse.json({ error: message }, { status: 500 }); } }