Add n8n community node, /api/v1/render alias, and job webhooks for OSS automation.

Payment-free self-hosted builds keep full API access with optional webhookUrl callbacks and the published n8n-nodes-songs2vid package source under integrations/n8n.
This commit is contained in:
Atakan Doğan Özban
2026-08-08 16:32:28 +02:00
parent 848607f9e0
commit f9b2a997a2
27 changed files with 7333 additions and 14 deletions
+52
View File
@@ -0,0 +1,52 @@
/**
* Deliver optional job webhooks for n8n / automation consumers.
* Fire-and-forget; failures are logged and never fail the encode/upload path.
*/
type WebhookPayload = {
event: "job.item.completed" | "job.item.failed" | "job.completed" | "job.failed" | "job.partial";
jobId: string;
status: string;
itemId?: string;
youtubeVideoId?: string | null;
error?: string | null;
completedAt?: string | null;
};
export async function deliverJobWebhook(
webhookUrl: string | null | undefined,
payload: WebhookPayload,
): Promise<void> {
if (!webhookUrl?.trim()) return;
let url: URL;
try {
url = new URL(webhookUrl.trim());
} catch {
console.warn(`[webhook] invalid URL for job ${payload.jobId}`);
return;
}
if (url.protocol !== "https:" && url.protocol !== "http:") {
console.warn(`[webhook] refused non-http(s) URL for job ${payload.jobId}`);
return;
}
try {
const res = await fetch(url.toString(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Songs2VID-Webhook/1.0",
},
body: JSON.stringify(payload),
signal: AbortSignal.timeout(8_000),
});
if (!res.ok) {
console.warn(`[webhook] ${payload.jobId}${res.status}`);
}
} catch (err) {
console.warn(
`[webhook] delivery failed for ${payload.jobId}:`,
err instanceof Error ? err.message : err,
);
}
}