MBO-Tech-IT-Webseite/app/api/analytics/track/route.ts

72 lines
1.9 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { createServiceClient } from "@/lib/supabase";
import { anonymizeIp, isBot, parseDevice, parseBrowser, parseOs } from "@/lib/analytics";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
interface TrackBody {
path: string;
session_id: string;
referrer?: string;
view_id?: string;
duration_ms?: number;
}
export async function POST(req: NextRequest) {
try {
const body: TrackBody = await req.json();
if (!body.path || !body.session_id) {
return NextResponse.json({ ok: false }, { status: 400 });
}
const ua = req.headers.get("user-agent") ?? "";
if (isBot(ua)) {
return NextResponse.json({ ok: true, bot: true });
}
const db = createServiceClient();
if (body.view_id && body.duration_ms !== undefined) {
await db
.from("page_views")
.update({ duration_ms: body.duration_ms })
.eq("id", body.view_id)
.is("duration_ms", null);
return NextResponse.json({ ok: true });
}
const rawIp =
req.headers.get("x-forwarded-for")?.split(",")[0].trim() ??
req.headers.get("x-real-ip") ??
"0.0.0.0";
const { data, error } = await db
.from("page_views")
.insert({
path: body.path,
session_id: body.session_id,
referrer: body.referrer ?? null,
ip_anon: anonymizeIp(rawIp),
device_type: parseDevice(ua),
browser: parseBrowser(ua),
os: parseOs(ua),
is_bot: false,
})
.select("id")
.single();
if (error) {
console.error("[analytics/track] DB error:", error);
return NextResponse.json({ ok: false }, { status: 500 });
}
return NextResponse.json({ ok: true, view_id: data.id });
} catch (err) {
console.error("[analytics/track] Error:", err);
return NextResponse.json({ ok: false }, { status: 500 });
}
}