diff --git a/server/src/config/services.ts b/server/src/config/services.ts index 035a0782f..953fc5a1a 100644 --- a/server/src/config/services.ts +++ b/server/src/config/services.ts @@ -228,12 +228,12 @@ export const initializeServices = async ({ settingsService, }); - const webhookProvider = new WebhookProvider(); - const slackProvider = new SlackProvider(); - const emailProvider = new EmailProvider(emailService); - const discordProvider = new DiscordProvider(); - const pagerDutyProvider = new PagerDutyProvider(); - const matrixProvider = new MatrixProvider(); + const webhookProvider = new WebhookProvider(logger); + const slackProvider = new SlackProvider(logger); + const emailProvider = new EmailProvider(emailService, logger); + const discordProvider = new DiscordProvider(logger); + const pagerDutyProvider = new PagerDutyProvider(logger); + const matrixProvider = new MatrixProvider(logger); const notificationsService = new NotificationsService( notificationsRepository, diff --git a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts index ebb0949b0..bbd3a11f0 100644 --- a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts +++ b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts @@ -18,7 +18,6 @@ class SuperSimpleQueueHelper { logger, networkService, statusService, - notificationService, notificationsService, checkService, buffer, diff --git a/server/src/service/infrastructure/notificationProviders/discord.ts b/server/src/service/infrastructure/notificationProviders/discord.ts index 5aa8dd1d4..83d8e4ec2 100644 --- a/server/src/service/infrastructure/notificationProviders/discord.ts +++ b/server/src/service/infrastructure/notificationProviders/discord.ts @@ -1,9 +1,10 @@ import type { Monitor, Notification, MonitorStatusResponse } from "@/types/index.js"; import { INotificationProvider } from "@/service/index.js"; -import { buildHardwareAlerts, buildDiscordBody } from "@/service/infrastructure/notificationProviders/utils.js"; +import { buildHardwareAlerts, buildDiscordBody, getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; import got from "got"; export class DiscordProvider implements INotificationProvider { + constructor(private logger: any) {} private getHardwareContent = (monitor: Monitor, monitorStatusResponse: MonitorStatusResponse) => { const { discordPayload } = buildHardwareAlerts("HOST_PLACEHOLDER", monitor, monitorStatusResponse); return discordPayload; @@ -22,6 +23,7 @@ export class DiscordProvider implements INotificationProvider { } try { + this.logger?.debug?.("Sending Discord alert", { address: notification.address }); await got.post(notification.address, { json: body, headers: { @@ -31,10 +33,27 @@ export class DiscordProvider implements INotificationProvider { }); return true; } catch (error: any) { + this.logger?.error?.("Discord alert failed", { error }); return false; } }; sendTestAlert = async (notification: Notification) => { - return false; + if (!notification.address) { + return false; + } + try { + this.logger?.debug?.("Sending Discord test alert", { address: notification.address }); + await got.post(notification.address, { + json: { content: getTestMessage() }, + headers: { + "Content-Type": "application/json", + }, + responseType: "json", + }); + return true; + } catch (error) { + this.logger?.error?.("Discord test alert failed", { error }); + return false; + } }; } diff --git a/server/src/service/infrastructure/notificationProviders/email.ts b/server/src/service/infrastructure/notificationProviders/email.ts index 0a405a078..344285e9c 100644 --- a/server/src/service/infrastructure/notificationProviders/email.ts +++ b/server/src/service/infrastructure/notificationProviders/email.ts @@ -4,7 +4,7 @@ import { buildHardwareAlerts, buildHardwareEmail, buildEmail, buildTestEmail } f export class EmailProvider implements INotificationProvider { private emailService: any; - constructor(emailService: any) { + constructor(emailService: any, private logger: any) { this.emailService = emailService; } @@ -27,6 +27,7 @@ export class EmailProvider implements INotificationProvider { return false; } + this.logger?.debug?.("Sending Email alert", { address: notification.address }); const messageId = await this.emailService.sendEmail(notification.address, subject, html); if (!messageId) return false; return true; @@ -35,6 +36,7 @@ export class EmailProvider implements INotificationProvider { async sendTestAlert(notification: Notification): Promise { const subject = "Test notification"; const html = await buildTestEmail(this.emailService); + this.logger?.debug?.("Sending Email test alert", { address: notification.address }); const messageId = await this.emailService.sendEmail(notification.address, subject, html); if (!messageId) return false; return true; diff --git a/server/src/service/infrastructure/notificationProviders/matrix.ts b/server/src/service/infrastructure/notificationProviders/matrix.ts index 8985ac10b..4592500a5 100644 --- a/server/src/service/infrastructure/notificationProviders/matrix.ts +++ b/server/src/service/infrastructure/notificationProviders/matrix.ts @@ -1,9 +1,15 @@ import got from "got"; import type { INotificationProvider } from "@/service/index.js"; import type { Notification, Monitor, MonitorStatusResponse } from "@/types/index.js"; -import { buildHardwareAlerts, buildHardwareWebhookBody, buildWebhookBody } from "@/service/infrastructure/notificationProviders/utils.js"; +import { + buildHardwareAlerts, + buildHardwareWebhookBody, + buildWebhookBody, + getTestMessage, +} from "@/service/infrastructure/notificationProviders/utils.js"; export class MatrixProvider implements INotificationProvider { + constructor(private logger: any) {} private getHardwareContent = (monitor: Monitor, monitorStatusResponse: MonitorStatusResponse) => { const { alertsToSend } = buildHardwareAlerts("HOST_PLACEHOLDER", monitor, monitorStatusResponse); const body = buildHardwareWebhookBody(alertsToSend, monitor); @@ -37,6 +43,7 @@ export class MatrixProvider implements INotificationProvider { formatted_body: formattedMessage, }; try { + this.logger?.debug?.("Sending Matrix alert", { room: roomId }); await got.post(url, { json: body, headers: { @@ -46,11 +53,34 @@ export class MatrixProvider implements INotificationProvider { }); return true; } catch (error) { + this.logger?.error?.("Matrix alert failed", { error }); return false; } }; sendTestAlert = async (notification: Notification) => { - return false; + const { homeserverUrl, accessToken, roomId } = notification; + if (!homeserverUrl || !accessToken || !roomId) { + return false; + } + const url = `${homeserverUrl}/_matrix/client/v3/rooms/${roomId}/send/m.room.message?access_token=${accessToken}`; + const body = { + msgtype: "m.text", + body: getTestMessage(), + }; + try { + this.logger?.debug?.("Sending Matrix test alert", { room: roomId }); + await got.post(url, { + json: body, + headers: { + "Content-Type": "application/json", + }, + responseType: "json", + }); + return true; + } catch (error) { + this.logger?.error?.("Matrix test alert failed", { error }); + return false; + } }; } diff --git a/server/src/service/infrastructure/notificationProviders/pagerduty.ts b/server/src/service/infrastructure/notificationProviders/pagerduty.ts index d0309550b..2d85cd4d6 100644 --- a/server/src/service/infrastructure/notificationProviders/pagerduty.ts +++ b/server/src/service/infrastructure/notificationProviders/pagerduty.ts @@ -1,9 +1,15 @@ import got from "got"; import type { Monitor, Notification, MonitorStatusResponse } from "@/types/index.js"; import { INotificationProvider } from "@/service/index.js"; -import { buildHardwareAlerts, buildHardwareWebhookBody, buildWebhookBody } from "@/service/infrastructure/notificationProviders/utils.js"; +import { + buildHardwareAlerts, + buildHardwareWebhookBody, + buildWebhookBody, + getTestMessage, +} from "@/service/infrastructure/notificationProviders/utils.js"; export class PagerDutyProvider implements INotificationProvider { + constructor(private logger: any) {} private getHardwareContent = (monitor: Monitor, monitorStatusResponse: MonitorStatusResponse) => { const { alertsToSend } = buildHardwareAlerts("HOST_PLACEHOLDER", monitor, monitorStatusResponse); const body = buildHardwareWebhookBody(alertsToSend, monitor); @@ -24,6 +30,7 @@ export class PagerDutyProvider implements INotificationProvider { } try { + this.logger?.debug?.("Sending PagerDuty alert", { routingKey: notification.address }); await got.post("https://events.pagerduty.com/v2/enqueue", { json: { routing_key: notification.address, @@ -40,11 +47,31 @@ export class PagerDutyProvider implements INotificationProvider { return true; } catch (error) { + this.logger?.error?.("PagerDuty alert failed", { error }); return false; } } async sendTestAlert(notification: Notification): Promise { - return false; + try { + this.logger?.debug?.("Sending PagerDuty test alert", { routingKey: notification.address }); + await got.post("https://events.pagerduty.com/v2/enqueue", { + json: { + routing_key: notification.address, + event_action: "trigger", + payload: { + summary: getTestMessage(), + severity: "info", + source: "checkmate", + timestamp: new Date().toISOString(), + }, + }, + responseType: "json", + }); + return true; + } catch (error) { + this.logger?.error?.("PagerDuty test alert failed", { error }); + return false; + } } } diff --git a/server/src/service/infrastructure/notificationProviders/slack.ts b/server/src/service/infrastructure/notificationProviders/slack.ts index c5745ce05..947048e4c 100644 --- a/server/src/service/infrastructure/notificationProviders/slack.ts +++ b/server/src/service/infrastructure/notificationProviders/slack.ts @@ -9,6 +9,7 @@ import { import got from "got"; export class SlackProvider implements INotificationProvider { + constructor(private logger: any) {} private getHardwareContent = (monitor: Monitor, monitorStatusResponse: MonitorStatusResponse) => { const { alertsToSend } = buildHardwareAlerts("HOST_PLACEHOLDER", monitor, monitorStatusResponse); const body = buildHardwareWebhookBody(alertsToSend, monitor); @@ -33,6 +34,7 @@ export class SlackProvider implements INotificationProvider { } try { + this.logger?.debug?.("Sending Slack alert", { address: notification.address }); await got.post(notification.address, { json: { text: body }, headers: { @@ -42,6 +44,7 @@ export class SlackProvider implements INotificationProvider { }); return true; } catch (error) { + this.logger?.error?.("Slack alert failed", { error }); return false; } } @@ -52,6 +55,7 @@ export class SlackProvider implements INotificationProvider { } try { + this.logger?.debug?.("Sending Slack test alert", { address: notification.address }); await got.post(notification.address, { json: { text: getTestMessage() }, headers: { @@ -61,6 +65,7 @@ export class SlackProvider implements INotificationProvider { }); return true; } catch (error) { + this.logger?.error?.("Slack test alert failed", { error }); return false; } } diff --git a/server/src/service/infrastructure/notificationProviders/webhook.ts b/server/src/service/infrastructure/notificationProviders/webhook.ts index 4d102c2b7..3976fb8e5 100644 --- a/server/src/service/infrastructure/notificationProviders/webhook.ts +++ b/server/src/service/infrastructure/notificationProviders/webhook.ts @@ -1,16 +1,22 @@ import type { Monitor, Alert, Notification, MonitorStatusResponse } from "@/types/index.js"; import { INotificationProvider } from "@/service/index.js"; -import { buildHardwareAlerts, buildHardwareWebhookBody, buildWebhookBody } from "@/service/infrastructure/notificationProviders/utils.js"; +import { + buildHardwareAlerts, + buildHardwareWebhookBody, + buildWebhookBody, + getTestMessage, +} from "@/service/infrastructure/notificationProviders/utils.js"; import got from "got"; export class WebhookProvider implements INotificationProvider { + constructor(private logger: any) {} private getHardwareContent = (monitor: Monitor, monitorStatusResponse: MonitorStatusResponse) => { const { alertsToSend } = buildHardwareAlerts("HOST_PLACEHOLDER", monitor, monitorStatusResponse); const body = buildHardwareWebhookBody(alertsToSend, monitor); return body; }; - private getContent = (monitor: Monitor, monitorStatusResponse: MonitorStatusResponse) => { + private getContent = (monitor: Monitor, monitorStatusResponse: MonitorStatusResponse): string => { const body = buildWebhookBody(monitor, monitorStatusResponse); return body; }; @@ -28,8 +34,9 @@ export class WebhookProvider implements INotificationProvider { } try { + this.logger?.debug?.("Sending webhook alert", { address: notification.address }); await got.post(notification.address, { - json: body, + json: { text: body }, headers: { "Content-Type": "application/json", }, @@ -37,11 +44,28 @@ export class WebhookProvider implements INotificationProvider { }); return true; } catch (error) { + this.logger?.error?.("Webhook alert failed", { error }); return false; } }; sendTestAlert = async (notification: Notification) => { - return false; + if (!notification.address) { + return false; + } + try { + this.logger?.debug?.("Sending webhook test alert", { address: notification.address }); + await got.post(notification.address, { + json: { text: getTestMessage() }, + headers: { + "Content-Type": "application/json", + }, + responseType: "json", + }); + return true; + } catch (error) { + this.logger?.error?.("Webhook test alert failed", { error }); + return false; + } }; } diff --git a/server/src/service/infrastructure/notificationsService.ts b/server/src/service/infrastructure/notificationsService.ts index 7ca52945e..ad27fe99a 100644 --- a/server/src/service/infrastructure/notificationsService.ts +++ b/server/src/service/infrastructure/notificationsService.ts @@ -140,6 +140,7 @@ export class NotificationsService implements INotificationsService { const notifications = await this.notificationsRepository.findNotificationsByIds(notificationIds); const tasks = notifications.map((notification) => this.sendTestNotification(notification)); const outcomes = await Promise.all(tasks); + console.log(outcomes); const succeeded = outcomes.filter(Boolean).length; const failed = outcomes.length - succeeded; if (failed > 0) {