feat: reminder email opt-in 1 hour before registration opens
This commit is contained in:
40
apps/web/src/routes/api/cron/reminders.ts
Normal file
40
apps/web/src/routes/api/cron/reminders.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { runSendReminders } from "@kk/api/routers/index";
|
||||
import { env } from "@kk/env/server";
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
|
||||
async function handleCronReminders({ request }: { request: Request }) {
|
||||
const secret = env.CRON_SECRET;
|
||||
if (!secret) {
|
||||
return new Response("CRON_SECRET not configured", { status: 500 });
|
||||
}
|
||||
|
||||
// Accept the secret via Authorization header (Bearer) or JSON body
|
||||
const authHeader = request.headers.get("Authorization");
|
||||
let providedSecret: string | null = null;
|
||||
|
||||
if (authHeader?.startsWith("Bearer ")) {
|
||||
providedSecret = authHeader.slice(7);
|
||||
} else {
|
||||
try {
|
||||
const body = await request.json();
|
||||
providedSecret = (body as { secret?: string }).secret ?? null;
|
||||
} catch {
|
||||
// ignore parse errors
|
||||
}
|
||||
}
|
||||
|
||||
if (!providedSecret || providedSecret !== secret) {
|
||||
return new Response("Unauthorized", { status: 401 });
|
||||
}
|
||||
|
||||
const result = await runSendReminders();
|
||||
return Response.json(result);
|
||||
}
|
||||
|
||||
export const Route = createFileRoute("/api/cron/reminders")({
|
||||
server: {
|
||||
handlers: {
|
||||
POST: handleCronReminders,
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user