From d3f5a1ab8d4950313c5722061c5429fbac1bdad0 Mon Sep 17 00:00:00 2001 From: Regalijan Date: Sun, 24 Mar 2024 03:05:53 -0400 Subject: [PATCH] Properly handle multiple jobs per report --- functions/api/coconut.ts | 45 +++++++++++++++++++++++++++++++ functions/api/reports/complete.ts | 22 +++++++++------ functions/api/reports/submit.ts | 3 +-- 3 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 functions/api/coconut.ts diff --git a/functions/api/coconut.ts b/functions/api/coconut.ts new file mode 100644 index 0000000..b97b4c9 --- /dev/null +++ b/functions/api/coconut.ts @@ -0,0 +1,45 @@ +import { jsonError } from "../common.js"; + +export async function onRequestPost(context: RequestContext) { + const { searchParams } = new URL(context.request.url); + const id = searchParams.get("attachment"); + const token = searchParams.get("token"); + + if (!id || !token) return jsonError("Invalid report id or token", 400); + + const coconutData: { token: string } | null = await context.env.DATA.get( + `coconutjob_${id}`, + { type: "json" }, + ); + + if (!coconutData) + return jsonError("Request is stale or otherwise invalid", 400); + + if (coconutData.token !== token) return jsonError("Forbidden", 403); + + await context.env.DATA.delete(`coconutjob_${id}`); + + const { event } = await context.request.json(); + + if (event === "job.failed") { + await fetch(context.env.REPORTS_WEBHOOK, { + body: JSON.stringify({ + embeds: [ + { + title: "Transcoding Failed", + color: 16711680, + description: `Attachment ${id} could not be transcoded, please log in to Coconut to see what went wrong.`, + }, + ], + }), + headers: { + "content-type": "application/json", + }, + method: "POST", + }); + } + + return new Response(null, { + status: 204, + }); +} diff --git a/functions/api/reports/complete.ts b/functions/api/reports/complete.ts index 72ad807..7ead357 100644 --- a/functions/api/reports/complete.ts +++ b/functions/api/reports/complete.ts @@ -21,18 +21,19 @@ export async function onRequestPost(context: RequestContext) { if (!value) return jsonError("Report is missing", 500); - const coconutData = (await context.env.DATA.get(`coconutjob_${id}`, { + const coconutData = (await context.env.DATA.get(`coconutdata_${id}`, { type: "json", })) as { attachments: string[]; - token: string; } | null; if (coconutData) { - const coconutResponsePromises = []; + const responsePromises = []; - for (const attachment of coconutData.attachments) - coconutResponsePromises.push( + for (const attachment of coconutData.attachments) { + const token = crypto.randomUUID(); + + responsePromises.push( fetch("https://api.coconut.co/v2/jobs", { body: JSON.stringify({ input: { @@ -48,8 +49,8 @@ export async function onRequestPost(context: RequestContext) { }, notification: { params: { - report_id: id, - token: coconutData.token, + attachment: attachment, + token, }, type: "http", url: `https://${context.request.headers.get("host")}/api/coconut`, @@ -76,9 +77,14 @@ export async function onRequestPost(context: RequestContext) { }, method: "POST", }), + context.env.DATA.put(`coconutjob_${attachment}`, token, { + expirationTtl: 600, + }), ); + } - await Promise.allSettled(coconutResponsePromises); + await Promise.allSettled(responsePromises); + await context.env.DATA.delete(`coconutdata_${id}`); } if (context.env.REPORTS_WEBHOOK) { diff --git a/functions/api/reports/submit.ts b/functions/api/reports/submit.ts index acce0a0..f730665 100644 --- a/functions/api/reports/submit.ts +++ b/functions/api/reports/submit.ts @@ -180,10 +180,9 @@ export async function onRequestPost(context: RequestContext) { const { current_user: currentUser } = context.data; if (filesToProcess.length) await context.env.DATA.put( - `coconutjob_${reportId}`, + `coconutdata_${reportId}`, JSON.stringify({ attachments: filesToProcess, - token: crypto.randomUUID(), }), { expirationTtl: 1800,