Update websocket to be consistant with streaming

This commit is contained in:
Owen
2026-04-16 21:27:06 -07:00
parent f932cc7aca
commit 3645cc5759
8 changed files with 275 additions and 49 deletions

View File

@@ -55,7 +55,7 @@ export async function sendAlertWebhook(
let response: Response;
try {
response = await fetch(url, {
method: "POST",
method: webhookConfig.method ?? "POST",
headers,
body,
signal: controller.signal
@@ -128,5 +128,13 @@ function buildHeaders(webhookConfig: WebhookAlertConfig): Record<string, string>
break;
}
if (webhookConfig.headers) {
for (const { key, value } of webhookConfig.headers) {
if (key.trim()) {
headers[key.trim()] = value;
}
}
}
return headers;
}

View File

@@ -41,6 +41,10 @@ export interface WebhookAlertConfig {
customHeaderName?: string;
/** Custom header value used when authType === "custom" */
customHeaderValue?: string;
/** Extra headers to send with every webhook request */
headers?: Array<{ key: string; value: string }>;
/** HTTP method (default POST) */
method?: string;
}
// ---------------------------------------------------------------------------

View File

@@ -28,6 +28,8 @@ import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import { encrypt } from "@server/lib/crypto";
import config from "@server/lib/config";
const SITE_EVENT_TYPES = ["site_online", "site_offline"] as const;
const HC_EVENT_TYPES = [
@@ -247,11 +249,12 @@ export async function createAlertRule(
}
if (webhookActions.length > 0) {
const serverSecret = config.getRawConfig().server.secret!;
await db.insert(alertWebhookActions).values(
webhookActions.map((wa) => ({
alertRuleId: rule.alertRuleId,
webhookUrl: wa.webhookUrl,
config: wa.config ?? null,
config: wa.config != null ? encrypt(wa.config, serverSecret) : null,
enabled: wa.enabled
}))
);

View File

@@ -29,6 +29,9 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import { and, eq } from "drizzle-orm";
import { decrypt } from "@server/lib/crypto";
import config from "@server/lib/config";
import { WebhookAlertConfig } from "@server/lib/alerts/types";
const paramsSchema = z
.object({
@@ -64,6 +67,7 @@ export type GetAlertRuleResponse = {
webhookUrl: string;
enabled: boolean;
lastSentAt: number | null;
config: WebhookAlertConfig | null;
}[];
};
@@ -172,12 +176,25 @@ export async function getAlertRule(
siteIds: siteRows.map((r) => r.siteId),
healthCheckIds: healthCheckRows.map((r) => r.healthCheckId),
recipients,
webhookActions: webhooks.map((w) => ({
webhookActionId: w.webhookActionId,
webhookUrl: w.webhookUrl,
enabled: w.enabled,
lastSentAt: w.lastSentAt ?? null
}))
webhookActions: webhooks.map((w) => {
let parsedConfig: WebhookAlertConfig | null = null;
if (w.config) {
try {
const serverSecret = config.getRawConfig().server.secret!;
const decrypted = decrypt(w.config, serverSecret);
parsedConfig = JSON.parse(decrypted) as WebhookAlertConfig;
} catch {
// best-effort return null if decryption fails
}
}
return {
webhookActionId: w.webhookActionId,
webhookUrl: w.webhookUrl,
enabled: w.enabled,
lastSentAt: w.lastSentAt ?? null,
config: parsedConfig
};
})
},
success: true,
error: false,

View File

@@ -29,6 +29,8 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import { and, eq } from "drizzle-orm";
import { encrypt } from "@server/lib/crypto";
import config from "@server/lib/config";
const SITE_EVENT_TYPES = ["site_online", "site_offline"] as const;
const HC_EVENT_TYPES = [
@@ -302,11 +304,12 @@ export async function updateAlertRule(
.where(eq(alertWebhookActions.alertRuleId, alertRuleId));
if (webhookActions.length > 0) {
const serverSecret = config.getRawConfig().server.secret!;
await db.insert(alertWebhookActions).values(
webhookActions.map((wa) => ({
alertRuleId,
webhookUrl: wa.webhookUrl,
config: wa.config ?? null,
config: wa.config != null ? encrypt(wa.config, serverSecret) : null,
enabled: wa.enabled
}))
);