Openstatus www.openstatus.dev
at 4c0f4c00a38753a5d0dfd7e7b7b7706dec6f1503 120 lines 3.1 kB view raw
1import { getSentry } from "@hono/sentry"; 2import { monitorPeriodicitySchema } from "@openstatus/db/src/schema/constants"; 3import { Hono } from "hono"; 4import { env } from "../env"; 5import { sendCheckerTasks } from "./checker"; 6import { sendFollowUpEmails } from "./emails"; 7import { 8 LaunchMonitorWorkflow, 9 Step3Days, 10 Step14Days, 11 StepPaused, 12 workflowStepSchema, 13} from "./monitor"; 14 15const app = new Hono({ strict: false }); 16 17app.use("*", async (c, next) => { 18 if (c.req.header("authorization") !== env().CRON_SECRET) { 19 return c.text("Unauthorized", 401); 20 } 21 22 return next(); 23}); 24 25app.get("/checker/:period", async (c) => { 26 const period = c.req.param("period"); 27 28 const schema = monitorPeriodicitySchema.safeParse(period); 29 30 if (!schema.success) { 31 return c.json({ error: schema.error.issues?.[0].message }, 400); 32 } 33 const sentry = getSentry(c); 34 const checkInId = sentry.captureCheckIn({ 35 monitorSlug: period, 36 status: "in_progress", 37 }); 38 try { 39 await sendCheckerTasks(schema.data, c); 40 sentry.captureCheckIn({ 41 checkInId, 42 monitorSlug: period, 43 status: "ok", 44 }); 45 return c.json({ success: schema.data }, 200); 46 } catch (e) { 47 console.error(e); 48 sentry.captureMessage(`Error in /checker/${period} cron: ${e}`, "error"); 49 sentry.captureCheckIn({ 50 checkInId, 51 monitorSlug: period, 52 status: "error", 53 }); 54 return c.text("Internal Server Error", 500); 55 } 56}); 57 58app.get("/emails/follow-up", async (c) => { 59 try { 60 await sendFollowUpEmails(); 61 return c.json({ success: true }, 200); 62 } catch (e) { 63 console.error(e); 64 return c.text("Internal Server Error", 500); 65 } 66}); 67 68app.get("/monitors", async (c) => { 69 await LaunchMonitorWorkflow(); 70 return c.json({ success: true }, 200); 71}); 72 73app.get("/monitors/:step", async (c) => { 74 const step = c.req.param("step"); 75 const schema = workflowStepSchema.safeParse(step); 76 77 const userId = c.req.query("userId"); 78 const initialRun = c.req.query("initialRun"); 79 if (!schema.success) { 80 return c.json({ error: schema.error.issues?.[0].message }, 400); 81 } 82 83 if (!userId) { 84 getSentry(c).captureMessage( 85 "userId is missing in /monitors/:step cron", 86 "error", 87 ); 88 return c.json({ error: "userId is required" }, 400); 89 } 90 if (!initialRun) { 91 getSentry(c).captureMessage( 92 "initalRun is missing in /monitors/:step cron", 93 "error", 94 ); 95 return c.json({ error: "initialRun is required" }, 400); 96 } 97 98 switch (schema.data) { 99 case "14days": 100 // We send the first email 101 await Step14Days(Number(userId), Number(initialRun)); 102 break; 103 case "3days": 104 await Step3Days(Number(userId), Number(initialRun)); 105 // 3 days before we send the second email 106 break; 107 case "paused": 108 // Let's pause the monitor 109 await StepPaused(Number(userId), Number(initialRun)); 110 break; 111 default: 112 throw new Error("Invalid step"); 113 } 114 // Swith on step 115 // and do the right action 116 // 117 return c.json({ success: true }, 200); 118}); 119 120export { app as cronRouter };