import fs from "node:fs";
import Papa from "papaparse";
const HEADERS = {
Authorization: `Bearer ${process.env.MODA_API_KEY!}`,
"Moda-Version": "2026-05-01",
"Content-Type": "application/json",
};
const CALLBACK_URL = "https://myapp.com/webhooks/moda";
// 1. upload the brief once
const briefForm = new FormData();
briefForm.set("file", new Blob([fs.readFileSync("brief.pdf")]), "brief.pdf");
const brief = await fetch("https://api.moda.app/v1/uploads", {
method: "POST",
headers: { Authorization: HEADERS.Authorization, "Moda-Version": HEADERS["Moda-Version"] },
body: briefForm,
}).then(r => r.json());
// brief.id = "file_01HT9..."
// 2. fan out — one task per prospect
const csv = Papa.parse(fs.readFileSync("prospects.csv", "utf8"), { header: true });
const kits = await fetch("https://api.moda.app/v1/brand-kits", { headers: HEADERS }).then(r => r.json());
const defaultKit = kits.data.find((k: any) => k.is_default);
const results: { prospect: string; task_id: string }[] = [];
for (const row of csv.data as any[]) {
const res = await fetch("https://api.moda.app/v1/tasks", {
method: "POST",
headers: HEADERS,
body: JSON.stringify({
prompt: `Personalized follow-up deck for ${row.company}.
Prospect: ${row.contact_name}, ${row.contact_role}.
Their focus area: ${row.focus_area}.
Use the attached brief as the source of truth for our product claims.`,
format: { category: "slides", width: 1920, height: 1080 },
number_of_slides: 8,
brand_kit_id: defaultKit?.id,
attachments: [
{ file_id: brief.id, role: "source", label: "Master brief" },
],
callback_url: CALLBACK_URL,
idempotency_key: `prospect-deck:${row.id}`, // stable per prospect
}),
});
if (res.status === 429) {
// rate limited — respect Retry-After and retry this prospect
const waitSec = Number(res.headers.get("Retry-After") ?? 10);
await new Promise(r => setTimeout(r, waitSec * 1000));
// simpler: push back onto the queue; full rate-limit handling left as an exercise
}
const task = await res.json();
results.push({ prospect: row.company, task_id: task.id });
}
fs.writeFileSync("tasks.json", JSON.stringify(results, null, 2));
console.log(`Queued ${results.length} tasks. Webhook will deliver results.`);