Skip to content

Commit

Permalink
chore: link email templates
Browse files Browse the repository at this point in the history
  • Loading branch information
mxkaske committed Mar 4, 2025
1 parent 953dd2c commit f4b6fbd
Show file tree
Hide file tree
Showing 35 changed files with 505 additions and 357 deletions.
7 changes: 7 additions & 0 deletions apps/checker/handlers/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ func (h Handler) HTTPCheckerHandler(c *gin.Context) {
Region: h.Region,
Message: res.Error,
CronTimestamp: req.CronTimestamp,
Latency: res.Latency,
})
}
// Check if the status is degraded
Expand All @@ -212,6 +213,7 @@ func (h Handler) HTTPCheckerHandler(c *gin.Context) {
Region: h.Region,
StatusCode: res.Status,
CronTimestamp: req.CronTimestamp,
Latency: res.Latency,
})
}
}
Expand All @@ -225,6 +227,7 @@ func (h Handler) HTTPCheckerHandler(c *gin.Context) {
Region: h.Region,
StatusCode: res.Status,
CronTimestamp: req.CronTimestamp,
Latency: res.Latency,
})
}

Expand All @@ -246,6 +249,7 @@ func (h Handler) HTTPCheckerHandler(c *gin.Context) {
Region: h.Region,
StatusCode: res.Status,
CronTimestamp: req.CronTimestamp,
Latency: res.Latency,
})
}
}
Expand All @@ -259,6 +263,7 @@ func (h Handler) HTTPCheckerHandler(c *gin.Context) {
Region: h.Region,
StatusCode: res.Status,
CronTimestamp: req.CronTimestamp,
Latency: res.Latency,
})
}

Expand All @@ -269,6 +274,7 @@ func (h Handler) HTTPCheckerHandler(c *gin.Context) {
Region: h.Region,
StatusCode: res.Status,
CronTimestamp: req.CronTimestamp,
Latency: res.Latency,
})
}
}
Expand Down Expand Up @@ -304,6 +310,7 @@ func (h Handler) HTTPCheckerHandler(c *gin.Context) {
Message: err.Error(),
Region: h.Region,
CronTimestamp: req.CronTimestamp,
Latency: res.Latency,
})
}
}
Expand Down
5 changes: 5 additions & 0 deletions apps/checker/handlers/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ func (h Handler) TCPHandler(c *gin.Context) {
Status: "degraded",
Region: h.Region,
CronTimestamp: req.CronTimestamp,
Latency: latency,
})
}

Expand All @@ -142,6 +143,7 @@ func (h Handler) TCPHandler(c *gin.Context) {
Status: "active",
Region: h.Region,
CronTimestamp: req.CronTimestamp,
Latency: latency,
})
}

Expand All @@ -152,6 +154,7 @@ func (h Handler) TCPHandler(c *gin.Context) {
Status: "active",
Region: h.Region,
CronTimestamp: req.CronTimestamp,
Latency: latency,
})
}

Expand All @@ -161,6 +164,7 @@ func (h Handler) TCPHandler(c *gin.Context) {
Status: "degraded",
Region: h.Region,
CronTimestamp: req.CronTimestamp,
Latency: latency,
})
}

Expand Down Expand Up @@ -194,6 +198,7 @@ func (h Handler) TCPHandler(c *gin.Context) {
Message: err.Error(),
Region: h.Region,
CronTimestamp: req.CronTimestamp,
Latency: latency,
})
}
}
Expand Down
1 change: 1 addition & 0 deletions apps/checker/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type UpdateData struct {
Region string `json:"region"`
CronTimestamp int64 `json:"cronTimestamp"`
StatusCode int `json:"statusCode,omitempty"`
Latency int `json:"latency,omitempty"`
}

func UpdateStatus(ctx context.Context, updateData UpdateData) {
Expand Down
1 change: 1 addition & 0 deletions apps/server/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const env = createEnv({
QSTASH_TOKEN: z.string(),
NODE_ENV: z.string().default("development"),
SUPER_ADMIN_TOKEN: z.string(),
RESEND_API_KEY: z.string(),
},

/**
Expand Down
15 changes: 14 additions & 1 deletion apps/server/src/routes/checker/alerting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
} from "@openstatus/db/src/schema";

import { checkerAudit } from "@/utils/audit-log";
import type { MonitorFlyRegion } from "@openstatus/db/src/schema/constants";
import type {
MonitorFlyRegion,
Region,
} from "@openstatus/db/src/schema/constants";
import { Redis } from "@openstatus/upstash";
import { providerToFunction } from "./utils";

Expand All @@ -19,13 +22,17 @@ export const triggerNotifications = async ({
notifType,
cronTimestamp,
incidentId,
region,
latency,
}: {
monitorId: string;
statusCode?: number;
message?: string;
notifType: "alert" | "recovery" | "degraded";
cronTimestamp: number;
incidentId: string;
region?: Region;
latency?: number;
}) => {
console.log(`💌 triggerAlerting for ${monitorId}`);
const notifications = await db
Expand Down Expand Up @@ -64,6 +71,8 @@ export const triggerNotifications = async ({
message,
incidentId,
cronTimestamp,
region,
latency,
});
break;
case "recovery":
Expand All @@ -74,6 +83,8 @@ export const triggerNotifications = async ({
message,
incidentId,
cronTimestamp,
region,
latency,
});
break;
case "degraded":
Expand All @@ -83,6 +94,8 @@ export const triggerNotifications = async ({
statusCode,
message,
cronTimestamp,
region,
latency,
});
break;
}
Expand Down
18 changes: 16 additions & 2 deletions apps/server/src/routes/checker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,23 @@ checkerRoute.post("/updateStatus", async (c) => {
region: z.enum(flyRegions),
cronTimestamp: z.number(),
status: monitorStatusSchema,
latency: z.number().optional(),
});

const result = payloadSchema.safeParse(json);

if (!result.success) {
return c.text("Unprocessable Entity", 422);
}
const { monitorId, message, region, statusCode, cronTimestamp, status } =
result.data;
const {
monitorId,
message,
region,
statusCode,
cronTimestamp,
status,
latency,
} = result.data;

console.log(`📝 update monitor status ${JSON.stringify(result.data)}`);

Expand Down Expand Up @@ -103,6 +111,8 @@ checkerRoute.post("/updateStatus", async (c) => {
notifType: "degraded",
cronTimestamp,
incidentId: `${cronTimestamp}`,
region,
latency,
});
}
}
Expand Down Expand Up @@ -182,6 +192,8 @@ checkerRoute.post("/updateStatus", async (c) => {
incidentId: newIncident.length
? String(newIncident[0]?.id)
: `${cronTimestamp}`,
region,
latency,
});

if (newIncident.length > 0) {
Expand Down Expand Up @@ -287,6 +299,8 @@ checkerRoute.post("/updateStatus", async (c) => {
notifType: "recovery",
cronTimestamp,
incidentId: String(incident.id),
region,
latency,
});

const monitor = await db
Expand Down
5 changes: 5 additions & 0 deletions apps/server/src/routes/checker/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
sendAlert as sendPagerdutyAlert,
} from "@openstatus/notification-pagerduty";

import type { Region } from "@openstatus/db/src/schema/constants";
import {
sendAlert as sendOpsGenieAlert,
sendDegraded as sendOpsGenieDegraded,
Expand All @@ -43,13 +44,17 @@ type SendNotification = ({
message,
incidentId,
cronTimestamp,
latency,
region,
}: {
monitor: Monitor;
notification: Notification;
statusCode?: number;
message?: string;
incidentId?: string;
cronTimestamp: number;
latency?: number;
region?: Region;
}) => Promise<void>;

type Notif = {
Expand Down
39 changes: 24 additions & 15 deletions apps/server/src/routes/v1/statusReportUpdates/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import {
statusReport,
statusReportUpdate,
} from "@openstatus/db/src/schema";
import { sendEmailHtml } from "@openstatus/emails";

import { env } from "@/env";
import { OpenStatusApiError, openApiErrorResponses } from "@/libs/errors";
import { EmailClient } from "@openstatus/emails";
import type { statusReportUpdatesApi } from "./index";
import { StatusReportUpdateSchema } from "./schema";

const emailClient = new EmailClient({ apiKey: env.RESEND_API_KEY });

const createStatusUpdate = createRoute({
method: "post",
tags: ["status_report_update"],
Expand Down Expand Up @@ -89,21 +92,27 @@ export function registerPostStatusReportUpdate(
)
.all();

const pageInfo = await db
.select()
.from(page)
.where(eq(page.id, _statusReport.pageId))
.get();
if (pageInfo) {
const subscribersEmails = subscribers.map((subscriber) => ({
to: subscriber.email,
subject: `New status update for ${pageInfo.title}`,
html: `<p>Hi,</p><p>${pageInfo.title} just posted an update on their status page:</p><p>New Status : ${statusReportUpdate.status}</p><p>${statusReportUpdate.message}</p></p><p></p><p>Powered by OpenStatus</p><p></p><p></p><p></p><p></p><p></p>
`,
from: "Notification OpenStatus <[email protected]>",
}));
const _page = await db.query.page.findFirst({
where: eq(page.id, _statusReport.pageId),
with: {
monitorsToPages: {
with: {
monitor: true,
},
},
},
});

await sendEmailHtml(subscribersEmails);
if (_page && subscribers.length > 0) {
await emailClient.sendStatusReportUpdate({
to: subscribers.map((subscriber) => subscriber.email),
pageTitle: _page.title,
reportTitle: _statusReport.title,
status: _statusReport.status,
message: _statusReportUpdate.message,
date: _statusReportUpdate.date.toISOString(),
monitors: _page.monitorsToPages.map((i) => i.monitor.name),
});
}
}

Expand Down
42 changes: 24 additions & 18 deletions apps/server/src/routes/v1/statusReports/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ import {
statusReportUpdate,
} from "@openstatus/db/src/schema";

import { env } from "@/env";
import { OpenStatusApiError, openApiErrorResponses } from "@/libs/errors";
import { sendBatchEmailHtml } from "@openstatus/emails/src/send";
import { EmailClient } from "@openstatus/emails";
import type { statusReportsApi } from "./index";
import { StatusReportSchema } from "./schema";

const emailClient = new EmailClient({ apiKey: env.RESEND_API_KEY });

const postRoute = createRoute({
method: "post",
tags: ["status_report"],
Expand Down Expand Up @@ -142,24 +145,27 @@ export function registerPostStatusReport(api: typeof statusReportsApi) {
)
.all();

const pageInfo = await db
.select()
.from(page)
.where(eq(page.id, _newStatusReport.pageId))
.get();

if (pageInfo) {
const emails = subscribers.map((subscriber) => {
return {
to: subscriber.email,
subject: `New status update for ${pageInfo.title}`,
html: `<p>Hi,</p><p>${pageInfo.title} just posted an update on their status page:</p><p>New Status : ${statusReportUpdate.status}</p><p>${statusReportUpdate.message}</p></p><p></p><p>Powered by OpenStatus</p><p></p><p></p><p></p><p></p><p></p>
`,
from: "Notification OpenStatus <[email protected]>",
};
});
const pageInfo = await db.query.page.findFirst({
where: eq(page.id, _newStatusReport.pageId),
with: {
monitorsToPages: {
with: {
monitor: true,
},
},
},
});

await sendBatchEmailHtml(emails);
if (pageInfo && subscribers.length > 0) {
await emailClient.sendStatusReportUpdate({
to: subscribers.map((subscriber) => subscriber.email),
pageTitle: pageInfo.title,
reportTitle: _newStatusReport.title,
status: _newStatusReport.status,
message: _newStatusReportUpdate.message,
date: _newStatusReportUpdate.date.toISOString(),
monitors: pageInfo.monitorsToPages.map((i) => i.monitor.name),
});
}
}

Expand Down
Loading

0 comments on commit f4b6fbd

Please sign in to comment.