import { db } from "@link-stack/bridge-common"; import { createLogger } from "@link-stack/logger"; const logger = createLogger('notify-webhooks'); export interface NotifyWebhooksOptions { backendId: string; payload: any; } const notifyWebhooksTask = async ( options: NotifyWebhooksOptions, ): Promise => { const { backendId, payload } = options; logger.debug({ backendId, payloadKeys: Object.keys(payload), }, 'Processing webhook notification'); const webhooks = await db .selectFrom("Webhook") .selectAll() .where("backendId", "=", backendId) .execute(); logger.debug({ count: webhooks.length, backendId }, 'Found webhooks'); for (const webhook of webhooks) { const { endpointUrl, httpMethod, headers } = webhook; const finalHeaders = { "Content-Type": "application/json", ...headers }; const body = JSON.stringify(payload); logger.debug({ url: endpointUrl, method: httpMethod, bodyLength: body.length, headerKeys: Object.keys(finalHeaders), }, 'Sending webhook'); try { const result = await fetch(endpointUrl, { method: httpMethod, headers: finalHeaders, body, }); logger.debug({ url: endpointUrl, status: result.status, statusText: result.statusText, ok: result.ok, }, 'Webhook response'); if (!result.ok) { const responseText = await result.text(); logger.error({ url: endpointUrl, status: result.status, responseSample: responseText.substring(0, 500), }, 'Webhook error response'); } } catch (error) { logger.error({ url: endpointUrl, error: error instanceof Error ? error.message : error, }, 'Webhook request failed'); } } }; export default notifyWebhooksTask;