mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-09-14 11:06:15 +05:00
Merge pull request #4969 from Dokploy/fix/server-threshold-email
fix(notifications): send server threshold alerts through email, resend, gotify and ntfy
(cherry picked from commit 218687f46d)
[skip ci]
This commit is contained in:
parent
bd92dfb8c1
commit
19958ee9d9
91
packages/server/src/emails/emails/server-threshold.tsx
Normal file
91
packages/server/src/emails/emails/server-threshold.tsx
Normal file
@ -0,0 +1,91 @@
|
||||
import {
|
||||
Body,
|
||||
Container,
|
||||
Head,
|
||||
Heading,
|
||||
Html,
|
||||
Img,
|
||||
Preview,
|
||||
Section,
|
||||
Tailwind,
|
||||
Text,
|
||||
} from "@react-email/components";
|
||||
import { emailTailwindConfig } from "../tailwind-config";
|
||||
|
||||
export type TemplateProps = {
|
||||
serverName: string;
|
||||
type: "CPU" | "Memory";
|
||||
value: string;
|
||||
threshold: string;
|
||||
message: string;
|
||||
date: string;
|
||||
};
|
||||
|
||||
export const ServerThresholdEmail = ({
|
||||
serverName = "my-server",
|
||||
type = "CPU",
|
||||
value = "95.00",
|
||||
threshold = "90.00",
|
||||
message = "Resource usage exceeded the configured threshold",
|
||||
date = "2023-05-01T00:00:00.000Z",
|
||||
}: TemplateProps) => {
|
||||
const previewText = `Server ${type} alert for ${serverName} ⚠️`;
|
||||
return (
|
||||
<Html>
|
||||
<Preview>{previewText}</Preview>
|
||||
<Tailwind config={emailTailwindConfig}>
|
||||
<Head />
|
||||
|
||||
<Body className="bg-white my-auto mx-auto font-sans px-2">
|
||||
<Container className="border border-solid border-[#eaeaea] rounded-lg my-[40px] mx-auto p-[20px] max-w-[465px]">
|
||||
<Section className="mt-[32px]">
|
||||
<Img
|
||||
src={
|
||||
"https://raw.githubusercontent.com/Dokploy/dokploy/refs/heads/canary/apps/dokploy/logo.png"
|
||||
}
|
||||
width="100"
|
||||
height="50"
|
||||
alt="Dokploy"
|
||||
className="my-0 mx-auto"
|
||||
/>
|
||||
</Section>
|
||||
<Heading className="text-black text-[24px] font-normal text-center p-0 my-[30px] mx-0">
|
||||
⚠️ Server {type} alert for <strong>{serverName}</strong>
|
||||
</Heading>
|
||||
<Text className="text-black text-[14px] leading-[24px]">
|
||||
Hello,
|
||||
</Text>
|
||||
<Text className="text-black text-[14px] leading-[24px]">
|
||||
The {type} usage on <strong>{serverName}</strong> exceeded the
|
||||
configured threshold.
|
||||
</Text>
|
||||
<Section className="flex text-black text-[14px] leading-[24px] bg-[#F4F4F5] rounded-lg p-2">
|
||||
<Text className="!leading-3 font-bold">Details: </Text>
|
||||
<Text className="!leading-3">
|
||||
Server Name: <strong>{serverName}</strong>
|
||||
</Text>
|
||||
<Text className="!leading-3">
|
||||
Type: <strong>{type}</strong>
|
||||
</Text>
|
||||
<Text className="!leading-3">
|
||||
Current Value: <strong>{value}%</strong>
|
||||
</Text>
|
||||
<Text className="!leading-3">
|
||||
Threshold: <strong>{threshold}%</strong>
|
||||
</Text>
|
||||
<Text className="!leading-3">
|
||||
Date: <strong>{date}</strong>
|
||||
</Text>
|
||||
</Section>
|
||||
<Section className="flex text-black text-[14px] mt-4 leading-[24px] bg-[#F4F4F5] rounded-lg p-2">
|
||||
<Text className="!leading-3 font-bold">Message: </Text>
|
||||
<Text className="text-[12px] leading-[24px]">{message}</Text>
|
||||
</Section>
|
||||
</Container>
|
||||
</Body>
|
||||
</Tailwind>
|
||||
</Html>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServerThresholdEmail;
|
||||
@ -1,12 +1,18 @@
|
||||
import { render } from "@react-email/components";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { db } from "../../db";
|
||||
import { notifications } from "../../db/schema";
|
||||
import ServerThresholdEmail from "../../emails/emails/server-threshold";
|
||||
import {
|
||||
sendCustomNotification,
|
||||
sendDiscordNotification,
|
||||
sendEmailNotification,
|
||||
sendGotifyNotification,
|
||||
sendLarkNotification,
|
||||
sendMattermostNotification,
|
||||
sendNtfyNotification,
|
||||
sendPushoverNotification,
|
||||
sendResendNotification,
|
||||
sendSlackNotification,
|
||||
sendTeamsNotification,
|
||||
sendTelegramNotification,
|
||||
@ -39,6 +45,9 @@ export const sendServerThresholdNotifications = async (
|
||||
discord: true,
|
||||
telegram: true,
|
||||
slack: true,
|
||||
resend: true,
|
||||
gotify: true,
|
||||
ntfy: true,
|
||||
mattermost: true,
|
||||
custom: true,
|
||||
lark: true,
|
||||
@ -52,9 +61,13 @@ export const sendServerThresholdNotifications = async (
|
||||
|
||||
for (const notification of notificationList) {
|
||||
const {
|
||||
email,
|
||||
discord,
|
||||
telegram,
|
||||
slack,
|
||||
resend,
|
||||
gotify,
|
||||
ntfy,
|
||||
mattermost,
|
||||
custom,
|
||||
lark,
|
||||
@ -63,6 +76,64 @@ export const sendServerThresholdNotifications = async (
|
||||
} = notification;
|
||||
|
||||
try {
|
||||
if (email || resend) {
|
||||
const template = await render(
|
||||
ServerThresholdEmail({
|
||||
serverName: payload.ServerName,
|
||||
type: payload.Type,
|
||||
value: payload.Value.toFixed(2),
|
||||
threshold: payload.Threshold.toFixed(2),
|
||||
message: payload.Message,
|
||||
date: date.toLocaleString(),
|
||||
}),
|
||||
);
|
||||
|
||||
if (email) {
|
||||
await sendEmailNotification(
|
||||
email,
|
||||
`Server ${payload.Type} alert for ${payload.ServerName}`,
|
||||
template,
|
||||
);
|
||||
}
|
||||
|
||||
if (resend) {
|
||||
await sendResendNotification(
|
||||
resend,
|
||||
`Server ${payload.Type} alert for ${payload.ServerName}`,
|
||||
template,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (gotify) {
|
||||
const decorate = (decoration: string, text: string) =>
|
||||
`${gotify.decoration ? decoration : ""} ${text}\n`;
|
||||
|
||||
await sendGotifyNotification(
|
||||
gotify,
|
||||
decorate("⚠️", `Server ${payload.Type} Alert`),
|
||||
`${decorate("🏷️", `Server: ${payload.ServerName}`)}` +
|
||||
`${decorate("📊", `Current Value: ${payload.Value.toFixed(2)}%`)}` +
|
||||
`${decorate("⚠️", `Threshold: ${payload.Threshold.toFixed(2)}%`)}` +
|
||||
`${decorate("📜", `Message: ${payload.Message}`)}` +
|
||||
`${decorate("🕒", `Date: ${date.toLocaleString()}`)}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (ntfy) {
|
||||
await sendNtfyNotification(
|
||||
ntfy,
|
||||
`Server ${payload.Type} Alert`,
|
||||
"warning",
|
||||
"",
|
||||
`🏷️Server: ${payload.ServerName}\n` +
|
||||
`📊Current Value: ${payload.Value.toFixed(2)}%\n` +
|
||||
`⚠️Threshold: ${payload.Threshold.toFixed(2)}%\n` +
|
||||
`📜Message: ${payload.Message}\n` +
|
||||
`🕒Date: ${date.toLocaleString()}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (discord) {
|
||||
const decorate = (decoration: string, text: string) =>
|
||||
`${discord.decoration ? decoration : ""} ${text}`.trim();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user