127 lines
3.5 KiB
TypeScript
127 lines
3.5 KiB
TypeScript
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<Platform, PostSyncState>;
|
|
}
|
|
|
|
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,
|
|
});
|
|
}
|