Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
4.6 kB ยท 214 lines
TypeScript
at incident-api
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215import { slackDataSchema } from "@openstatus/db/src/schema";import { COLORS, type NotificationContext, buildCommonMessageData,} from "@openstatus/notification-base";import { safeFetch } from "@openstatus/utils";
import { buildAlertBlocks, buildDegradedBlocks, buildRecoveryBlocks,} from "./blocks";
const postToWebhook = async ( body: Record<string, unknown>, webhookUrl: string,) => { if (!webhookUrl || webhookUrl.trim() === "") { throw new Error("Slack webhook URL is required"); }
const res = await safeFetch(webhookUrl, { method: "POST", body: JSON.stringify(body), }); if (!res.ok) { throw new Error(`Failed to send Slack notification: ${res.statusText}`); }};
export const sendAlert = async ({ monitor, notification, statusCode, message, cronTimestamp, latency, regions,}: NotificationContext) => { const notificationData = slackDataSchema.parse(JSON.parse(notification.data)); const { slack: webhookUrl } = notificationData;
const context = { monitor, notification, statusCode, message, cronTimestamp, latency, regions, };
const data = buildCommonMessageData(context); const blocks = buildAlertBlocks(data);
await postToWebhook( { attachments: [ { color: COLORS.red, blocks, }, ], }, webhookUrl, );};
export const sendRecovery = async ({ monitor, notification, statusCode, message, incident, cronTimestamp, regions, latency,}: NotificationContext) => { const notificationData = slackDataSchema.parse(JSON.parse(notification.data)); const { slack: webhookUrl } = notificationData;
const context = { monitor, notification, statusCode, message, cronTimestamp, latency, regions, };
const data = buildCommonMessageData(context, { incident }); const blocks = buildRecoveryBlocks(data);
await postToWebhook( { attachments: [ { color: COLORS.green, blocks, }, ], }, webhookUrl, );};
export const sendDegraded = async ({ monitor, notification, statusCode, message, incident, cronTimestamp, regions, latency,}: NotificationContext) => { const notificationData = slackDataSchema.parse(JSON.parse(notification.data)); const { slack: webhookUrl } = notificationData;
const context = { monitor, notification, statusCode, message, cronTimestamp, latency, regions, };
const data = buildCommonMessageData(context, { incident }); const blocks = buildDegradedBlocks(data);
await postToWebhook( { attachments: [ { color: COLORS.yellow, blocks, }, ], }, webhookUrl, );};
export const sendTestSlackMessage = async (webhookUrl: string) => { await postToWebhook( { attachments: [ { color: COLORS.green, blocks: [ { type: "header", text: { type: "plain_text", text: "Test Notification", emoji: false, }, }, { type: "section", text: { type: "mrkdwn", text: "`๐งช Your Slack webhook is configured correctly!`", }, }, { type: "divider", }, { type: "section", fields: [ { type: "mrkdwn", text: "*Status*\nWebhook Connected", }, { type: "mrkdwn", text: "*Type*\nTest Notification", }, ], }, { type: "section", text: { type: "mrkdwn", text: "*Next Steps*\nYou will receive notifications here when your monitors trigger fail, recover, or degrades.", }, }, { type: "actions", elements: [ { type: "button", text: { type: "plain_text", text: "View Dashboard", emoji: true, }, url: "https://app.openstatus.dev", action_id: "view_dashboard", }, ], }, ], }, ], }, webhookUrl, );};