fix: correctly parse incoming JSON

This commit is contained in:
2026-06-11 19:45:17 +07:00 Unverified
parent 78d2c13352
commit 9432f281a8
+50 -46
View File
@@ -1,6 +1,6 @@
import type { App } from "@"; import type { App } from "@";
import { env } from "bun"; import { env } from "bun";
import { status } from "elysia"; import { status, t } from "elysia";
import { TTLCache } from "enka.ts"; import { TTLCache } from "enka.ts";
import { createLogger } from "@/lib/logger"; import { createLogger } from "@/lib/logger";
@@ -17,33 +17,63 @@ const pending = new Map<string, Pending>();
const log = createLogger("WH"); const log = createLogger("WH");
export function webhookMerger(app: App) { export function webhookMerger(app: App) {
return app.post("/webhook/:id", async ({ body, params: { id } }) => { return app.post(
const map = await getRoutes(); "/webhook/:id",
const cur = map.find((e) => e[0] === id); async ({ body, params: { id } }) => {
const map = await getRoutes();
const cur = map.find((e) => e[0] === id);
if (!cur) return status(404); if (!cur) return status(404);
const [, url, bufferTime] = cur; const [, url, bufferTime] = cur;
const existing = pending.get(id); const existing = pending.get(id);
if (existing) { if (existing) {
clearTimeout(existing.timer); clearTimeout(existing.timer);
existing.data = merge(existing.data, body); existing.data = merge(existing.data, body);
existing.count++; existing.count++;
log.debug`collected ${existing}`; log.debug`collected ${existing}`;
existing.timer = setTimeout(async () => { existing.timer = setTimeout(async () => {
log.debug`running ${existing}`; log.debug`running ${existing}`;
try {
const res = await fetch(url, {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify(existing.data),
});
if (!res.ok)
log.warn`Could not forward webhook: ${res.status}\n${await res.json().catch(() => res.text())}`;
} finally {
pending.delete(id);
}
}, bufferTime);
return status(202);
}
const state: Pending = {
data: body,
count: 1,
timer: undefined as never,
};
log.debug`collected ${state}`;
state.timer = setTimeout(async () => {
log.debug`running ${state}`;
try { try {
const res = await fetch(url, { const res = await fetch(url, {
method: "POST", method: "POST",
headers: { headers: {
"content-type": "application/json", "content-type": "application/json",
}, },
body: JSON.stringify(existing.data), body: JSON.stringify(state.data),
}); });
if (!res.ok) if (!res.ok)
log.warn`Could not forward webhook: ${res.status}\n${await res.json().catch(() => res.text())}`; log.warn`Could not forward webhook: ${res.status}\n${await res.json().catch(() => res.text())}`;
@@ -52,38 +82,12 @@ export function webhookMerger(app: App) {
} }
}, bufferTime); }, bufferTime);
pending.set(id, state);
return status(202); return status(202);
} },
{ body: t.Object({}, { additionalProperties: true }) },
const state: Pending = { );
data: body,
count: 1,
timer: undefined as never,
};
log.debug`collected ${state}`;
state.timer = setTimeout(async () => {
log.debug`running ${state}`;
try {
const res = await fetch(url, {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify(state.data),
});
if (!res.ok)
log.warn`Could not forward webhook: ${res.status}\n${await res.json().catch(() => res.text())}`;
} finally {
pending.delete(id);
}
}, bufferTime);
pending.set(id, state);
return status(202);
});
} }
type RouteMap = [string, string, number][]; type RouteMap = [string, string, number][];