Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/utils/helpers/AnalyticsHelper.ts
T

110 lines
3.5 KiB
TypeScript

import platform from "platform";
import { CookieCategory } from "~/application/cookies/CookieCategory";
import CookieHelper from "./CookieHelper";
import { AppRootData } from "../data/useRootData";
import { apiPath } from "../app/CanonicalUrlUtils";
// EU-Sterilisation (R-P1a): Google-Analytics-gtag-Aufrufe entfernt. Es bleibt nur die First-Party-
// Analytics-Ingestion gegen den eigenen API-Endpunkt (gated über ANALYTICS-Cookie-Consent).
type AnalyticsProps = {
url: string;
rootData: Pick<AppRootData, "apiBaseUrl" | "userSession" | "analytics" | "analyticsToken">;
route?: string;
};
export async function addPageView({ url, rootData, route }: AnalyticsProps) {
if (rootData.analytics && CookieHelper.hasConsent(rootData.userSession, CookieCategory.ANALYTICS)) {
// console.log("[PAGE VIEW]", JSON.stringify({ url, analytics: rootData.analytics }));
try {
await fetch(new URL(apiPath("analytics/page-views", { mode: "host-aware" }), rootData.apiBaseUrl), {
method: "POST",
headers: { "Content-Type": "application/json", ...(rootData.analyticsToken ? { "x-analytics-token": rootData.analyticsToken } : {}) },
body: JSON.stringify({
url,
route,
analytics: {
...rootData.analytics,
userAgent: getUserAgentDetails(),
},
}),
});
} catch (e: any) {
// eslint-disable-next-line no-console
console.error("[PAGE VIEW]", e.message);
}
}
}
type EventProps = AnalyticsProps & {
url?: string;
action: string;
category: string;
label: string;
value: string;
};
export async function addEvent({ url, route, action, category, label, value, rootData }: EventProps) {
if (rootData.analytics && CookieHelper.hasConsent(rootData.userSession, CookieCategory.ANALYTICS)) {
// console.log("[EVENT]", JSON.stringify({ action, category, label, value, url, analytics: rootData.analytics }));
try {
await fetch(new URL(apiPath("analytics/events", { mode: "host-aware" }), rootData.apiBaseUrl), {
method: "POST",
headers: { "Content-Type": "application/json", ...(rootData.analyticsToken ? { "x-analytics-token": rootData.analyticsToken } : {}) },
body: JSON.stringify({
action,
category,
label,
value,
url,
route,
analytics: {
...rootData.analytics,
userAgent: getUserAgentDetails(),
},
}),
});
} catch (e: any) {
// eslint-disable-next-line no-console
console.error("[PAGE VIEW]", e.message);
}
}
}
function getUserAgentDetails(userAgent?: string) {
const deviceType = () => {
if (!userAgent) {
return undefined;
}
const ua = userAgent;
if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {
return "tablet";
} else if (/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(ua)) {
return "mobile";
}
return "desktop";
};
return {
type: deviceType(),
os: {
family: platform.os?.family,
version: platform.os?.version,
},
browser: {
name: platform.name,
version: platform.version,
},
};
}
// export async function createUniqueVisitorHash(domain: string, ipAddress: string, userAgent: string) {
// const hash = sha256(domain + ipAddress + userAgent);
// console.log({ hash });
// return hash;
// }
export default {
addPageView,
addEvent,
getUserAgentDetails,
};