feat: add monitor event send notification
This commit is contained in:
parent
af49417899
commit
0346dc21d9
@ -14,7 +14,7 @@ import { useCurrentWorkspaceId } from '../../store/user';
|
||||
export const NotificationList: React.FC = React.memo(() => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const currentWorkspaceId = useCurrentWorkspaceId();
|
||||
const { data: list = [], refetch } = trpc.notification.getAll.useQuery({
|
||||
const { data: list = [], refetch } = trpc.notification.all.useQuery({
|
||||
workspaceId: currentWorkspaceId!,
|
||||
});
|
||||
const [editingFormData, setEditingFormData] = useState<
|
||||
|
@ -1,13 +1,17 @@
|
||||
import { Monitor } from '@prisma/client';
|
||||
import { createSubscribeInitializer, subscribeEventBus } from '../../ws/shared';
|
||||
import { Monitor, Notification } from '@prisma/client';
|
||||
import { subscribeEventBus } from '../../ws/shared';
|
||||
import { prisma } from '../_client';
|
||||
import { monitorProviders } from './provider';
|
||||
import { sendNotification } from '../notification';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
export type MonitorUpsertData = Pick<
|
||||
Monitor,
|
||||
'workspaceId' | 'name' | 'type' | 'interval'
|
||||
> & { id?: string; active?: boolean; payload: Record<string, any> };
|
||||
|
||||
type MonitorWithNotification = Monitor & { notifications: Notification[] };
|
||||
|
||||
class MonitorManager {
|
||||
private monitorRunner: Record<string, MonitorRunner> = {};
|
||||
private isStarted = false;
|
||||
@ -15,8 +19,8 @@ class MonitorManager {
|
||||
/**
|
||||
* create or update
|
||||
*/
|
||||
async upsert(data: MonitorUpsertData): Promise<Monitor> {
|
||||
let monitor: Monitor;
|
||||
async upsert(data: MonitorUpsertData): Promise<MonitorWithNotification> {
|
||||
let monitor: MonitorWithNotification;
|
||||
if (data.id) {
|
||||
// update
|
||||
monitor = await prisma.monitor.update({
|
||||
@ -24,6 +28,9 @@ class MonitorManager {
|
||||
id: data.id,
|
||||
},
|
||||
data: { ...data },
|
||||
include: {
|
||||
notifications: true,
|
||||
},
|
||||
});
|
||||
|
||||
return monitor;
|
||||
@ -31,6 +38,9 @@ class MonitorManager {
|
||||
// create
|
||||
monitor = await prisma.monitor.create({
|
||||
data: { ...data },
|
||||
include: {
|
||||
notifications: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -63,6 +73,9 @@ class MonitorManager {
|
||||
where: {
|
||||
active: true,
|
||||
},
|
||||
include: {
|
||||
notifications: true,
|
||||
},
|
||||
});
|
||||
|
||||
Promise.all(
|
||||
@ -88,7 +101,7 @@ class MonitorRunner {
|
||||
isStopped = false;
|
||||
timer: NodeJS.Timeout | null = null;
|
||||
|
||||
constructor(public monitor: Monitor) {}
|
||||
constructor(public monitor: Monitor & { notifications: Notification[] }) {}
|
||||
|
||||
/**
|
||||
* Start single monitor
|
||||
@ -114,7 +127,7 @@ class MonitorRunner {
|
||||
}, interval * 1000);
|
||||
};
|
||||
|
||||
async function run() {
|
||||
const run = async () => {
|
||||
let value = 0;
|
||||
try {
|
||||
value = await provider.run(monitor);
|
||||
@ -132,6 +145,12 @@ class MonitorRunner {
|
||||
type: 'DOWN',
|
||||
},
|
||||
});
|
||||
await this.notify(
|
||||
`[${monitor.name}] 🔴 Down`,
|
||||
`[${monitor.name}] 🔴 Down\nTime: ${dayjs().format(
|
||||
'YYYY-MM-DD HH:mm:ss'
|
||||
)}`
|
||||
);
|
||||
} else if (value > 0 && currentStatus === 'DOWN') {
|
||||
await prisma.monitorEvent.create({
|
||||
data: {
|
||||
@ -140,6 +159,12 @@ class MonitorRunner {
|
||||
type: 'UP',
|
||||
},
|
||||
});
|
||||
await this.notify(
|
||||
`[${monitor.name}] ✅ Up`,
|
||||
`[${monitor.name}] ✅ Up\nTime: ${dayjs().format(
|
||||
'YYYY-MM-DD HH:mm:ss'
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
// insert into data
|
||||
@ -154,7 +179,7 @@ class MonitorRunner {
|
||||
|
||||
// Run next loop
|
||||
nextAction();
|
||||
}
|
||||
};
|
||||
|
||||
run();
|
||||
|
||||
@ -177,6 +202,17 @@ class MonitorRunner {
|
||||
this.stopMonitor();
|
||||
this.startMonitor();
|
||||
}
|
||||
|
||||
async notify(title: string, message: string) {
|
||||
const notifications = this.monitor.notifications;
|
||||
await Promise.all(
|
||||
notifications.map((n) =>
|
||||
sendNotification(n, title, message).catch((err) => {
|
||||
console.error(err);
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const monitorManager = new MonitorManager();
|
||||
|
@ -3,6 +3,7 @@ import { notificationProviders } from './provider';
|
||||
|
||||
export async function sendNotification(
|
||||
notification: Pick<Notification, 'name' | 'type' | 'payload'>,
|
||||
title: string,
|
||||
message: string
|
||||
) {
|
||||
const type = notification.type;
|
||||
@ -11,5 +12,5 @@ export async function sendNotification(
|
||||
throw new Error('Not match type:' + type);
|
||||
}
|
||||
|
||||
await notificationProviders[type].send(notification, message);
|
||||
await notificationProviders[type].send(notification, title, message);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ interface SMTPPayload {
|
||||
|
||||
// Fork from https://github.com/louislam/uptime-kuma/blob/HEAD/server/notification-providers/smtp.js
|
||||
export const smtp: NotificationProvider = {
|
||||
send: async (notification, message) => {
|
||||
send: async (notification, title, message) => {
|
||||
const payload = notification.payload as unknown as SMTPPayload;
|
||||
|
||||
const config: SMTPTransport.Options = {
|
||||
@ -34,7 +34,7 @@ export const smtp: NotificationProvider = {
|
||||
};
|
||||
}
|
||||
|
||||
const subject = message;
|
||||
const subject = title;
|
||||
const bodyTextContent = message;
|
||||
|
||||
const transporter = nodemailer.createTransport(config);
|
||||
|
@ -3,6 +3,7 @@ import { Notification } from '@prisma/client';
|
||||
export interface NotificationProvider {
|
||||
send: (
|
||||
notification: Pick<Notification, 'name' | 'type' | 'payload'>,
|
||||
title: string,
|
||||
message: string
|
||||
) => Promise<void>;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { prisma } from '../../model/_client';
|
||||
import { sendNotification } from '../../model/notification';
|
||||
|
||||
export const notificationRouter = router({
|
||||
getAll: workspaceProcedure.query(({ input }) => {
|
||||
all: workspaceProcedure.query(({ input }) => {
|
||||
const workspaceId = input.workspaceId;
|
||||
|
||||
return prisma.notification.findMany({
|
||||
@ -23,7 +23,11 @@ export const notificationRouter = router({
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
await sendNotification(input, `${input.name} + Notification Testing`);
|
||||
await sendNotification(
|
||||
input,
|
||||
`${input.name} Notification Testing`,
|
||||
`This is Notification Testing`
|
||||
);
|
||||
}),
|
||||
upsert: workspaceOwnerProcedure
|
||||
.input(
|
||||
|
Loading…
Reference in New Issue
Block a user