mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor(notifications): minimize send notifications in more reusable fn
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
|||||||
notifications,
|
notifications,
|
||||||
} from "@/server/db/schema";
|
} from "@/server/db/schema";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { desc } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
createDiscordNotification,
|
createDiscordNotification,
|
||||||
createEmailNotification,
|
createEmailNotification,
|
||||||
@@ -28,16 +29,15 @@ import {
|
|||||||
createTelegramNotification,
|
createTelegramNotification,
|
||||||
findNotificationById,
|
findNotificationById,
|
||||||
removeNotificationById,
|
removeNotificationById,
|
||||||
sendDiscordTestNotification,
|
sendDiscordNotification,
|
||||||
sendEmailTestNotification,
|
sendEmailNotification,
|
||||||
sendSlackTestNotification,
|
sendSlackNotification,
|
||||||
sendTelegramTestNotification,
|
sendTelegramNotification,
|
||||||
updateDiscordNotification,
|
updateDiscordNotification,
|
||||||
updateEmailNotification,
|
updateEmailNotification,
|
||||||
updateSlackNotification,
|
updateSlackNotification,
|
||||||
updateTelegramNotification,
|
updateTelegramNotification,
|
||||||
} from "../services/notification";
|
} from "../services/notification";
|
||||||
import { desc } from "drizzle-orm";
|
|
||||||
|
|
||||||
export const notificationRouter = createTRPCRouter({
|
export const notificationRouter = createTRPCRouter({
|
||||||
createSlack: adminProcedure
|
createSlack: adminProcedure
|
||||||
@@ -71,7 +71,10 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiTestSlackConnection)
|
.input(apiTestSlackConnection)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
try {
|
try {
|
||||||
await sendSlackTestNotification(input);
|
await sendSlackNotification(input, {
|
||||||
|
channel: input.channel,
|
||||||
|
text: "Hi, From Dokploy 👋",
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -112,7 +115,7 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiTestTelegramConnection)
|
.input(apiTestTelegramConnection)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
try {
|
try {
|
||||||
await sendTelegramTestNotification(input);
|
await sendTelegramNotification(input, "Hi, From Dokploy 👋");
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -126,6 +129,12 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiCreateDiscord)
|
.input(apiCreateDiscord)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
try {
|
try {
|
||||||
|
// go to your discord server
|
||||||
|
// go to settings
|
||||||
|
// go to integrations
|
||||||
|
// add a new integration
|
||||||
|
// select webhook
|
||||||
|
// copy the webhook url
|
||||||
return await createDiscordNotification(input);
|
return await createDiscordNotification(input);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -154,7 +163,10 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiTestDiscordConnection)
|
.input(apiTestDiscordConnection)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
try {
|
try {
|
||||||
await sendDiscordTestNotification(input);
|
await sendDiscordNotification(input, {
|
||||||
|
title: "Test Notification",
|
||||||
|
description: "Hi, From Dokploy 👋",
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
@@ -195,7 +207,11 @@ export const notificationRouter = createTRPCRouter({
|
|||||||
.input(apiTestEmailConnection)
|
.input(apiTestEmailConnection)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
try {
|
try {
|
||||||
await sendEmailTestNotification(input);
|
await sendEmailNotification(
|
||||||
|
input,
|
||||||
|
"Test Email",
|
||||||
|
"<p>Hi, From Dokploy 👋</p>",
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
|
|||||||
@@ -420,97 +420,6 @@ export const updateDestinationById = async (
|
|||||||
return result[0];
|
return result[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sendSlackTestNotification = async (
|
|
||||||
slackTestConnection: typeof apiTestSlackConnection._type,
|
|
||||||
) => {
|
|
||||||
const { webhookUrl, channel } = slackTestConnection;
|
|
||||||
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ text: "Hi, From Dokploy 👋", channel }),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sendTelegramTestNotification = async (
|
|
||||||
telegramTestConnection: typeof apiTestTelegramConnection._type,
|
|
||||||
) => {
|
|
||||||
const { botToken, chatId } = telegramTestConnection;
|
|
||||||
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: "Hi, From Dokploy 👋",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sendDiscordTestNotification = async (
|
|
||||||
discordTestConnection: typeof apiTestDiscordConnection._type,
|
|
||||||
) => {
|
|
||||||
const { webhookUrl } = discordTestConnection;
|
|
||||||
// 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: "Hi, From Dokploy 👋",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sendEmailTestNotification = async (
|
|
||||||
emailTestConnection: typeof apiTestEmailConnection._type,
|
|
||||||
) => {
|
|
||||||
const { smtpServer, smtpPort, username, password, toAddresses, fromAddress } =
|
|
||||||
emailTestConnection;
|
|
||||||
const transporter = nodemailer.createTransport({
|
|
||||||
host: smtpServer,
|
|
||||||
port: smtpPort,
|
|
||||||
secure: smtpPort === 465,
|
|
||||||
auth: {
|
|
||||||
user: username,
|
|
||||||
pass: password,
|
|
||||||
},
|
|
||||||
} as SMTPTransport.Options);
|
|
||||||
// need to add a valid from address
|
|
||||||
const mailOptions = {
|
|
||||||
from: fromAddress,
|
|
||||||
to: toAddresses?.join(", "),
|
|
||||||
subject: "Test email",
|
|
||||||
text: "Hi, From Dokploy 👋",
|
|
||||||
};
|
|
||||||
|
|
||||||
await transporter.sendMail(mailOptions);
|
|
||||||
|
|
||||||
console.log("Email notification sent successfully");
|
|
||||||
};
|
|
||||||
|
|
||||||
interface BuildFailedEmailProps {
|
interface BuildFailedEmailProps {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
applicationName: string;
|
applicationName: string;
|
||||||
@@ -540,28 +449,10 @@ export const sendBuildErrorNotifications = async ({
|
|||||||
for (const notification of notificationList) {
|
for (const notification of notificationList) {
|
||||||
const { email, discord, telegram, slack } = notification;
|
const { email, discord, telegram, slack } = notification;
|
||||||
if (email) {
|
if (email) {
|
||||||
const {
|
await sendEmailNotification(
|
||||||
smtpServer,
|
email,
|
||||||
smtpPort,
|
"Build failed for dokploy",
|
||||||
username,
|
render(
|
||||||
password,
|
|
||||||
fromAddress,
|
|
||||||
toAddresses,
|
|
||||||
} = email;
|
|
||||||
const transporter = nodemailer.createTransport({
|
|
||||||
host: smtpServer,
|
|
||||||
port: smtpPort,
|
|
||||||
secure: smtpPort === 465,
|
|
||||||
auth: {
|
|
||||||
user: username,
|
|
||||||
pass: password,
|
|
||||||
},
|
|
||||||
} as SMTPTransport.Options);
|
|
||||||
const mailOptions = {
|
|
||||||
from: fromAddress,
|
|
||||||
to: toAddresses?.join(", "),
|
|
||||||
subject: "Build failed for dokploy",
|
|
||||||
html: render(
|
|
||||||
BuildFailedEmail({
|
BuildFailedEmail({
|
||||||
projectName,
|
projectName,
|
||||||
applicationName,
|
applicationName,
|
||||||
@@ -571,13 +462,12 @@ export const sendBuildErrorNotifications = async ({
|
|||||||
date: date.toLocaleString(),
|
date: date.toLocaleString(),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
};
|
);
|
||||||
await transporter.sendMail(mailOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (discord) {
|
if (discord) {
|
||||||
const { webhookUrl } = discord;
|
const { webhookUrl } = discord;
|
||||||
const embed = {
|
await sendDiscordNotification(discord, {
|
||||||
title: "⚠️ Build Failed",
|
title: "⚠️ Build Failed",
|
||||||
color: 0xff0000,
|
color: 0xff0000,
|
||||||
fields: [
|
fields: [
|
||||||
@@ -609,59 +499,31 @@ export const sendBuildErrorNotifications = async ({
|
|||||||
footer: {
|
footer: {
|
||||||
text: "Dokploy Build Notification",
|
text: "Dokploy Build Notification",
|
||||||
},
|
},
|
||||||
};
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
embeds: [embed],
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (telegram) {
|
if (telegram) {
|
||||||
const { botToken, chatId } = telegram;
|
await sendTelegramNotification(
|
||||||
const messageText = `
|
telegram,
|
||||||
<b>⚠️ Build Failed</b>
|
`
|
||||||
|
<b>⚠️ Build Failed</b>
|
||||||
<b>Project:</b> ${projectName}
|
|
||||||
<b>Application:</b> ${applicationName}
|
<b>Project:</b> ${projectName}
|
||||||
<b>Type:</b> ${applicationType}
|
<b>Application:</b> ${applicationName}
|
||||||
<b>Time:</b> ${date.toLocaleString()}
|
<b>Type:</b> ${applicationType}
|
||||||
|
<b>Time:</b> ${date.toLocaleString()}
|
||||||
<b>Error:</b>
|
|
||||||
<pre>${errorMessage}</pre>
|
<b>Error:</b>
|
||||||
|
<pre>${errorMessage}</pre>
|
||||||
<b>Build Details:</b> ${buildLink}
|
|
||||||
`;
|
<b>Build Details:</b> ${buildLink}
|
||||||
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: messageText,
|
|
||||||
parse_mode: "HTML",
|
|
||||||
disable_web_page_preview: true,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slack) {
|
if (slack) {
|
||||||
const { webhookUrl, channel } = slack;
|
const { channel } = slack;
|
||||||
const message = {
|
await sendSlackNotification(slack, {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
attachments: [
|
attachments: [
|
||||||
{
|
{
|
||||||
@@ -703,18 +565,7 @@ export const sendBuildErrorNotifications = async ({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(message),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -747,28 +598,10 @@ export const sendBuildSuccessNotifications = async ({
|
|||||||
const { email, discord, telegram, slack } = notification;
|
const { email, discord, telegram, slack } = notification;
|
||||||
|
|
||||||
if (email) {
|
if (email) {
|
||||||
const {
|
await sendEmailNotification(
|
||||||
smtpServer,
|
email,
|
||||||
smtpPort,
|
"Build success for dokploy",
|
||||||
username,
|
render(
|
||||||
password,
|
|
||||||
fromAddress,
|
|
||||||
toAddresses,
|
|
||||||
} = email;
|
|
||||||
const transporter = nodemailer.createTransport({
|
|
||||||
host: smtpServer,
|
|
||||||
port: smtpPort,
|
|
||||||
secure: smtpPort === 465,
|
|
||||||
auth: {
|
|
||||||
user: username,
|
|
||||||
pass: password,
|
|
||||||
},
|
|
||||||
} as SMTPTransport.Options);
|
|
||||||
const mailOptions = {
|
|
||||||
from: fromAddress,
|
|
||||||
to: toAddresses?.join(", "),
|
|
||||||
subject: "Build success for dokploy",
|
|
||||||
html: render(
|
|
||||||
BuildSuccessEmail({
|
BuildSuccessEmail({
|
||||||
projectName,
|
projectName,
|
||||||
applicationName,
|
applicationName,
|
||||||
@@ -777,13 +610,11 @@ export const sendBuildSuccessNotifications = async ({
|
|||||||
date: date.toLocaleString(),
|
date: date.toLocaleString(),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
};
|
);
|
||||||
await transporter.sendMail(mailOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (discord) {
|
if (discord) {
|
||||||
const { webhookUrl } = discord;
|
await sendDiscordNotification(discord, {
|
||||||
const embed = {
|
|
||||||
title: "✅ Build Success",
|
title: "✅ Build Success",
|
||||||
color: 0x00ff00,
|
color: 0x00ff00,
|
||||||
fields: [
|
fields: [
|
||||||
@@ -811,56 +642,28 @@ export const sendBuildSuccessNotifications = async ({
|
|||||||
footer: {
|
footer: {
|
||||||
text: "Dokploy Build Notification",
|
text: "Dokploy Build Notification",
|
||||||
},
|
},
|
||||||
};
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
embeds: [embed],
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (telegram) {
|
if (telegram) {
|
||||||
const { botToken, chatId } = telegram;
|
await sendTelegramNotification(
|
||||||
const messageText = `
|
telegram,
|
||||||
<b>✅ Build Success</b>
|
`
|
||||||
|
<b>✅ Build Success</b>
|
||||||
<b>Project:</b> ${projectName}
|
|
||||||
<b>Application:</b> ${applicationName}
|
<b>Project:</b> ${projectName}
|
||||||
<b>Type:</b> ${applicationType}
|
<b>Application:</b> ${applicationName}
|
||||||
<b>Time:</b> ${date.toLocaleString()}
|
<b>Type:</b> ${applicationType}
|
||||||
|
<b>Time:</b> ${date.toLocaleString()}
|
||||||
<b>Build Details:</b> ${buildLink}
|
|
||||||
`;
|
<b>Build Details:</b> ${buildLink}
|
||||||
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: messageText,
|
|
||||||
parse_mode: "HTML",
|
|
||||||
disable_web_page_preview: true,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slack) {
|
if (slack) {
|
||||||
const { webhookUrl, channel } = slack;
|
const { webhookUrl, channel } = slack;
|
||||||
const message = {
|
await sendSlackNotification(slack, {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
attachments: [
|
attachments: [
|
||||||
{
|
{
|
||||||
@@ -901,18 +704,7 @@ export const sendBuildSuccessNotifications = async ({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(message),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -945,28 +737,10 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
const { email, discord, telegram, slack } = notification;
|
const { email, discord, telegram, slack } = notification;
|
||||||
|
|
||||||
if (email) {
|
if (email) {
|
||||||
const {
|
await sendEmailNotification(
|
||||||
smtpServer,
|
email,
|
||||||
smtpPort,
|
"Database backup for dokploy",
|
||||||
username,
|
render(
|
||||||
password,
|
|
||||||
fromAddress,
|
|
||||||
toAddresses,
|
|
||||||
} = email;
|
|
||||||
const transporter = nodemailer.createTransport({
|
|
||||||
host: smtpServer,
|
|
||||||
port: smtpPort,
|
|
||||||
secure: smtpPort === 465,
|
|
||||||
auth: {
|
|
||||||
user: username,
|
|
||||||
pass: password,
|
|
||||||
},
|
|
||||||
} as SMTPTransport.Options);
|
|
||||||
const mailOptions = {
|
|
||||||
from: fromAddress,
|
|
||||||
to: toAddresses?.join(", "),
|
|
||||||
subject: "Database backup for dokploy",
|
|
||||||
html: render(
|
|
||||||
DatabaseBackupEmail({
|
DatabaseBackupEmail({
|
||||||
projectName,
|
projectName,
|
||||||
applicationName,
|
applicationName,
|
||||||
@@ -976,13 +750,11 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
date: date.toLocaleString(),
|
date: date.toLocaleString(),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
};
|
);
|
||||||
await transporter.sendMail(mailOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (discord) {
|
if (discord) {
|
||||||
const { webhookUrl } = discord;
|
await sendDiscordNotification(discord, {
|
||||||
const embed = {
|
|
||||||
title:
|
title:
|
||||||
type === "success"
|
type === "success"
|
||||||
? "✅ Database Backup Successful"
|
? "✅ Database Backup Successful"
|
||||||
@@ -1013,36 +785,23 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
name: "Type",
|
name: "Type",
|
||||||
value: type,
|
value: type,
|
||||||
},
|
},
|
||||||
|
...(type === "error" && errorMessage
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
name: "Error Message",
|
||||||
|
value: errorMessage,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
],
|
],
|
||||||
timestamp: date.toISOString(),
|
timestamp: date.toISOString(),
|
||||||
footer: {
|
footer: {
|
||||||
text: "Dokploy Database Backup Notification",
|
text: "Dokploy Database Backup Notification",
|
||||||
},
|
},
|
||||||
};
|
|
||||||
|
|
||||||
if (type === "error" && errorMessage) {
|
|
||||||
embed.fields.push({
|
|
||||||
name: "Error Message",
|
|
||||||
value: errorMessage as unknown as string,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
embeds: [embed],
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (telegram) {
|
if (telegram) {
|
||||||
const { botToken, chatId } = telegram;
|
|
||||||
const statusEmoji = type === "success" ? "✅" : "❌";
|
const statusEmoji = type === "success" ? "✅" : "❌";
|
||||||
const messageText = `
|
const messageText = `
|
||||||
<b>${statusEmoji} Database Backup ${type === "success" ? "Successful" : "Failed"}</b>
|
<b>${statusEmoji} Database Backup ${type === "success" ? "Successful" : "Failed"}</b>
|
||||||
@@ -1055,28 +814,12 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
<b>Status:</b> ${type === "success" ? "Successful" : "Failed"}
|
<b>Status:</b> ${type === "success" ? "Successful" : "Failed"}
|
||||||
${type === "error" && errorMessage ? `<b>Error:</b> ${errorMessage}` : ""}
|
${type === "error" && errorMessage ? `<b>Error:</b> ${errorMessage}` : ""}
|
||||||
`;
|
`;
|
||||||
const url = `https://api.telegram.org/bot${botToken}/sendMessage`;
|
await sendTelegramNotification(telegram, messageText);
|
||||||
const response = await fetch(url, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
chat_id: chatId,
|
|
||||||
text: messageText,
|
|
||||||
parse_mode: "HTML",
|
|
||||||
disable_web_page_preview: true,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slack) {
|
if (slack) {
|
||||||
const { webhookUrl, channel } = slack;
|
const { channel } = slack;
|
||||||
const message = {
|
await sendSlackNotification(slack, {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
attachments: [
|
attachments: [
|
||||||
{
|
{
|
||||||
@@ -1086,6 +829,15 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
? ":white_check_mark: *Database Backup Successful*"
|
? ":white_check_mark: *Database Backup Successful*"
|
||||||
: ":x: *Database Backup Failed*",
|
: ":x: *Database Backup Failed*",
|
||||||
fields: [
|
fields: [
|
||||||
|
...(type === "error" && errorMessage
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
title: "Error Message",
|
||||||
|
value: errorMessage,
|
||||||
|
short: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
{
|
{
|
||||||
title: "Project",
|
title: "Project",
|
||||||
value: projectName,
|
value: projectName,
|
||||||
@@ -1124,25 +876,7 @@ export const sendDatabaseBackupNotifications = async ({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
|
||||||
|
|
||||||
if (type === "error" && errorMessage) {
|
|
||||||
message.attachments[0].fields.push({
|
|
||||||
title: "Error Message",
|
|
||||||
value: errorMessage,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(message),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1165,40 +899,15 @@ export const sendDockerCleanupNotifications = async (
|
|||||||
const { email, discord, telegram, slack } = notification;
|
const { email, discord, telegram, slack } = notification;
|
||||||
|
|
||||||
if (email) {
|
if (email) {
|
||||||
const {
|
await sendEmailNotification(
|
||||||
smtpServer,
|
email,
|
||||||
smtpPort,
|
"Docker cleanup for dokploy",
|
||||||
username,
|
render(DockerCleanupEmail({ message, date: date.toLocaleString() })),
|
||||||
password,
|
);
|
||||||
fromAddress,
|
|
||||||
toAddresses,
|
|
||||||
} = email;
|
|
||||||
const transporter = nodemailer.createTransport({
|
|
||||||
host: smtpServer,
|
|
||||||
port: smtpPort,
|
|
||||||
secure: smtpPort === 465,
|
|
||||||
auth: {
|
|
||||||
user: username,
|
|
||||||
pass: password,
|
|
||||||
},
|
|
||||||
} as SMTPTransport.Options);
|
|
||||||
const mailOptions = {
|
|
||||||
from: fromAddress,
|
|
||||||
to: toAddresses?.join(", "),
|
|
||||||
subject: "Docker cleanup for dokploy",
|
|
||||||
html: render(
|
|
||||||
DockerCleanupEmail({
|
|
||||||
message,
|
|
||||||
date: date.toLocaleString(),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
await transporter.sendMail(mailOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (discord) {
|
if (discord) {
|
||||||
const { webhookUrl } = discord;
|
await sendDiscordNotification(discord, {
|
||||||
const embed = {
|
|
||||||
title: "✅ Docker Cleanup",
|
title: "✅ Docker Cleanup",
|
||||||
color: 0x00ff00,
|
color: 0x00ff00,
|
||||||
fields: [
|
fields: [
|
||||||
@@ -1211,51 +920,23 @@ export const sendDockerCleanupNotifications = async (
|
|||||||
footer: {
|
footer: {
|
||||||
text: "Dokploy Docker Cleanup Notification",
|
text: "Dokploy Docker Cleanup Notification",
|
||||||
},
|
},
|
||||||
};
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
embeds: [embed],
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (telegram) {
|
if (telegram) {
|
||||||
const { botToken, chatId } = telegram;
|
await sendTelegramNotification(
|
||||||
const messageText = `
|
telegram,
|
||||||
<b>✅ Docker Cleanup</b>
|
`
|
||||||
<b>Message:</b> ${message}
|
<b>✅ Docker Cleanup</b>
|
||||||
<b>Time:</b> ${date.toLocaleString()}
|
<b>Message:</b> ${message}
|
||||||
`;
|
<b>Time:</b> ${date.toLocaleString()}
|
||||||
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: messageText,
|
|
||||||
parse_mode: "HTML",
|
|
||||||
disable_web_page_preview: true,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slack) {
|
if (slack) {
|
||||||
const { webhookUrl, channel } = slack;
|
const { channel } = slack;
|
||||||
const messageResponse = {
|
await sendSlackNotification(slack, {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
attachments: [
|
attachments: [
|
||||||
{
|
{
|
||||||
@@ -1281,24 +962,13 @@ export const sendDockerCleanupNotifications = async (
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(messageResponse),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sendEmailNotification = async (
|
export const sendEmailNotification = async (
|
||||||
connection: typeof email.$inferSelect,
|
connection: typeof email.$inferInsert,
|
||||||
subject: string,
|
subject: string,
|
||||||
htmlContent: string,
|
htmlContent: string,
|
||||||
) => {
|
) => {
|
||||||
@@ -1320,7 +990,7 @@ export const sendEmailNotification = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const sendDiscordNotification = async (
|
export const sendDiscordNotification = async (
|
||||||
connection: typeof discord.$inferSelect,
|
connection: typeof discord.$inferInsert,
|
||||||
embed: any,
|
embed: any,
|
||||||
) => {
|
) => {
|
||||||
const response = await fetch(connection.webhookUrl, {
|
const response = await fetch(connection.webhookUrl, {
|
||||||
@@ -1333,7 +1003,7 @@ export const sendDiscordNotification = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const sendTelegramNotification = async (
|
export const sendTelegramNotification = async (
|
||||||
connection: typeof telegram.$inferSelect,
|
connection: typeof telegram.$inferInsert,
|
||||||
messageText: string,
|
messageText: string,
|
||||||
) => {
|
) => {
|
||||||
const url = `https://api.telegram.org/bot${connection.botToken}/sendMessage`;
|
const url = `https://api.telegram.org/bot${connection.botToken}/sendMessage`;
|
||||||
@@ -1352,7 +1022,7 @@ export const sendTelegramNotification = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const sendSlackNotification = async (
|
export const sendSlackNotification = async (
|
||||||
connection: typeof slack.$inferSelect,
|
connection: typeof slack.$inferInsert,
|
||||||
message: any,
|
message: any,
|
||||||
) => {
|
) => {
|
||||||
const response = await fetch(connection.webhookUrl, {
|
const response = await fetch(connection.webhookUrl, {
|
||||||
@@ -1380,41 +1050,17 @@ export const sendDokployRestartNotifications = async () => {
|
|||||||
const { email, discord, telegram, slack } = notification;
|
const { email, discord, telegram, slack } = notification;
|
||||||
|
|
||||||
if (email) {
|
if (email) {
|
||||||
const {
|
await sendEmailNotification(
|
||||||
smtpServer,
|
email,
|
||||||
smtpPort,
|
"Dokploy Server Restarted",
|
||||||
username,
|
render(DokployRestartEmail({ date: date.toLocaleString() })),
|
||||||
password,
|
);
|
||||||
fromAddress,
|
|
||||||
toAddresses,
|
|
||||||
} = email;
|
|
||||||
const transporter = nodemailer.createTransport({
|
|
||||||
host: smtpServer,
|
|
||||||
port: smtpPort,
|
|
||||||
secure: smtpPort === 465,
|
|
||||||
auth: {
|
|
||||||
user: username,
|
|
||||||
pass: password,
|
|
||||||
},
|
|
||||||
} as SMTPTransport.Options);
|
|
||||||
const mailOptions = {
|
|
||||||
from: fromAddress,
|
|
||||||
to: toAddresses?.join(", "),
|
|
||||||
subject: "Dokploy Server Restarted",
|
|
||||||
html: render(
|
|
||||||
DokployRestartEmail({
|
|
||||||
date: date.toLocaleString(),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
await transporter.sendMail(mailOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (discord) {
|
if (discord) {
|
||||||
const { webhookUrl } = discord;
|
await sendDiscordNotification(discord, {
|
||||||
const embed = {
|
|
||||||
title: "✅ Dokploy Server Restarted",
|
title: "✅ Dokploy Server Restarted",
|
||||||
color: 0xff0000,
|
color: 0x00ff00,
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "Time",
|
name: "Time",
|
||||||
@@ -1426,50 +1072,22 @@ export const sendDokployRestartNotifications = async () => {
|
|||||||
footer: {
|
footer: {
|
||||||
text: "Dokploy Restart Notification",
|
text: "Dokploy Restart Notification",
|
||||||
},
|
},
|
||||||
};
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
embeds: [embed],
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (telegram) {
|
if (telegram) {
|
||||||
const { botToken, chatId } = telegram;
|
await sendTelegramNotification(
|
||||||
const messageText = `
|
telegram,
|
||||||
<b>✅ Dokploy Serverd Restarted</b>
|
`
|
||||||
<b>Time:</b> ${date.toLocaleString()}
|
<b>✅ Dokploy Serverd Restarted</b>
|
||||||
`;
|
<b>Time:</b> ${date.toLocaleString()}
|
||||||
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: messageText,
|
|
||||||
parse_mode: "HTML",
|
|
||||||
disable_web_page_preview: true,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slack) {
|
if (slack) {
|
||||||
const { webhookUrl, channel } = slack;
|
const { channel } = slack;
|
||||||
const message = {
|
await sendSlackNotification(slack, {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
attachments: [
|
attachments: [
|
||||||
{
|
{
|
||||||
@@ -1491,18 +1109,7 @@ export const sendDokployRestartNotifications = async () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
|
||||||
const response = await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(message),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Error to send test notification");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -57,9 +57,8 @@ void app.prepare().then(async () => {
|
|||||||
// Timeout to wait for the database to be ready
|
// Timeout to wait for the database to be ready
|
||||||
await new Promise((resolve) => setTimeout(resolve, 7000));
|
await new Promise((resolve) => setTimeout(resolve, 7000));
|
||||||
await migration();
|
await migration();
|
||||||
|
await sendDokployRestartNotifications();
|
||||||
}
|
}
|
||||||
await sendDokployRestartNotifications();
|
|
||||||
|
|
||||||
server.listen(PORT);
|
server.listen(PORT);
|
||||||
console.log("Server Started:", PORT);
|
console.log("Server Started:", PORT);
|
||||||
deploymentWorker.run();
|
deploymentWorker.run();
|
||||||
|
|||||||
Reference in New Issue
Block a user