add pager duty handling method

This commit is contained in:
Alex Holliday
2025-06-09 10:49:52 +08:00
parent 5a50e9b301
commit 92ddf023ec
5 changed files with 51 additions and 14 deletions

View File

@@ -18,10 +18,11 @@ const PLATFORMS = {
};
class NotificationController {
constructor(notificationService, stringService, statusService) {
constructor({ notificationService, stringService, statusService, db }) {
this.notificationService = notificationService;
this.stringService = stringService;
this.statusService = statusService;
this.db = db;
this.triggerNotification = this.triggerNotification.bind(this);
this.testWebhook = this.testWebhook.bind(this);
}

View File

@@ -39,6 +39,10 @@ const NotificationSchema = mongoose.Schema(
type: configSchema,
default: () => ({}),
},
notificationName: {
type: String,
required: true,
},
address: {
type: String,
},

View File

@@ -291,11 +291,12 @@ const startApp = async () => {
ServiceRegistry.get(StringService.SERVICE_NAME)
);
const notificationController = new NotificationController(
ServiceRegistry.get(NotificationService.SERVICE_NAME),
ServiceRegistry.get(StringService.SERVICE_NAME),
ServiceRegistry.get(StatusService.SERVICE_NAME)
);
const notificationController = new NotificationController({
notificationService: ServiceRegistry.get(NotificationService.SERVICE_NAME),
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
statusService: ServiceRegistry.get(StatusService.SERVICE_NAME),
db: ServiceRegistry.get(MongoDB.SERVICE_NAME),
});
const diagnosticController = new DiagnosticController(
ServiceRegistry.get(MongoDB.SERVICE_NAME)

View File

@@ -112,8 +112,7 @@ class NotificationService {
async sendWebhookNotification(networkResponse, notification) {
const { monitor, status, code } = networkResponse;
const { platform } = notification;
const { webhookUrl, botToken, chatId } = notification.config;
const { webhookUrl, platform, botToken, chatId } = notification.config;
// Early return if platform is not supported
if (!PLATFORM_TYPES.includes(platform)) {
@@ -204,6 +203,38 @@ class NotificationService {
return true;
}
async sendPagerDutyNotification(networkResponse, notification) {
const { monitor, status, code } = networkResponse;
const { routingKey, platform } = notification.config;
const message = this.formatNotificationMessage(
monitor,
status,
platform,
null,
code, // Pass the code field directly
networkResponse.timestamp
);
try {
const response = await this.networkService.requestPagerDuty({
message,
routingKey,
monitorUrl: monitor.url,
});
return response.status;
} catch (error) {
this.logger.error({
message: "Failed to send PagerDuty notification",
details: error.details,
service: error.service || this.SERVICE_NAME,
method: error.method || "sendPagerDutyNotification",
stack: error.stack,
});
return false;
}
}
async handleStatusNotifications(networkResponse) {
try {
// If status hasn't changed, we're done
@@ -211,17 +242,17 @@ class NotificationService {
// if prevStatus is undefined, monitor is resuming, we're done
if (networkResponse.prevStatus === undefined) return false;
const notifications = await this.db.getNotificationsByMonitorId(
networkResponse.monitorId
);
const notificationIDs = networkResponse.monitor?.notifications ?? [];
const notifications = await this.db.getNotificationsByIds(notificationIDs);
for (const notification of notifications) {
if (notification.type === "email") {
await this.sendEmail(networkResponse, notification.address);
} else if (notification.type === "webhook") {
await this.sendWebhookNotification(networkResponse, notification);
} else if (notification.type === "pager_duty") {
await this.sendPagerDutyNotification(networkResponse, notification);
}
// Handle other types of notifications here
}
return true;
} catch (error) {

View File

@@ -567,11 +567,11 @@ const triggerNotificationBodyValidation = joi.object({
});
const createNotificationBodyValidation = joi.object({
userId: joi.number().required().messages({
userId: joi.string().required().messages({
"number.empty": "User ID is required",
"any.required": "User ID is required",
}),
teamId: joi.number().required().messages({
teamId: joi.string().required().messages({
"string.empty": "Team ID is required",
"any.required": "Team ID is required",
}),