Files
Checkmate/server/service/notificationService.js
T

123 lines
3.7 KiB
JavaScript
Raw Normal View History

2025-04-20 11:29:53 -07:00
class NotificationService {
2025-06-19 12:12:55 +08:00
constructor({
emailService,
db,
logger,
networkService,
stringService,
notificationUtils,
}) {
2025-04-20 11:29:53 -07:00
this.emailService = emailService;
this.db = db;
this.logger = logger;
this.networkService = networkService;
this.stringService = stringService;
2025-06-19 12:12:55 +08:00
this.notificationUtils = notificationUtils;
2025-04-20 11:29:53 -07:00
}
2025-06-19 12:12:55 +08:00
sendNotification = async ({ notification, subject, content, html }) => {
const { type, address } = notification;
2025-04-20 11:29:53 -07:00
2025-06-19 12:12:55 +08:00
if (type === "email") {
const messageId = await this.emailService.sendEmail(address, subject, html);
if (!messageId) return false;
return true;
2025-04-20 11:29:53 -07:00
}
2025-05-29 17:09:47 -07:00
2025-06-19 12:12:55 +08:00
// Create a body for webhooks
let body = { text: content };
if (type === "discord") {
body = { content };
2025-06-16 13:53:08 +08:00
}
2025-05-29 17:09:47 -07:00
2025-06-19 12:12:55 +08:00
if (type === "slack" || type === "discord" || type === "webhook") {
const response = await this.networkService.requestWebhook(type, address, body);
2025-05-29 17:09:47 -07:00
return response.status;
2025-04-20 11:29:53 -07:00
}
2025-06-19 12:12:55 +08:00
if (type === "pager_duty") {
const response = await this.networkService.requestPagerDuty({
message: content,
monitorUrl: subject,
routingKey: address,
2025-06-18 10:44:59 +08:00
});
2025-04-20 11:29:53 -07:00
2025-06-19 12:12:55 +08:00
return response;
2025-06-10 13:44:15 +08:00
}
2025-06-10 13:20:44 +08:00
};
2025-06-19 12:12:55 +08:00
async handleNotifications(networkResponse) {
const { monitor, statusChanged, prevStatus } = networkResponse;
const { type } = monitor;
if (type !== "hardware" && statusChanged === false) return false;
// if prevStatus is undefined, monitor is resuming, we're done
if (type !== "hardware" && prevStatus === undefined) return false;
2025-06-18 10:44:59 +08:00
2025-06-19 12:12:55 +08:00
const notificationIDs = networkResponse.monitor?.notifications ?? [];
if (notificationIDs.length === 0) return false;
2025-06-18 10:44:59 +08:00
2025-06-19 12:12:55 +08:00
if (networkResponse.monitor.type === "hardware") {
const thresholds = networkResponse?.monitor?.thresholds;
2025-04-20 11:29:53 -07:00
2025-06-19 12:12:55 +08:00
if (thresholds === undefined) return false; // No thresholds set, we're done
const metrics = networkResponse?.payload?.data ?? null;
if (metrics === null) return false; // No metrics, we're done
2025-06-10 13:44:15 +08:00
2025-06-19 12:12:55 +08:00
const alerts = await this.notificationUtils.buildHardwareAlerts(networkResponse);
if (alerts.length === 0) return false;
2025-06-09 10:49:52 +08:00
2025-06-19 12:12:55 +08:00
const { subject, html } = await this.notificationUtils.buildHardwareEmail(
networkResponse,
2025-06-16 13:53:08 +08:00
alerts
);
2025-06-19 12:12:55 +08:00
const content =
await this.notificationUtils.buildHardwareNotificationMessage(alerts);
2025-05-29 17:09:47 -07:00
2025-06-19 12:12:55 +08:00
const success = await this.notifyAll({ notificationIDs, subject, html, content });
return success;
2025-04-20 11:29:53 -07:00
}
2025-06-16 13:53:08 +08:00
2025-06-19 12:12:55 +08:00
// Status monitors
const { subject, html } =
await this.notificationUtils.buildStatusEmail(networkResponse);
const content = await this.notificationUtils.buildWebhookMessage(networkResponse);
const success = this.notifyAll({ notificationIDs, subject, html, content });
return success;
2025-04-20 11:29:53 -07:00
}
2025-06-16 12:17:43 +08:00
2025-06-19 12:12:55 +08:00
async notifyAll({ notificationIDs, subject, html, content }) {
2025-06-16 12:17:43 +08:00
const notifications = await this.db.getNotificationsByIds(notificationIDs);
// Map each notification to a test promise
2025-06-19 12:12:55 +08:00
const promises = notifications.map(async (notification) => {
2025-06-16 12:17:43 +08:00
try {
2025-06-19 12:12:55 +08:00
await this.sendNotification({ notification, subject, content, html });
2025-06-16 12:17:43 +08:00
return true;
} catch (err) {
return false;
}
});
2025-06-19 12:12:55 +08:00
const results = await Promise.all(promises);
2025-06-16 12:17:43 +08:00
return results.every((r) => r === true);
}
2025-06-19 12:12:55 +08:00
async getTestNotification() {
const html = await this.notificationUtils.buildTestEmail();
const content = "This is a test notification";
const subject = "Test Notification";
return { subject, html, content };
}
async testAllNotifications(notificationIDs) {
const { subject, html, content } = await this.getTestNotification();
return this.notifyAll({ notificationIDs, subject, html, content });
}
async sendTestNotification(notification) {
const { subject, html, content } = await this.getTestNotification();
const success = await this.sendNotification({ notification, subject, content, html });
return success;
}
2025-04-20 11:29:53 -07:00
}
export default NotificationService;