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 });
|
|||
|
|
}
|
|||
|
|
}
|