mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(notifications): add build failed and invitation emails from react-email
This commit is contained in:
@@ -10,11 +10,17 @@ import {
|
||||
apiCreateSlack,
|
||||
apiCreateTelegram,
|
||||
apiFindOneNotification,
|
||||
apiSendTest,
|
||||
apiUpdateDestination,
|
||||
apiTestDiscordConnection,
|
||||
apiTestEmailConnection,
|
||||
apiTestSlackConnection,
|
||||
apiTestTelegramConnection,
|
||||
apiUpdateDiscord,
|
||||
apiUpdateEmail,
|
||||
apiUpdateSlack,
|
||||
apiUpdateTelegram,
|
||||
notifications,
|
||||
} from "@/server/db/schema";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { updateDestinationById } from "../services/destination";
|
||||
import {
|
||||
createDiscordNotification,
|
||||
createEmailNotification,
|
||||
@@ -22,8 +28,16 @@ import {
|
||||
createTelegramNotification,
|
||||
findNotificationById,
|
||||
removeNotificationById,
|
||||
sendDiscordTestNotification,
|
||||
sendEmailTestNotification,
|
||||
sendSlackTestNotification,
|
||||
sendTelegramTestNotification,
|
||||
updateDiscordNotification,
|
||||
updateEmailNotification,
|
||||
updateSlackNotification,
|
||||
updateTelegramNotification,
|
||||
} from "../services/notification";
|
||||
import nodemailer from "nodemailer";
|
||||
import { desc } from "drizzle-orm";
|
||||
|
||||
export const notificationRouter = createTRPCRouter({
|
||||
createSlack: adminProcedure
|
||||
@@ -35,7 +49,34 @@ export const notificationRouter = createTRPCRouter({
|
||||
console.log(error);
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to create the destination",
|
||||
message: "Error to create the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateSlack: adminProcedure
|
||||
.input(apiUpdateSlack)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
return await updateSlackNotification(input);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to update the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
testSlackConnection: adminProcedure
|
||||
.input(apiTestSlackConnection)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
await sendSlackTestNotification(input);
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to test the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
@@ -48,7 +89,35 @@ export const notificationRouter = createTRPCRouter({
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to create the destination",
|
||||
message: "Error to create the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
updateTelegram: adminProcedure
|
||||
.input(apiUpdateTelegram)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
return await updateTelegramNotification(input);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to update the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
testTelegramConnection: adminProcedure
|
||||
.input(apiTestTelegramConnection)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
await sendTelegramTestNotification(input);
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to test the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
@@ -61,7 +130,36 @@ export const notificationRouter = createTRPCRouter({
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to create the destination",
|
||||
message: "Error to create the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
updateDiscord: adminProcedure
|
||||
.input(apiUpdateDiscord)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
return await updateDiscordNotification(input);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to update the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
testDiscordConnection: adminProcedure
|
||||
.input(apiTestDiscordConnection)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
await sendDiscordTestNotification(input);
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to test the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
@@ -72,9 +170,37 @@ export const notificationRouter = createTRPCRouter({
|
||||
try {
|
||||
return await createEmailNotification(input);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to create the destination",
|
||||
message: "Error to create the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateEmail: adminProcedure
|
||||
.input(apiUpdateEmail)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
return await updateEmailNotification(input);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to update the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
testEmailConnection: adminProcedure
|
||||
.input(apiTestEmailConnection)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
await sendEmailTestNotification(input);
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to test the notification",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
@@ -97,127 +223,6 @@ export const notificationRouter = createTRPCRouter({
|
||||
const notification = await findNotificationById(input.notificationId);
|
||||
return notification;
|
||||
}),
|
||||
testConnection: adminProcedure
|
||||
.input(apiSendTest)
|
||||
.mutation(async ({ input }) => {
|
||||
const notificationType = input.notificationType;
|
||||
console.log(input);
|
||||
|
||||
if (notificationType === "slack") {
|
||||
// go to your slack dashboard
|
||||
// go to integrations
|
||||
// add a new integration
|
||||
// select incoming webhook
|
||||
// copy the webhook url
|
||||
console.log("test slack");
|
||||
const { webhookUrl, channel } = input;
|
||||
try {
|
||||
const response = await fetch(webhookUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ text: "Test notification", channel }),
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
} else if (notificationType === "telegram") {
|
||||
// start telegram
|
||||
// search BotFather
|
||||
// send /newbot
|
||||
// name
|
||||
// name-with-bot-at-the-end
|
||||
// copy the token
|
||||
// search @userinfobot
|
||||
// send /start
|
||||
// copy the Id
|
||||
const { botToken, chatId } = input;
|
||||
try {
|
||||
const url = `https://api.telegram.org/bot${botToken}/sendMessage`;
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
chat_id: chatId,
|
||||
text: "Test notification",
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Error sending Telegram notification: ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
|
||||
console.log("Telegram notification sent successfully");
|
||||
} catch (error) {
|
||||
console.error("Error sending Telegram notification:", error);
|
||||
throw new Error("Error sending Telegram notification");
|
||||
}
|
||||
} else if (notificationType === "discord") {
|
||||
const { webhookUrl } = input;
|
||||
try {
|
||||
// go to your discord server
|
||||
// go to settings
|
||||
// go to integrations
|
||||
// add a new integration
|
||||
// select webhook
|
||||
// copy the webhook url
|
||||
const response = await fetch(webhookUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
content: "Test notification",
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Error sending Discord notification: ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
|
||||
console.log("Discord notification sent successfully");
|
||||
} catch (error) {
|
||||
console.error("Error sending Discord notification:", error);
|
||||
throw new Error("Error sending Discord notification");
|
||||
}
|
||||
} else if (notificationType === "email") {
|
||||
const { smtpServer, smtpPort, username, password, toAddresses } = input;
|
||||
try {
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: smtpServer,
|
||||
port: smtpPort,
|
||||
secure: smtpPort === "465",
|
||||
auth: {
|
||||
user: username,
|
||||
pass: password,
|
||||
},
|
||||
});
|
||||
// need to add a valid from address
|
||||
const fromAddress = "no-reply@emails.dokploy.com";
|
||||
const mailOptions = {
|
||||
from: fromAddress,
|
||||
to: toAddresses?.join(", "),
|
||||
subject: "Test email",
|
||||
text: "Test email",
|
||||
};
|
||||
|
||||
await transporter.sendMail(mailOptions);
|
||||
|
||||
console.log("Email notification sent successfully");
|
||||
} catch (error) {
|
||||
console.error("Error sending Email notification:", error);
|
||||
throw new Error("Error sending Email notification");
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
all: adminProcedure.query(async () => {
|
||||
return await db.query.notifications.findMany({
|
||||
with: {
|
||||
@@ -226,19 +231,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
discord: true,
|
||||
email: true,
|
||||
},
|
||||
orderBy: desc(notifications.createdAt),
|
||||
});
|
||||
}),
|
||||
update: adminProcedure
|
||||
.input(apiUpdateDestination)
|
||||
.mutation(async ({ input }) => {
|
||||
try {
|
||||
return await updateDestinationById(input.destinationId, input);
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error to update this destination",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user