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.
7.5 kB · 276 lines
TypeScript
at incident-api
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277import { COLOR_DECIMALS, type FormattedMessageData,} from "@openstatus/notification-base";
/** * Discord Embed structure for webhook messages * Reference: https://birdie0.github.io/discord-webhooks-guide/structure/embeds.html */
interface DiscordEmbedField { name: string; value: string; inline?: boolean;}
interface DiscordEmbedFooter { text: string;}
export interface DiscordEmbed { title: string; description: string; color: number; fields: DiscordEmbedField[]; timestamp: string; footer: DiscordEmbedFooter; url: string;}
/** * Builds Discord embed for alert notifications * * Layout: * - Title: "{monitor.name} is failing" * - Description: "METHOD URL" in code format (e.g., `GET https://api.example.com`) * - Color: Red (#ED4245 / 15548997) * - Fields: Status Code, Regions, Latency, Cron Timestamp (inline), Error Message in code block (full width) * - Timestamp: ISO 8601 format * - Footer: "openstatus" * - URL: Dashboard link * * @param data - Formatted message data from buildCommonMessageData * @returns DiscordEmbed object ready for webhook payload * * @example * const embed = buildAlertEmbed({ * monitorName: "API Health", * monitorUrl: "https://api.example.com", * statusCodeFormatted: "503 Service Unavailable", * errorMessage: "Connection timeout", * timestampFormatted: "Jan 22, 2026 at 14:30 UTC", * regionDisplay: "iad (Virginia)", * latencyDisplay: "1,234 ms", * dashboardUrl: "https://app.openstatus.dev/monitors/123" * }); */export function buildAlertEmbed(data: FormattedMessageData): DiscordEmbed { // Format description as "METHOD URL" or just "URL" for non-HTTP const description = data.monitorMethod && data.monitorJobType === "http" ? `${data.monitorMethod} ${data.monitorUrl}` : data.monitorUrl;
return { title: buildTitle(data.monitorName, " is failing"), description: `\`${description}\``, color: COLOR_DECIMALS.red, fields: [ { name: "Status Code", value: data.statusCodeFormatted, inline: true, }, { name: "Regions", value: data.regionsDisplay, inline: true, }, { name: "Latency", value: data.latencyDisplay, inline: true, }, { name: "Cron Timestamp", value: data.timestampFormatted, inline: true, }, { name: "Error Message", value: `\`\`\`${data.errorMessage}\`\`\``, inline: false, }, ], timestamp: new Date().toISOString(), footer: { text: "openstatus", }, url: data.dashboardUrl, };}
/** * Builds Discord embed for recovery notifications * * Layout: * - Title: "{monitor.name} is recovered" * - Description: "METHOD URL" in code format (e.g., `GET https://api.example.com`) * - Color: Green (#57F287 / 5763719) * - Fields: Optional Downtime field (if incidentDuration exists), Status Code, Regions, Latency, Cron Timestamp (inline) * - Timestamp: ISO 8601 format * - Footer: "openstatus" * - URL: Dashboard link * * @param data - Formatted message data from buildCommonMessageData * @returns DiscordEmbed object ready for webhook payload * * @example * const embed = buildRecoveryEmbed({ * monitorName: "API Health", * monitorUrl: "https://api.example.com", * statusCodeFormatted: "200 OK", * errorMessage: "", * timestampFormatted: "Jan 22, 2026 at 14:35 UTC", * regionDisplay: "iad (Virginia)", * latencyDisplay: "156 ms", * dashboardUrl: "https://app.openstatus.dev/monitors/123", * incidentDuration: "5m 30s" * }); */export function buildRecoveryEmbed(data: FormattedMessageData): DiscordEmbed { const fields: DiscordEmbedField[] = [];
// Format description as "METHOD URL" or just "URL" for non-HTTP const description = data.monitorMethod && data.monitorJobType === "http" ? `${data.monitorMethod} ${data.monitorUrl}` : data.monitorUrl;
// Add downtime field if incident duration is available if (data.incidentDuration) { fields.push({ name: "⏱️ Downtime", value: data.incidentDuration, inline: false, }); }
// Add status fields (inline for 3-column layout) fields.push( { name: "Status Code", value: data.statusCodeFormatted, inline: true, }, { name: "Regions", value: data.regionsDisplay, inline: true, }, { name: "Latency", value: data.latencyDisplay, inline: true, }, { name: "Cron Timestamp", value: data.timestampFormatted, inline: true, }, );
return { title: buildTitle(data.monitorName, " is recovered"), description: `\`${description}\``, color: COLOR_DECIMALS.green, fields, timestamp: new Date().toISOString(), footer: { text: "openstatus", }, url: data.dashboardUrl, };}
/** * Builds Discord embed for degraded notifications * * Layout: * - Title: "{monitor.name} is degraded" * - Description: "METHOD URL" in code format (e.g., `GET https://api.example.com`) * - Color: Yellow (#FEE75C / 16705372) * - Fields: Optional Previous Incident Duration field (if incidentDuration exists), Status Code, Regions, Latency, Cron Timestamp (inline) * - Timestamp: ISO 8601 format * - Footer: "openstatus" * - URL: Dashboard link * * @param data - Formatted message data from buildCommonMessageData * @returns DiscordEmbed object ready for webhook payload * * @example * const embed = buildDegradedEmbed({ * monitorName: "API Health", * monitorUrl: "https://api.example.com", * statusCodeFormatted: "504 Gateway Timeout", * errorMessage: "Slow response", * timestampFormatted: "Jan 22, 2026 at 14:40 UTC", * regionDisplay: "iad (Virginia)", * latencyDisplay: "5,234 ms", * dashboardUrl: "https://app.openstatus.dev/monitors/123", * incidentDuration: "2h 15m" * }); */export function buildDegradedEmbed(data: FormattedMessageData): DiscordEmbed { const fields: DiscordEmbedField[] = [];
// Format description as "METHOD URL" or just "URL" for non-HTTP const description = data.monitorMethod && data.monitorJobType === "http" ? `${data.monitorMethod} ${data.monitorUrl}` : data.monitorUrl;
// Add previous incident duration field if available if (data.incidentDuration) { fields.push({ name: "⏱️ Previous Incident Duration", value: data.incidentDuration, inline: false, }); }
// Add status fields (inline for 3-column layout) fields.push( { name: "Status Code", value: data.statusCodeFormatted, inline: true, }, { name: "Regions", value: data.regionsDisplay, inline: true, }, { name: "Latency", value: data.latencyDisplay, inline: true, }, { name: "Cron Timestamp", value: data.timestampFormatted, inline: true, }, );
return { title: buildTitle(data.monitorName, " is degraded"), description: `\`${description}\``, color: COLOR_DECIMALS.yellow, fields, timestamp: new Date().toISOString(), footer: { text: "openstatus", }, url: data.dashboardUrl, };}
function buildTitle(name: string, suffix: string): string { const shortenedName = name .slice(0, 256 - suffix.length) // Keep surrogate pairs complete at the title limit. .replace(/[\uD800-\uDBFF]$/, ""); return `${shortenedName}${suffix}`;}