import { NextResponse } from "next/server"; import { getCampaign, saveCampaign } from "@/lib/campaign-storage"; import { computeTimeline } from "@/lib/campaign-timeline"; import { getIntegrations, schedulePost, findIntegrationForPlatform, } from "@/lib/postiz-client"; import type { PostSyncState, Platform, PostNode } from "@/lib/types/campaign"; export async function POST( _request: Request, { params }: { params: Promise<{ id: string }> } ) { const { id } = await params; const campaign = await getCampaign(id); if (!campaign) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } if (!campaign.postiz?.instance || !campaign.postiz?.apiKey) { return NextResponse.json( { error: "Postiz not configured for this campaign" }, { status: 400 } ); } const { instance, apiKey } = campaign.postiz; // Fetch available integrations from Postiz let integrations; try { integrations = await getIntegrations(instance, apiKey); } catch (err) { return NextResponse.json( { error: `Failed to connect to Postiz: ${err instanceof Error ? err.message : "Unknown error"}`, }, { status: 502 } ); } // Compute timeline entries from graph const timeline = computeTimeline(campaign); const results: { nodeId: string; platform: string; status: string; error?: string; }[] = []; // Build a node-id map for quick lookup const nodeMap = new Map(campaign.nodes.map((n) => [n.id, n])); for (const entry of timeline) { const node = nodeMap.get(entry.nodeId); if (!node || node.type !== "post") continue; const postNode = node as PostNode; // Initialize sync state if needed if (!postNode.data.postizSync) { postNode.data.postizSync = {} as Record; } const platform = entry.platform; const integration = findIntegrationForPlatform(integrations, platform); if (!integration) { postNode.data.postizSync[platform] = { status: "failed", error: `No ${platform} integration found in Postiz`, }; results.push({ nodeId: entry.nodeId, platform, status: "failed", error: `No ${platform} integration found`, }); continue; } try { const postizType = platform === "twitter" ? "x" : platform; const response = await schedulePost(instance, apiKey, { content: entry.content, type: postizType, date: entry.scheduledAt.toISOString(), integration: integration.id, }); postNode.data.postizSync[platform] = { postizPostId: response.id, scheduledAt: entry.scheduledAt.toISOString(), syncedAt: new Date().toISOString(), integrationId: integration.id, status: "synced", }; results.push({ nodeId: entry.nodeId, platform, status: "synced" }); } catch (err) { postNode.data.postizSync[platform] = { status: "failed", error: err instanceof Error ? err.message : "Unknown error", }; results.push({ nodeId: entry.nodeId, platform, status: "failed", error: err instanceof Error ? err.message : "Unknown error", }); } } // Save updated campaign with sync state await saveCampaign(campaign); const synced = results.filter((r) => r.status === "synced").length; const failed = results.filter((r) => r.status === "failed").length; return NextResponse.json({ synced, failed, total: results.length, results, }); }