feat: add task workflow and asset downloads
This commit is contained in:
71
lib/server/webhook.ts
Normal file
71
lib/server/webhook.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { createHmac } from "node:crypto";
|
||||
import type { GenerationJob, WebhookLastStatus } from "@/lib/types";
|
||||
|
||||
export type JobWebhookPayload = {
|
||||
jobId: string;
|
||||
status: GenerationJob["status"];
|
||||
capability: GenerationJob["capability"];
|
||||
outputAssetIds: string[];
|
||||
error?: GenerationJob["error"];
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
const MAX_WEBHOOK_ATTEMPTS = 3;
|
||||
|
||||
export function buildJobWebhookPayload(job: GenerationJob): JobWebhookPayload {
|
||||
return {
|
||||
jobId: job.id,
|
||||
status: job.status,
|
||||
capability: job.capability,
|
||||
outputAssetIds: job.outputAssetIds,
|
||||
error: job.error,
|
||||
updatedAt: job.updatedAt
|
||||
};
|
||||
}
|
||||
|
||||
export function signWebhookBody(body: string, secret = process.env.ZHINIAN_WEBHOOK_SECRET): string | undefined {
|
||||
if (!secret?.trim()) return undefined;
|
||||
return `sha256=${createHmac("sha256", secret.trim()).update(body).digest("hex")}`;
|
||||
}
|
||||
|
||||
export async function deliverJobWebhook(job: GenerationJob): Promise<{
|
||||
attempts: number;
|
||||
lastStatus?: WebhookLastStatus;
|
||||
}> {
|
||||
if (!job.webhookUrl) return { attempts: job.webhookAttempts || 0 };
|
||||
let attempts = job.webhookAttempts || 0;
|
||||
let lastStatus: WebhookLastStatus | undefined = job.webhookLastStatus;
|
||||
const payload = buildJobWebhookPayload(job);
|
||||
const body = JSON.stringify(payload);
|
||||
const signature = signWebhookBody(body);
|
||||
|
||||
while (attempts < MAX_WEBHOOK_ATTEMPTS) {
|
||||
attempts += 1;
|
||||
const attemptedAt = new Date().toISOString();
|
||||
try {
|
||||
const response = await fetch(job.webhookUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "zhinian-aigc-webhook/1.0",
|
||||
...(signature ? { "X-Zhinian-Signature": signature } : {})
|
||||
},
|
||||
body
|
||||
});
|
||||
lastStatus = {
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
attemptedAt
|
||||
};
|
||||
if (response.ok) break;
|
||||
} catch (error) {
|
||||
lastStatus = {
|
||||
ok: false,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
attemptedAt
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return { attempts, lastStatus };
|
||||
}
|
||||
Reference in New Issue
Block a user