61 lines
2.2 KiB
TypeScript
61 lines
2.2 KiB
TypeScript
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 });
|
||
}
|
||
}
|