Openstatus www.openstatus.dev
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: notification messages (#998)

* chore: notification messages

* ci: apply automated fixes

* chore: add cron timestamp

* ci: apply automated fixes

* fix: webhooks

---------

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

authored by

Maximilian Kaske
autofix-ci[bot]
and committed by
GitHub
a49ddf89 ce393586

+368 -144
+5
apps/server/src/checker/alerting.ts
··· 17 17 statusCode, 18 18 message, 19 19 notifType, 20 + cronTimestamp, 20 21 incidentId, 21 22 }: { 22 23 monitorId: string; 23 24 statusCode?: number; 24 25 message?: string; 25 26 notifType: "alert" | "recovery" | "degraded"; 27 + cronTimestamp: number; 26 28 incidentId?: string; 27 29 }) => { 28 30 console.log(`💌 triggerAlerting for ${monitorId}`); ··· 61 63 statusCode, 62 64 message, 63 65 incidentId, 66 + cronTimestamp, 64 67 }); 65 68 break; 66 69 case "recovery": ··· 70 73 statusCode, 71 74 message, 72 75 incidentId, 76 + cronTimestamp, 73 77 }); 74 78 break; 75 79 case "degraded": ··· 78 82 notification: selectNotificationSchema.parse(notif.notification), 79 83 statusCode, 80 84 message, 85 + cronTimestamp, 81 86 }); 82 87 break; 83 88 }
+3
apps/server/src/checker/index.ts
··· 101 101 statusCode, 102 102 message, 103 103 notifType: "degraded", 104 + cronTimestamp, 104 105 }); 105 106 } 106 107 } ··· 176 177 statusCode, 177 178 message, 178 179 notifType: "alert", 180 + cronTimestamp, 179 181 }); 180 182 181 183 if (newIncident.length > 0) { ··· 265 267 statusCode, 266 268 message, 267 269 notifType: "recovery", 270 + cronTimestamp, 268 271 }); 269 272 270 273 const monitor = await db
+3
apps/server/src/checker/utils.ts
··· 36 36 statusCode, 37 37 message, 38 38 incidentId, 39 + cronTimestamp, 39 40 }: { 40 41 monitor: Monitor; 41 42 notification: Notification; 42 43 statusCode?: number; 43 44 message?: string; 44 45 incidentId?: string; 46 + cronTimestamp: number; 45 47 }) => Promise<void>; 46 48 47 49 type Notif = { ··· 49 51 sendRecovery: SendNotification; 50 52 sendDegraded: SendNotification; 51 53 }; 54 + 52 55 export const providerToFunction = { 53 56 email: { 54 57 sendAlert: sendEmailAlert,
+11 -7
packages/db/src/schema/notifications/validation.ts
··· 36 36 export const emailSchema = z.string().email(); 37 37 export const urlSchema = z.string().url(); 38 38 39 + export const emailDataSchema = z.object({ email: emailSchema }); 40 + export const phoneDataSchema = z.object({ sms: phoneSchema }); 41 + export const slackDataSchema = z.object({ slack: urlSchema }); 42 + export const discordDataSchema = z.object({ discord: urlSchema }); 43 + export const pagerdutyDataSchema = z.object({ pagerduty: z.string() }); 44 + 39 45 export const NotificationDataSchema = z.union([ 40 - z.object({ sms: phoneSchema }), 41 - z.object({ email: emailSchema }), 42 - z.object({ slack: urlSchema }), 43 - z.object({ discord: urlSchema }), 44 - z.object({ 45 - pagerduty: z.string(), 46 - }), 46 + emailDataSchema, 47 + phoneDataSchema, 48 + slackDataSchema, 49 + discordDataSchema, 50 + pagerdutyDataSchema, 47 51 ]);
+8 -8
packages/notifications/discord/src/index.ts
··· 20 20 notification, 21 21 statusCode, 22 22 message, 23 + cronTimestamp, 23 24 }: { 24 25 monitor: Monitor; 25 26 notification: Notification; 26 27 statusCode?: number; 27 28 message?: string; 28 29 incidentId?: string; 30 + cronTimestamp: number; 29 31 }) => { 30 32 const notificationData = JSON.parse(notification.data); 31 33 const { discord: webhookUrl } = notificationData; // webhook url ··· 33 35 34 36 try { 35 37 await postToWebhook( 36 - `Your monitor ${name} is down 🚨 37 - 38 - Your monitor with url ${monitor.url} is down with ${ 39 - statusCode ? `status code ${statusCode}` : `error message ${message}` 40 - }.`, 38 + `**🚨 Alert [${name}](<${monitor.url}>)**\nStatus Code: ${statusCode || "_empty_"}\nMessage: ${message || "_empty_"}\nCron Timestamp: ${cronTimestamp} (${new Date(cronTimestamp).toISOString()})\n> Check your [Dashboard](<https://www.openstatus.dev/app/>).\n`, 41 39 webhookUrl, 42 40 ); 43 41 } catch (err) { ··· 61 59 statusCode?: number; 62 60 message?: string; 63 61 incidentId?: string; 62 + cronTimestamp: number; 64 63 }) => { 65 64 const notificationData = JSON.parse(notification.data); 66 65 const { discord: webhookUrl } = notificationData; // webhook url ··· 68 67 69 68 try { 70 69 await postToWebhook( 71 - `Your monitor ${name}|${monitor.url} is up again 🎉`, 70 + `**✅ Recovered [${name}](<${monitor.url}>)**\n> Check your [Dashboard](<https://www.openstatus.dev/app/>).\n`, 72 71 webhookUrl, 73 72 ); 74 73 } catch (err) { ··· 92 91 statusCode?: number; 93 92 message?: string; 94 93 incidentId?: string; 94 + cronTimestamp: number; 95 95 }) => { 96 96 const notificationData = JSON.parse(notification.data); 97 97 const { discord: webhookUrl } = notificationData; // webhook url ··· 99 99 100 100 try { 101 101 await postToWebhook( 102 - `Your monitor ${name}|${monitor.url} is degraded ⚠️`, 102 + `**⚠️ Degraded [${name}](<${monitor.url}>)**\n> Check your [Dashboard](<https://www.openstatus.dev/app/>).\n`, 103 103 webhookUrl, 104 104 ); 105 105 } catch (err) { ··· 114 114 } 115 115 try { 116 116 await postToWebhook( 117 - "This is a test notification from OpenStatus. \nIf you see this, it means that your webhook is working! 🎉", 117 + "**🧪 Test [OpenStatus](<https://www.openstatus.dev/>)**\nIf you can read this, your Slack webhook is functioning correctly!\n> Check your [Dashboard](<https://www.openstatus.dev/app/>).\n", 118 118 webhookUrl, 119 119 ); 120 120 return true;
+65
packages/notifications/discord/src/mock.ts
··· 1 + import type { Monitor, Notification } from "@openstatus/db/src/schema"; 2 + import { 3 + sendAlert, 4 + sendDegraded, 5 + sendRecovery, 6 + sendTestDiscordMessage, 7 + } from "./index"; 8 + 9 + const monitor: Monitor = { 10 + id: 1, 11 + name: "OpenStatus Docs", 12 + url: "https://docs.openstatus.dev", 13 + periodicity: "10m", 14 + jobType: "website", 15 + active: true, 16 + public: true, 17 + createdAt: null, 18 + updatedAt: null, 19 + regions: ["ams", "fra"], 20 + description: "Monitor Description", 21 + headers: [], 22 + body: "", 23 + workspaceId: 1, 24 + timeout: 45000, 25 + degradedAfter: null, 26 + assertions: null, 27 + status: "active", 28 + method: "GET", 29 + deletedAt: null, 30 + }; 31 + 32 + const notification: Notification = { 33 + id: 1, 34 + name: "Discord", 35 + data: `{ "discord": "${process.env.DISCORD_WEBHOOK}" }`, 36 + createdAt: null, 37 + updatedAt: null, 38 + workspaceId: 1, 39 + provider: "discord", 40 + }; 41 + 42 + const cronTimestamp = Date.now(); 43 + 44 + if (process.env.NODE_ENV === "development") { 45 + await sendDegraded({ 46 + monitor, 47 + notification, 48 + cronTimestamp, 49 + }); 50 + 51 + await sendAlert({ 52 + monitor, 53 + notification, 54 + statusCode: 500, 55 + cronTimestamp, 56 + }); 57 + 58 + await sendRecovery({ 59 + monitor, 60 + notification, 61 + cronTimestamp, 62 + }); 63 + 64 + await sendTestDiscordMessage(process.env.DISCORD_WEBHOOK); 65 + }
+84 -86
packages/notifications/email/src/index.ts
··· 1 - import type { Monitor, Notification } from "@openstatus/db/src/schema"; 1 + import { 2 + type Monitor, 3 + type Notification, 4 + emailDataSchema, 5 + } from "@openstatus/db/src/schema"; 2 6 3 7 import { env } from "../env"; 4 - import { EmailConfigurationSchema } from "./schema/config"; 5 8 6 - export const sendAlert = async ({ 7 - monitor, 8 - notification, 9 - statusCode, 10 - message, 11 - // biome-ignore lint/correctness/noUnusedVariables: <explanation> 12 - incidentId, 9 + async function send({ 10 + subject, 11 + html, 12 + email, 13 + id, 14 + type, 13 15 }: { 14 - monitor: Monitor; 15 - notification: Notification; 16 - statusCode?: number; 17 - message?: string; 18 - incidentId?: string; 19 - }) => { 20 - // FIXME: 21 - const config = EmailConfigurationSchema.parse(JSON.parse(notification.data)); 22 - const { email } = config; 23 - 16 + subject: string; 17 + html: string; 18 + email: string; 19 + id: number; 20 + type: "recovered" | "alert" | "degraded"; 21 + }) { 24 22 const res = await fetch("https://api.resend.com/emails", { 25 23 method: "POST", 26 24 headers: { ··· 30 28 body: JSON.stringify({ 31 29 to: email, 32 30 from: "Notifications <ping@openstatus.dev>", 33 - 34 - subject: `Your monitor ${monitor.name} is down 🚨`, 35 - html: `<p>Hi,<br><br>Your monitor ${monitor.name} is down. </p><p>URL : ${ 36 - monitor.url 37 - }</p> ${ 38 - statusCode 39 - ? `<p>Status Code: ${statusCode}</p>` 40 - : `<p>Error message: ${message}</p>` 41 - }<p>OpenStatus 🏓 </p>`, 31 + subject, 32 + html, 42 33 }), 43 34 }); 44 35 ··· 48 39 // return NextResponse.json(data); 49 40 } 50 41 if (!res.ok) { 51 - console.log(`Error sending recovery email ${monitor.id}`); 42 + console.log(`Error sending ${type} email ${id}`); 52 43 } 53 - }; 44 + } 54 45 55 - export const sendRecovery = async ({ 46 + export const sendAlert = async ({ 56 47 monitor, 57 48 notification, 58 - // biome-ignore lint/correctness/noUnusedVariables: <explanation> 59 49 statusCode, 60 - // biome-ignore lint/correctness/noUnusedVariables: <explanation> 61 50 message, 62 - // biome-ignore lint/correctness/noUnusedVariables: <explanation> 63 - incidentId, 51 + cronTimestamp, 64 52 }: { 65 53 monitor: Monitor; 66 54 notification: Notification; 67 55 statusCode?: number; 68 56 message?: string; 69 57 incidentId?: string; 58 + cronTimestamp: number; 70 59 }) => { 71 - // FIXME: 72 - const config = EmailConfigurationSchema.parse(JSON.parse(notification.data)); 73 - const { email } = config; 60 + const config = emailDataSchema.safeParse(JSON.parse(notification.data)); 74 61 75 - const res = await fetch("https://api.resend.com/emails", { 76 - method: "POST", 77 - headers: { 78 - "Content-Type": "application/json", 79 - Authorization: `Bearer ${env.RESEND_API_KEY}`, 80 - }, 81 - body: JSON.stringify({ 82 - to: email, 83 - from: "Notifications <ping@openstatus.dev>", 62 + if (!config.success) return; 84 63 85 - subject: `Your monitor ${monitor.name} is back up 🎉`, 86 - html: `<p>Hi,<br><br>Your monitor ${monitor.name} is up again </p><p>URL : ${monitor.url}</p> <p>OpenStatus 🏓 </p>`, 87 - }), 64 + await send({ 65 + id: monitor.id, 66 + type: "alert", 67 + email: config.data.email, 68 + subject: `🚨 Alert ${monitor.name}`, 69 + html: ` 70 + <p>Hi,</p> 71 + <p>Your monitor <strong>${monitor.name}</strong> is down.</p> 72 + <p>URL: ${monitor.url}</p> 73 + ${ 74 + statusCode 75 + ? `<p>Status Code: ${statusCode}</p>` 76 + : `<p>Error message: ${message}</p>` 77 + } 78 + <p>Cron Timestamp: ${cronTimestamp} (${new Date(cronTimestamp).toISOString()})</p> 79 + <p>OpenStatus 🏓</p>`, 88 80 }); 81 + }; 89 82 90 - if (res.ok) { 91 - const data = await res.json(); 92 - console.log(data); 93 - // return NextResponse.json(data); 94 - } 95 - if (!res.ok) { 96 - console.log(`Error sending recovery email ${monitor.id}`); 97 - } 83 + export const sendRecovery = async ({ 84 + monitor, 85 + notification, 86 + }: { 87 + monitor: Monitor; 88 + notification: Notification; 89 + statusCode?: number; 90 + message?: string; 91 + incidentId?: string; 92 + cronTimestamp: number; 93 + }) => { 94 + const config = emailDataSchema.safeParse(JSON.parse(notification.data)); 95 + 96 + if (!config.success) return; 97 + 98 + send({ 99 + id: monitor.id, 100 + type: "recovered", 101 + email: config.data.email, 102 + subject: `✅ Recovered ${monitor.name}`, 103 + html: ` 104 + <p>Hi,</p> 105 + <p>Your monitor <strong>${monitor.name}</strong> is up again.</p> 106 + <p>URL: ${monitor.url}</p> 107 + <p>OpenStatus 🏓</p> 108 + `, 109 + }); 98 110 }; 99 111 100 112 export const sendDegraded = async ({ 101 113 monitor, 102 114 notification, 103 - // biome-ignore lint/correctness/noUnusedVariables: <explanation> 104 - statusCode, 105 - // biome-ignore lint/correctness/noUnusedVariables: <explanation> 106 - message, 107 115 }: { 108 116 monitor: Monitor; 109 117 notification: Notification; 110 118 statusCode?: number; 111 119 message?: string; 120 + cronTimestamp: number; 112 121 }) => { 113 - // FIXME: 114 - const config = EmailConfigurationSchema.parse(JSON.parse(notification.data)); 115 - const { email } = config; 122 + const config = emailDataSchema.safeParse(JSON.parse(notification.data)); 116 123 117 - const res = await fetch("https://api.resend.com/emails", { 118 - method: "POST", 119 - headers: { 120 - "Content-Type": "application/json", 121 - Authorization: `Bearer ${env.RESEND_API_KEY}`, 122 - }, 123 - body: JSON.stringify({ 124 - to: email, 125 - from: "Notifications <ping@openstatus.dev>", 124 + if (!config.success) return; 126 125 127 - subject: `Your monitor ${monitor.name} is degraded ⚠️`, 128 - html: `<p>Hi,<br><br>Your monitor ${monitor.name} is taking longer than expected to respond</p><p>URL : ${monitor.url}</p> <p>OpenStatus 🏓 </p>`, 129 - }), 126 + send({ 127 + id: monitor.id, 128 + type: "degraded", 129 + email: config.data.email, 130 + subject: `⚠️ Degraded ${monitor.name}`, 131 + html: ` 132 + <p>Hi,</p> 133 + <p>Your monitor <strong>${monitor.name}</strong> is taking longer than expected to respond</p> 134 + <p>URL: ${monitor.url}</p> 135 + <p>OpenStatus 🏓</p> 136 + `, 130 137 }); 131 - 132 - if (res.ok) { 133 - const data = await res.json(); 134 - console.log(data); 135 - // return NextResponse.json(data); 136 - } 137 - if (!res.ok) { 138 - console.log(`Error sending recovery email ${monitor.id}`); 139 - } 140 138 };
+58
packages/notifications/email/src/mock.ts
··· 1 + import type { Monitor, Notification } from "@openstatus/db/src/schema"; 2 + import { sendAlert, sendDegraded, sendRecovery } from "./index"; 3 + 4 + const monitor: Monitor = { 5 + id: 1, 6 + name: "OpenStatus Docs", 7 + url: "https://docs.openstatus.dev", 8 + periodicity: "10m", 9 + jobType: "website", 10 + active: true, 11 + public: true, 12 + createdAt: null, 13 + updatedAt: null, 14 + regions: ["ams", "fra"], 15 + description: "Monitor Description", 16 + headers: [], 17 + body: "", 18 + workspaceId: 1, 19 + timeout: 45000, 20 + degradedAfter: null, 21 + assertions: null, 22 + status: "active", 23 + method: "GET", 24 + deletedAt: null, 25 + }; 26 + 27 + const notification: Notification = { 28 + id: 1, 29 + name: "Email", 30 + data: '{ "email": "max@openstatus.dev" }', 31 + createdAt: null, 32 + updatedAt: null, 33 + workspaceId: 1, 34 + provider: "email", 35 + }; 36 + 37 + const cronTimestamp = Date.now(); 38 + 39 + if (process.env.NODE_ENV === "development") { 40 + sendDegraded({ 41 + monitor, 42 + notification, 43 + cronTimestamp, 44 + }); 45 + 46 + sendAlert({ 47 + monitor, 48 + notification, 49 + statusCode: 500, 50 + cronTimestamp, 51 + }); 52 + 53 + sendRecovery({ 54 + monitor, 55 + notification, 56 + cronTimestamp, 57 + }); 58 + }
-5
packages/notifications/email/src/schema/config.ts
··· 1 - import { z } from "zod"; 2 - 3 - export const EmailConfigurationSchema = z.object({ 4 - email: z.string().email(), 5 - });
+5 -1
packages/notifications/pagerduty/src/index.ts
··· 12 12 statusCode, 13 13 message, 14 14 incidentId, 15 + cronTimestamp, 15 16 }: { 16 17 monitor: Monitor; 17 18 notification: Notification; 18 19 statusCode?: number; 19 20 message?: string; 20 21 incidentId?: string; 22 + cronTimestamp: number; 21 23 }) => { 22 24 const notificationData = PagerDutySchema.parse(JSON.parse(notification.data)); 23 25 const { name } = monitor; ··· 30 32 summary: `${name} is down`, 31 33 source: "Open Status", 32 34 severity: "error", 33 - timestamp: new Date().toISOString(), 35 + timestamp: new Date(cronTimestamp).toISOString(), 34 36 custom_details: { 35 37 statusCode, 36 38 message, ··· 65 67 statusCode?: number; 66 68 message?: string; 67 69 incidentId?: string; 70 + cronTimestamp: number; 68 71 }) => { 69 72 const notificationData = PagerDutySchema.parse(JSON.parse(notification.data)); 70 73 const { name } = monitor; ··· 115 118 statusCode?: number; 116 119 message?: string; 117 120 incidentId?: string; 121 + cronTimestamp: number; 118 122 }) => { 119 123 const notificationData = PagerDutySchema.parse(JSON.parse(notification.data)); 120 124
+58 -37
packages/notifications/slack/src/index.ts
··· 20 20 message, 21 21 // biome-ignore lint/correctness/noUnusedVariables: <explanation> 22 22 incidentId, 23 + cronTimestamp, 23 24 }: { 24 25 monitor: Monitor; 25 26 notification: Notification; 26 27 statusCode?: number; 27 28 message?: string; 28 29 incidentId?: string; 30 + cronTimestamp: number; 29 31 }) => { 30 32 const notificationData = JSON.parse(notification.data); 31 33 const { slack: webhookUrl } = notificationData; // webhook url ··· 36 38 { 37 39 blocks: [ 38 40 { 41 + type: "divider", 42 + }, 43 + { 39 44 type: "section", 40 45 text: { 41 46 type: "mrkdwn", 42 - text: `Your monitor <${monitor.url}/|${name}> with ${ 43 - statusCode 44 - ? `status code ${statusCode}` 45 - : `error message ${message}` 46 - } 🚨 \n\n Powered by <https://www.openstatus.dev/|OpenStatus>.`, 47 + text: ` 48 + *🚨 Alert <${monitor.url}/|${name}>*\n\n 49 + Status Code: ${statusCode || "_empty_"}\n 50 + Message: ${message || "_empty_"}\n 51 + Cron Timestamp: ${cronTimestamp} (${new Date(cronTimestamp).toISOString()}) 52 + `, 47 53 }, 48 - accessory: { 49 - type: "button", 50 - text: { 51 - type: "plain_text", 52 - text: "Open Monitor", 53 - emoji: true, 54 + }, 55 + { 56 + type: "context", 57 + elements: [ 58 + { 59 + type: "mrkdwn", 60 + text: "Check your <https://www.openstatus.dev/app|Dashboard>.", 54 61 }, 55 - value: `monitor_url_${monitor.url}`, 56 - url: monitor.url, 57 - }, 62 + ], 58 63 }, 59 64 ], 60 65 }, ··· 81 86 statusCode?: number; 82 87 message?: string; 83 88 incidentId?: string; 89 + cronTimestamp: number; 84 90 }) => { 85 91 const notificationData = JSON.parse(notification.data); 86 92 const { slack: webhookUrl } = notificationData; // webhook url ··· 91 97 { 92 98 blocks: [ 93 99 { 100 + type: "divider", 101 + }, 102 + { 94 103 type: "section", 95 104 text: { 96 105 type: "mrkdwn", 97 - text: `Your monitor <${monitor.url}/|${name}> is up again 98 - 🚀 \n\n Powered by <https://www.openstatus.dev/|OpenStatus>.`, 106 + text: `*✅ Recovered <${monitor.url}/|${name}>*`, 99 107 }, 100 - accessory: { 101 - type: "button", 102 - text: { 103 - type: "plain_text", 104 - text: "Open Monitor", 105 - emoji: true, 108 + }, 109 + { 110 + type: "context", 111 + elements: [ 112 + { 113 + type: "mrkdwn", 114 + text: "Check your <https://www.openstatus.dev/app|Dashboard>.", 106 115 }, 107 - value: `monitor_url_${monitor.url}`, 108 - url: monitor.url, 109 - }, 116 + ], 110 117 }, 111 118 ], 112 119 }, ··· 130 137 notification: Notification; 131 138 statusCode?: number; 132 139 message?: string; 140 + cronTimestamp: number; 133 141 }) => { 134 142 const notificationData = JSON.parse(notification.data); 135 143 const { slack: webhookUrl } = notificationData; // webhook url ··· 140 148 { 141 149 blocks: [ 142 150 { 151 + type: "divider", 152 + }, 153 + { 143 154 type: "section", 144 155 text: { 145 156 type: "mrkdwn", 146 - text: `Your monitor <${monitor.url}/|${name}> is degraded 147 - ⚠️ \n\n Powered by <https://www.openstatus.dev/|OpenStatus>.`, 157 + text: `*⚠️ Degraded <${monitor.url}/|${name}>*`, 148 158 }, 149 - accessory: { 150 - type: "button", 151 - text: { 152 - type: "plain_text", 153 - text: "Open Monitor", 154 - emoji: true, 159 + }, 160 + { 161 + type: "context", 162 + elements: [ 163 + { 164 + type: "mrkdwn", 165 + text: "Check your <https://www.openstatus.dev/app|Dashboard>.", 155 166 }, 156 - value: `monitor_url_${monitor.url}`, 157 - url: monitor.url, 158 - }, 167 + ], 159 168 }, 160 169 ], 161 170 }, ··· 172 181 await postToWebhook( 173 182 { 174 183 blocks: [ 184 + { 185 + type: "divider", 186 + }, 175 187 { 176 188 type: "section", 177 189 text: { 178 190 type: "mrkdwn", 179 - text: "This is a test notification from <https://www.openstatus.dev/|OpenStatus>.\n If you can read this, your Slack webhook is functioning correctly!", 191 + text: "*🧪 Test <https://www.openstatus.dev/|OpenStatus>*\n\nIf you can read this, your Slack webhook is functioning correctly!", 180 192 }, 193 + }, 194 + { 195 + type: "context", 196 + elements: [ 197 + { 198 + type: "mrkdwn", 199 + text: "Check your <https://www.openstatus.dev/app|Dashboard>.", 200 + }, 201 + ], 181 202 }, 182 203 ], 183 204 },
+65
packages/notifications/slack/src/mock.ts
··· 1 + import type { Monitor, Notification } from "@openstatus/db/src/schema"; 2 + import { 3 + sendAlert, 4 + sendDegraded, 5 + sendRecovery, 6 + sendTestSlackMessage, 7 + } from "./index"; 8 + 9 + const monitor: Monitor = { 10 + id: 1, 11 + name: "OpenStatus Docs", 12 + url: "https://docs.openstatus.dev", 13 + periodicity: "10m", 14 + jobType: "website", 15 + active: true, 16 + public: true, 17 + createdAt: null, 18 + updatedAt: null, 19 + regions: ["ams", "fra"], 20 + description: "Monitor Description", 21 + headers: [], 22 + body: "", 23 + workspaceId: 1, 24 + timeout: 45000, 25 + degradedAfter: null, 26 + assertions: null, 27 + status: "active", 28 + method: "GET", 29 + deletedAt: null, 30 + }; 31 + 32 + const notification: Notification = { 33 + id: 1, 34 + name: "Slack", 35 + data: `{ "slack": "${process.env.SLACK_WEBHOOK}" }`, 36 + createdAt: null, 37 + updatedAt: null, 38 + workspaceId: 1, 39 + provider: "slack", 40 + }; 41 + 42 + const cronTimestamp = Date.now(); 43 + 44 + if (process.env.NODE_ENV === "development") { 45 + await sendDegraded({ 46 + monitor, 47 + notification, 48 + cronTimestamp, 49 + }); 50 + 51 + await sendAlert({ 52 + monitor, 53 + notification, 54 + statusCode: 500, 55 + cronTimestamp, 56 + }); 57 + 58 + await sendRecovery({ 59 + monitor, 60 + notification, 61 + cronTimestamp, 62 + }); 63 + 64 + await sendTestSlackMessage(process.env.SLACK_WEBHOOK); 65 + }
+3
packages/notifications/twillio-sms/src/index.ts
··· 16 16 statusCode?: number; 17 17 message?: string; 18 18 incidentId?: string; 19 + cronTimestamp: number; 19 20 }) => { 20 21 const notificationData = SmsConfigurationSchema.parse( 21 22 JSON.parse(notification.data), ··· 66 67 statusCode?: number; 67 68 message?: string; 68 69 incidentId?: string; 70 + cronTimestamp: number; 69 71 }) => { 70 72 const notificationData = SmsConfigurationSchema.parse( 71 73 JSON.parse(notification.data), ··· 109 111 statusCode?: number; 110 112 message?: string; 111 113 incidentId?: string; 114 + cronTimestamp: number; 112 115 }) => { 113 116 const notificationData = SmsConfigurationSchema.parse( 114 117 JSON.parse(notification.data),