kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 9a620ba2f31238f03cd28f1da5ef3838d67e4e8a 57 lines 1.4 kB view raw
1import { createHmac } from "node:crypto"; 2import { assertPublicWebhookDestination } from "./config"; 3 4type GenericWebhookPayload = Record<string, unknown>; 5 6const GENERIC_WEBHOOK_TIMEOUT_MS = 10_000; 7 8export async function postToGenericWebhook( 9 webhookUrl: string, 10 payload: GenericWebhookPayload, 11 secret?: string, 12): Promise<void> { 13 await assertPublicWebhookDestination(webhookUrl); 14 15 const body = JSON.stringify(payload); 16 const headers: Record<string, string> = { 17 "Content-Type": "application/json", 18 }; 19 20 if (secret) { 21 headers["X-Kaneo-Signature"] = createHmac("sha256", secret) 22 .update(body) 23 .digest("hex"); 24 } 25 26 const controller = new AbortController(); 27 const timeoutId = setTimeout( 28 () => controller.abort(), 29 GENERIC_WEBHOOK_TIMEOUT_MS, 30 ); 31 32 try { 33 const response = await fetch(webhookUrl, { 34 method: "POST", 35 headers, 36 body, 37 signal: controller.signal, 38 }); 39 40 if (!response.ok) { 41 const errorText = await response.text(); 42 throw new Error( 43 `Generic webhook request failed (${response.status}): ${errorText}`, 44 ); 45 } 46 } catch (error) { 47 if (error instanceof Error && error.name === "AbortError") { 48 throw new Error( 49 `Generic webhook request timed out after ${GENERIC_WEBHOOK_TIMEOUT_MS}ms`, 50 ); 51 } 52 53 throw error; 54 } finally { 55 clearTimeout(timeoutId); 56 } 57}