mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-18 13:45:23 +02:00
458 lines
11 KiB
TypeScript
458 lines
11 KiB
TypeScript
import {
|
|
createDiscordNotification,
|
|
createEmailNotification,
|
|
createGotifyNotification,
|
|
createSlackNotification,
|
|
createTelegramNotification,
|
|
findNotificationById,
|
|
IS_CLOUD,
|
|
removeNotificationById,
|
|
sendDiscordNotification,
|
|
sendEmailNotification,
|
|
sendGotifyNotification,
|
|
sendServerThresholdNotifications,
|
|
sendSlackNotification,
|
|
sendTelegramNotification,
|
|
updateDiscordNotification,
|
|
updateEmailNotification,
|
|
updateGotifyNotification,
|
|
updateSlackNotification,
|
|
updateTelegramNotification,
|
|
} from "@dokploy/server";
|
|
import { TRPCError } from "@trpc/server";
|
|
import { desc, eq, sql } from "drizzle-orm";
|
|
import { z } from "zod";
|
|
import {
|
|
adminProcedure,
|
|
createTRPCRouter,
|
|
protectedProcedure,
|
|
publicProcedure,
|
|
} from "@/server/api/trpc";
|
|
import { db } from "@/server/db";
|
|
import {
|
|
apiCreateDiscord,
|
|
apiCreateEmail,
|
|
apiCreateGotify,
|
|
apiCreateSlack,
|
|
apiCreateTelegram,
|
|
apiFindOneNotification,
|
|
apiTestDiscordConnection,
|
|
apiTestEmailConnection,
|
|
apiTestGotifyConnection,
|
|
apiTestSlackConnection,
|
|
apiTestTelegramConnection,
|
|
apiUpdateDiscord,
|
|
apiUpdateEmail,
|
|
apiUpdateGotify,
|
|
apiUpdateSlack,
|
|
apiUpdateTelegram,
|
|
notifications,
|
|
server,
|
|
users_temp,
|
|
} from "@/server/db/schema";
|
|
|
|
export const notificationRouter = createTRPCRouter({
|
|
createSlack: adminProcedure
|
|
.input(apiCreateSlack)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
return await createSlackNotification(
|
|
input,
|
|
ctx.session.activeOrganizationId,
|
|
);
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error creating the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
updateSlack: adminProcedure
|
|
.input(apiUpdateSlack)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
const notification = await findNotificationById(input.notificationId);
|
|
if (notification.organizationId !== ctx.session.activeOrganizationId) {
|
|
throw new TRPCError({
|
|
code: "UNAUTHORIZED",
|
|
message: "You are not authorized to update this notification",
|
|
});
|
|
}
|
|
return await updateSlackNotification({
|
|
...input,
|
|
organizationId: ctx.session.activeOrganizationId,
|
|
});
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}),
|
|
testSlackConnection: adminProcedure
|
|
.input(apiTestSlackConnection)
|
|
.mutation(async ({ input }) => {
|
|
try {
|
|
await sendSlackNotification(input, {
|
|
channel: input.channel,
|
|
text: "Hi, From Dokploy 👋",
|
|
});
|
|
return true;
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error testing the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
createTelegram: adminProcedure
|
|
.input(apiCreateTelegram)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
return await createTelegramNotification(
|
|
input,
|
|
ctx.session.activeOrganizationId,
|
|
);
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error creating the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
|
|
updateTelegram: adminProcedure
|
|
.input(apiUpdateTelegram)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
const notification = await findNotificationById(input.notificationId);
|
|
if (notification.organizationId !== ctx.session.activeOrganizationId) {
|
|
throw new TRPCError({
|
|
code: "UNAUTHORIZED",
|
|
message: "You are not authorized to update this notification",
|
|
});
|
|
}
|
|
return await updateTelegramNotification({
|
|
...input,
|
|
organizationId: ctx.session.activeOrganizationId,
|
|
});
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error updating the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
testTelegramConnection: adminProcedure
|
|
.input(apiTestTelegramConnection)
|
|
.mutation(async ({ input }) => {
|
|
try {
|
|
await sendTelegramNotification(input, "Hi, From Dokploy 👋");
|
|
return true;
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error testing the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
createDiscord: adminProcedure
|
|
.input(apiCreateDiscord)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
return await createDiscordNotification(
|
|
input,
|
|
ctx.session.activeOrganizationId,
|
|
);
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error creating the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
|
|
updateDiscord: adminProcedure
|
|
.input(apiUpdateDiscord)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
const notification = await findNotificationById(input.notificationId);
|
|
if (notification.organizationId !== ctx.session.activeOrganizationId) {
|
|
throw new TRPCError({
|
|
code: "UNAUTHORIZED",
|
|
message: "You are not authorized to update this notification",
|
|
});
|
|
}
|
|
return await updateDiscordNotification({
|
|
...input,
|
|
organizationId: ctx.session.activeOrganizationId,
|
|
});
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error updating the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
|
|
testDiscordConnection: adminProcedure
|
|
.input(apiTestDiscordConnection)
|
|
.mutation(async ({ input }) => {
|
|
try {
|
|
const decorate = (decoration: string, text: string) =>
|
|
`${input.decoration ? decoration : ""} ${text}`.trim();
|
|
|
|
await sendDiscordNotification(input, {
|
|
title: decorate(">", "`🤚` - Test Notification"),
|
|
description: decorate(">", "Hi, From Dokploy 👋"),
|
|
color: 0xf3f7f4,
|
|
});
|
|
|
|
return true;
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error testing the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
createEmail: adminProcedure
|
|
.input(apiCreateEmail)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
return await createEmailNotification(
|
|
input,
|
|
ctx.session.activeOrganizationId,
|
|
);
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error creating the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
updateEmail: adminProcedure
|
|
.input(apiUpdateEmail)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
const notification = await findNotificationById(input.notificationId);
|
|
if (notification.organizationId !== ctx.session.activeOrganizationId) {
|
|
throw new TRPCError({
|
|
code: "UNAUTHORIZED",
|
|
message: "You are not authorized to update this notification",
|
|
});
|
|
}
|
|
return await updateEmailNotification({
|
|
...input,
|
|
organizationId: ctx.session.activeOrganizationId,
|
|
});
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error updating the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
testEmailConnection: adminProcedure
|
|
.input(apiTestEmailConnection)
|
|
.mutation(async ({ input }) => {
|
|
try {
|
|
await sendEmailNotification(
|
|
input,
|
|
"Test Email",
|
|
"<p>Hi, From Dokploy 👋</p>",
|
|
);
|
|
return true;
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error testing the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
remove: adminProcedure
|
|
.input(apiFindOneNotification)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
const notification = await findNotificationById(input.notificationId);
|
|
if (notification.organizationId !== ctx.session.activeOrganizationId) {
|
|
throw new TRPCError({
|
|
code: "UNAUTHORIZED",
|
|
message: "You are not authorized to delete this notification",
|
|
});
|
|
}
|
|
return await removeNotificationById(input.notificationId);
|
|
} catch (error) {
|
|
const message =
|
|
error instanceof Error
|
|
? error.message
|
|
: "Error deleting this notification";
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message,
|
|
});
|
|
}
|
|
}),
|
|
one: protectedProcedure
|
|
.input(apiFindOneNotification)
|
|
.query(async ({ input, ctx }) => {
|
|
const notification = await findNotificationById(input.notificationId);
|
|
if (notification.organizationId !== ctx.session.activeOrganizationId) {
|
|
throw new TRPCError({
|
|
code: "UNAUTHORIZED",
|
|
message: "You are not authorized to access this notification",
|
|
});
|
|
}
|
|
return notification;
|
|
}),
|
|
all: adminProcedure.query(async ({ ctx }) => {
|
|
return await db.query.notifications.findMany({
|
|
with: {
|
|
slack: true,
|
|
telegram: true,
|
|
discord: true,
|
|
email: true,
|
|
gotify: true,
|
|
},
|
|
orderBy: desc(notifications.createdAt),
|
|
where: eq(notifications.organizationId, ctx.session.activeOrganizationId),
|
|
});
|
|
}),
|
|
receiveNotification: publicProcedure
|
|
.input(
|
|
z.object({
|
|
ServerType: z.enum(["Dokploy", "Remote"]).default("Dokploy"),
|
|
Type: z.enum(["Memory", "CPU"]),
|
|
Value: z.number(),
|
|
Threshold: z.number(),
|
|
Message: z.string(),
|
|
Timestamp: z.string(),
|
|
Token: z.string(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input }) => {
|
|
try {
|
|
let organizationId = "";
|
|
let ServerName = "";
|
|
if (input.ServerType === "Dokploy") {
|
|
const result = await db
|
|
.select()
|
|
.from(users_temp)
|
|
.where(
|
|
sql`${users_temp.metricsConfig}::jsonb -> 'server' ->> 'token' = ${input.Token}`,
|
|
);
|
|
|
|
if (!result?.[0]?.id) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Token not found",
|
|
});
|
|
}
|
|
|
|
organizationId = result?.[0]?.id;
|
|
ServerName = "Dokploy";
|
|
} else {
|
|
const result = await db
|
|
.select()
|
|
.from(server)
|
|
.where(
|
|
sql`${server.metricsConfig}::jsonb -> 'server' ->> 'token' = ${input.Token}`,
|
|
);
|
|
|
|
if (!result?.[0]?.organizationId) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Token not found",
|
|
});
|
|
}
|
|
|
|
organizationId = result?.[0]?.organizationId;
|
|
ServerName = "Remote";
|
|
}
|
|
|
|
await sendServerThresholdNotifications(organizationId, {
|
|
...input,
|
|
ServerName,
|
|
});
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error sending the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
createGotify: adminProcedure
|
|
.input(apiCreateGotify)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
return await createGotifyNotification(
|
|
input,
|
|
ctx.session.activeOrganizationId,
|
|
);
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error creating the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
updateGotify: adminProcedure
|
|
.input(apiUpdateGotify)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
const notification = await findNotificationById(input.notificationId);
|
|
if (
|
|
IS_CLOUD &&
|
|
notification.organizationId !== ctx.session.activeOrganizationId
|
|
) {
|
|
throw new TRPCError({
|
|
code: "UNAUTHORIZED",
|
|
message: "You are not authorized to update this notification",
|
|
});
|
|
}
|
|
return await updateGotifyNotification({
|
|
...input,
|
|
organizationId: ctx.session.activeOrganizationId,
|
|
});
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}),
|
|
testGotifyConnection: adminProcedure
|
|
.input(apiTestGotifyConnection)
|
|
.mutation(async ({ input }) => {
|
|
try {
|
|
await sendGotifyNotification(
|
|
input,
|
|
"Test Notification",
|
|
"Hi, From Dokploy 👋",
|
|
);
|
|
return true;
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error testing the notification",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
getEmailProviders: adminProcedure.query(async ({ ctx }) => {
|
|
return await db.query.notifications.findMany({
|
|
where: eq(notifications.organizationId, ctx.session.activeOrganizationId),
|
|
with: {
|
|
email: true,
|
|
},
|
|
});
|
|
}),
|
|
});
|