2025-11-30 12:21:21 +01:00
|
|
|
"use server";
|
|
|
|
|
import { eq } from "drizzle-orm";
|
|
|
|
|
import { dispatchViaProvider } from "./providers";
|
|
|
|
|
import type {EventPayload, DispatchResult} from "./types";
|
2025-11-09 16:47:58 +01:00
|
|
|
import * as drizzleDb from "@/db";
|
2025-11-30 12:21:21 +01:00
|
|
|
import { db } from "@/db";
|
|
|
|
|
import { notificationLog } from "@/db/schema/11_notification-log";
|
|
|
|
|
import {NotificationChannel} from "@/db/schema/09_notification-channel";
|
|
|
|
|
import {Json} from "drizzle-zod";
|
2025-11-09 16:47:58 +01:00
|
|
|
|
|
|
|
|
export async function dispatchNotification(
|
|
|
|
|
payload: EventPayload,
|
|
|
|
|
policyId?: string,
|
|
|
|
|
channelId?: string,
|
2025-11-30 12:21:21 +01:00
|
|
|
organizationId?: string
|
2025-11-09 16:47:58 +01:00
|
|
|
): Promise<DispatchResult> {
|
2025-11-30 12:21:21 +01:00
|
|
|
try {
|
|
|
|
|
let channel: NotificationChannel | null = null;
|
2025-11-09 16:47:58 +01:00
|
|
|
|
2025-11-30 12:21:21 +01:00
|
|
|
if (policyId) {
|
|
|
|
|
const policy = await db.query.alertPolicy.findFirst({
|
|
|
|
|
where: eq(drizzleDb.schemas.alertPolicy.id, policyId),
|
|
|
|
|
with: {
|
|
|
|
|
notificationChannel: true
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-11-29 23:12:06 +01:00
|
|
|
|
2025-11-30 12:21:21 +01:00
|
|
|
if (!policy || !policy.notificationChannel) {
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
channelId: "",
|
|
|
|
|
provider: null,
|
|
|
|
|
error: "Policy or associated channel not found",
|
|
|
|
|
};
|
|
|
|
|
}
|
2025-11-09 16:47:58 +01:00
|
|
|
|
2025-11-30 12:21:21 +01:00
|
|
|
if (!policy.enabled || !policy.notificationChannel.enabled) {
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
channelId: policy.notificationChannel.id,
|
|
|
|
|
provider: policy.notificationChannel.provider as any,
|
|
|
|
|
error: "Policy or channel is disabled",
|
|
|
|
|
};
|
|
|
|
|
}
|
2025-11-09 16:47:58 +01:00
|
|
|
|
2025-11-30 12:21:21 +01:00
|
|
|
channel = {
|
|
|
|
|
...policy.notificationChannel,
|
|
|
|
|
config : policy.notificationChannel.config as Json,
|
2025-11-09 16:47:58 +01:00
|
|
|
};
|
|
|
|
|
}
|
2025-11-30 12:21:21 +01:00
|
|
|
|
|
|
|
|
if (channelId) {
|
|
|
|
|
const fetchedChannel = await db.query.notificationChannel.findFirst({
|
|
|
|
|
where: eq(drizzleDb.schemas.notificationChannel.id, channelId),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!fetchedChannel) {
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
channelId: channelId,
|
|
|
|
|
provider: null,
|
|
|
|
|
error: "Channel not found",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
channel = {
|
|
|
|
|
...fetchedChannel,
|
|
|
|
|
config : fetchedChannel.config as Json,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!channel) {
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
channelId: channelId || "",
|
|
|
|
|
provider: null,
|
|
|
|
|
error: "No valid channel to dispatch notification",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const result = await dispatchViaProvider(
|
|
|
|
|
channel.provider,
|
|
|
|
|
channel.config,
|
|
|
|
|
{ ...payload, timestamp: payload.timestamp || new Date() },
|
|
|
|
|
channel.id
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const [log] = await db
|
|
|
|
|
.insert(notificationLog)
|
|
|
|
|
.values({
|
|
|
|
|
channelId: channel.id,
|
|
|
|
|
policyId: policyId || null,
|
|
|
|
|
organizationId: organizationId || null,
|
|
|
|
|
title: payload.title,
|
|
|
|
|
message: payload.message,
|
|
|
|
|
level: payload.level,
|
|
|
|
|
payload: payload.data || null,
|
|
|
|
|
success: result.success,
|
|
|
|
|
error: result.success ? null : result.error,
|
|
|
|
|
providerResponse: result.response || null,
|
|
|
|
|
})
|
|
|
|
|
.returning({ id: notificationLog.id });
|
|
|
|
|
|
|
|
|
|
return { ...result, channelId: channel.id };
|
|
|
|
|
|
|
|
|
|
} catch (err: any) {
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
channelId: channelId || "",
|
|
|
|
|
provider: null,
|
|
|
|
|
error: err?.message || "Unexpected error during dispatch",
|
|
|
|
|
};
|
2025-11-09 16:47:58 +01:00
|
|
|
}
|
2025-11-30 12:21:21 +01:00
|
|
|
}
|