12 lines
1.2 KiB
TypeScript
12 lines
1.2 KiB
TypeScript
import { db } from "@/lib/db";
|
|
|
|
function allowed(bucket: string, seconds = 3600) {
|
|
const now = Math.floor(Date.now() / 1000); const row = db.prepare("SELECT reset_at FROM rate_limits WHERE bucket=?").get(bucket) as { reset_at: number } | undefined;
|
|
if (row && row.reset_at > now) return false;
|
|
db.prepare("INSERT INTO rate_limits(bucket,count,reset_at) VALUES(?,1,?) ON CONFLICT(bucket) DO UPDATE SET count=count+1,reset_at=excluded.reset_at").run(bucket, now + seconds); return true;
|
|
}
|
|
export async function sendAlert(bucket: string, title: string, message: string) {
|
|
const url = process.env.ALERT_WEBHOOK_URL?.trim(); if (!url || !allowed(`alert:${bucket}`)) return false;
|
|
try { const isNtfy = /(^|\.)ntfy\.sh\//.test(new URL(url).hostname + new URL(url).pathname); const response = await fetch(url, isNtfy ? { method: "POST", headers: { Title: title, Priority: "high" }, body: message, signal: AbortSignal.timeout(10_000) } : { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content: `**${title}**\n${message}` }), signal: AbortSignal.timeout(10_000) }); if (!response.ok) throw new Error(`Alert ${response.status}`); return true; } catch { return false; }
|
|
}
|