Openstatus www.openstatus.dev

Fix pager duty (#1556)

* Fix pager duty

* ci: apply automated fixes

* fix test import

* fix test

* fmt

* lint

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

authored by

Thibault Le Ouay
autofix-ci[bot]
and committed by
GitHub
9b47fa62 8826e499

+165 -20
+3
packages/notifications/pagerduty/package.json
··· 1 1 { 2 2 "name": "@openstatus/notification-pagerduty", 3 3 "version": "0.0.0", 4 + "scripts": { 5 + "test": "bun test" 6 + }, 4 7 "main": "src/index.ts", 5 8 "dependencies": { 6 9 "@openstatus/db": "workspace:*",
+131
packages/notifications/pagerduty/src/index.test.ts
··· 1 + import { 2 + afterEach, 3 + beforeEach, 4 + describe, 5 + expect, 6 + jest, 7 + spyOn, 8 + test, 9 + } from "bun:test"; 10 + import { selectNotificationSchema } from "@openstatus/db/src/schema"; 11 + import { sendAlert, sendDegraded, sendRecovery } from "./index"; 12 + 13 + describe("PagerDuty Notifications", () => { 14 + // biome-ignore lint/suspicious/noExplicitAny: <explanation> 15 + let fetchMock: any = undefined; 16 + 17 + beforeEach(() => { 18 + fetchMock = spyOn(global, "fetch").mockImplementation(() => 19 + Promise.resolve(new Response(null, { status: 200 })), 20 + ); 21 + }); 22 + 23 + afterEach(() => { 24 + jest.resetAllMocks(); 25 + }); 26 + 27 + test("Send degraded", async () => { 28 + const monitor = { 29 + id: "monitor-1", 30 + name: "API Health Check", 31 + url: "https://api.example.com/health", 32 + jobType: "http" as const, 33 + periodicity: "5m" as const, 34 + status: "active" as const, // or "down", "degraded" 35 + createdAt: new Date(), 36 + updatedAt: new Date(), 37 + region: "us-east-1", 38 + }; 39 + 40 + const a = { 41 + id: 1, 42 + name: "PagerDuty Notification", 43 + provider: "pagerduty", 44 + workspaceId: 1, 45 + createdAt: new Date(), 46 + updatedAt: new Date(), 47 + data: '{"pagerduty":"{\\"integration_keys\\":[{\\"integration_key\\":\\"my_key\\",\\"name\\":\\"Default Service\\",\\"id\\":\\"ABCD\\",\\"type\\":\\"service\\"}],\\"account\\":{\\"subdomain\\":\\"test\\",\\"name\\":\\"test\\"}}"}', 48 + }; 49 + 50 + const n = selectNotificationSchema.parse(a); 51 + await sendDegraded({ 52 + // @ts-expect-error 53 + monitor, 54 + notification: n, 55 + statusCode: 500, 56 + message: "Something went wrong", 57 + cronTimestamp: Date.now(), 58 + }); 59 + expect(fetchMock).toHaveBeenCalled(); 60 + }); 61 + 62 + test("Send Recovered", async () => { 63 + const monitor = { 64 + id: "monitor-1", 65 + name: "API Health Check", 66 + url: "https://api.example.com/health", 67 + jobType: "http" as const, 68 + periodicity: "5m" as const, 69 + status: "active" as const, // or "down", "degraded" 70 + createdAt: new Date(), 71 + updatedAt: new Date(), 72 + region: "us-east-1", 73 + }; 74 + 75 + const a = { 76 + id: 1, 77 + name: "PagerDuty Notification", 78 + provider: "pagerduty", 79 + workspaceId: 1, 80 + createdAt: new Date(), 81 + updatedAt: new Date(), 82 + data: '{"pagerduty":"{\\"integration_keys\\":[{\\"integration_key\\":\\"my_key\\",\\"name\\":\\"Default Service\\",\\"id\\":\\"ABCD\\",\\"type\\":\\"service\\"}],\\"account\\":{\\"subdomain\\":\\"test\\",\\"name\\":\\"test\\"}}"}', 83 + }; 84 + 85 + const n = selectNotificationSchema.parse(a); 86 + await sendRecovery({ 87 + // @ts-expect-error 88 + monitor, 89 + notification: n, 90 + statusCode: 500, 91 + message: "Something went wrong", 92 + cronTimestamp: Date.now(), 93 + }); 94 + expect(fetchMock).toHaveBeenCalled(); 95 + }); 96 + 97 + test("Send Alert", async () => { 98 + const monitor = { 99 + id: "monitor-1", 100 + name: "API Health Check", 101 + url: "https://api.example.com/health", 102 + jobType: "http" as const, 103 + periodicity: "5m" as const, 104 + status: "active" as const, // or "down", "degraded" 105 + createdAt: new Date(), 106 + updatedAt: new Date(), 107 + region: "us-east-1", 108 + }; 109 + const a = { 110 + id: 1, 111 + name: "PagerDuty Notification", 112 + provider: "pagerduty", 113 + workspaceId: 1, 114 + createdAt: new Date(), 115 + updatedAt: new Date(), 116 + data: '{"pagerduty":"{\\"integration_keys\\":[{\\"integration_key\\":\\"my_key\\",\\"name\\":\\"Default Service\\",\\"id\\":\\"ABCD\\",\\"type\\":\\"service\\"}],\\"account\\":{\\"subdomain\\":\\"test\\",\\"name\\":\\"test\\"}}"}', 117 + }; 118 + 119 + const n = selectNotificationSchema.parse(a); 120 + 121 + await sendAlert({ 122 + // @ts-expect-error 123 + monitor, 124 + notification: n, 125 + statusCode: 500, 126 + message: "Something went wrong", 127 + cronTimestamp: Date.now(), 128 + }); 129 + expect(fetchMock).toHaveBeenCalled(); 130 + }); 131 + });
+31 -20
packages/notifications/pagerduty/src/index.ts
··· 1 - import type { Monitor, Notification } from "@openstatus/db/src/schema"; 1 + import { 2 + type Monitor, 3 + type Notification, 4 + pagerdutyDataSchema, 5 + } from "@openstatus/db/src/schema"; 2 6 3 7 import type { Region } from "@openstatus/db/src/schema/constants"; 4 8 import { ··· 24 28 latency?: number; 25 29 region?: Region; 26 30 }) => { 27 - const notificationData = PagerDutySchema.parse(JSON.parse(notification.data)); 31 + const data = pagerdutyDataSchema.parse(JSON.parse(notification.data)); 32 + 33 + const notificationData = PagerDutySchema.parse(JSON.parse(data.pagerduty)); 34 + 28 35 const { name } = monitor; 29 36 30 37 try { ··· 72 79 latency?: number; 73 80 region?: Region; 74 81 }) => { 75 - const notificationData = PagerDutySchema.parse(JSON.parse(notification.data)); 82 + const data = pagerdutyDataSchema.parse(JSON.parse(notification.data)); 83 + 84 + const notificationData = PagerDutySchema.parse(JSON.parse(data.pagerduty)); 76 85 const { name } = monitor; 77 86 78 - const event = triggerEventPayloadSchema.parse({ 79 - routing_key: notificationData.integration_keys[0].integration_key, 80 - dedup_key: `${monitor.id}}`, 81 - event_action: "trigger", 82 - payload: { 83 - summary: `${name} is degraded`, 84 - source: "Open Status", 85 - severity: "warning", 86 - timestamp: new Date().toISOString(), 87 - custom_details: { 88 - statusCode, 89 - message, 90 - }, 91 - }, 92 - }); 93 - 94 87 try { 95 88 for await (const integrationKey of notificationData.integration_keys) { 96 89 // biome-ignore lint/correctness/noUnusedVariables: <explanation> 97 90 const { integration_key, type } = integrationKey; 91 + 92 + const event = triggerEventPayloadSchema.parse({ 93 + routing_key: integration_key, 94 + dedup_key: `${monitor.id}}`, 95 + event_action: "trigger", 96 + payload: { 97 + summary: `${name} is degraded`, 98 + source: "Open Status", 99 + severity: "warning", 100 + timestamp: new Date().toISOString(), 101 + custom_details: { 102 + statusCode, 103 + message, 104 + }, 105 + }, 106 + }); 98 107 99 108 await fetch("https://events.pagerduty.com/v2/enqueue", { 100 109 method: "POST", ··· 125 134 latency?: number; 126 135 region?: Region; 127 136 }) => { 128 - const notificationData = PagerDutySchema.parse(JSON.parse(notification.data)); 137 + const data = pagerdutyDataSchema.parse(JSON.parse(notification.data)); 138 + 139 + const notificationData = PagerDutySchema.parse(JSON.parse(data.pagerduty)); 129 140 130 141 try { 131 142 for await (const integrationKey of notificationData.integration_keys) {