diff --git a/app/routes/action.send-rating.ts b/app/routes/action.send-rating.ts index 394683149..95463d1cb 100644 --- a/app/routes/action.send-rating.ts +++ b/app/routes/action.send-rating.ts @@ -3,9 +3,8 @@ import { json, redirect } from "@remix-run/node"; import { BannerState } from "~/components/UserFeedback"; import { userRatingFieldname } from "~/components/UserFeedback/RatingBox"; import { getSessionForContext } from "~/services/session.server"; -import { config } from "~/services/env/web"; import { bannerStateName } from "~/services/feedback/handleFeedback"; -import { getPosthogClient } from "~/services/analytics/posthogClient.server"; +import { sendCustomEvent } from "~/services/analytics/customEvent"; export const loader = () => redirect("/"); @@ -32,11 +31,13 @@ export const action = async ({ request }: ActionFunctionArgs) => { const headers = { "Set-Cookie": await commitSession(session) }; - getPosthogClient()?.capture({ - distinctId: config().ENVIRONMENT, - event: "rating given", - // eslint-disable-next-line camelcase - properties: { wasHelpful: userRatings[url], $current_url: url, context }, + sendCustomEvent({ + eventName: "rating given", + request, + properties: { + wasHelpful: userRatings[url], + context, + }, }); return clientJavaScriptAvailable diff --git a/app/routes/action.set-analytics.tsx b/app/routes/action.set-analytics.tsx index 4eb90bcf2..f3f7297e1 100644 --- a/app/routes/action.set-analytics.tsx +++ b/app/routes/action.set-analytics.tsx @@ -8,8 +8,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { const { searchParams } = new URL(request.url); const clientJavaScriptAvailable = searchParams.get("js"); - const cookie = await consentCookieFromRequest({ request }); - const headers = { "Set-Cookie": cookie }; + const headers = await consentCookieFromRequest({ request }); if (clientJavaScriptAvailable) { return json({ success: true }, { headers }); diff --git a/app/routes/cookie-einstellungen.tsx b/app/routes/cookie-einstellungen.tsx index d3b74f064..e48612792 100644 --- a/app/routes/cookie-einstellungen.tsx +++ b/app/routes/cookie-einstellungen.tsx @@ -19,7 +19,7 @@ export async function loader({ request }: LoaderFunctionArgs) { } export async function action({ request }: ActionFunctionArgs) { - const headers = { "Set-Cookie": await consentCookieFromRequest({ request }) }; + const headers = await consentCookieFromRequest({ request }); return redirect("/cookie-einstellungen/erfolg", { headers }); } diff --git a/app/routes/shared/step.server.ts b/app/routes/shared/step.server.ts index 574ee01d5..397fafffa 100644 --- a/app/routes/shared/step.server.ts +++ b/app/routes/shared/step.server.ts @@ -37,6 +37,7 @@ import { deleteFromArrayInplace, } from "~/services/session.server/arrayDeletion"; import type { StrapiMeta } from "~/services/cms/models/StrapiMeta"; +import { hasTrackingConsent } from "~/services/analytics/gdprCookie.server"; const structureCmsContent = ( formPageContent: z.infer< @@ -301,8 +302,12 @@ export const action = async ({ request }: ActionFunctionArgs) => { }); const customEventName = flowController.getMeta(stepId)?.customEventName; - if (customEventName) - void sendCustomEvent(customEventName, validationResult.data, request); + if (customEventName && (await hasTrackingConsent({ request }))) + sendCustomEvent({ + request, + eventName: customEventName, + properties: { context: validationResult.data }, + }); const returnTo = formData.get("_returnTo"); const destination = diff --git a/app/services/analytics/customEvent.ts b/app/services/analytics/customEvent.ts index b81c6df59..ccdb3b3ec 100644 --- a/app/services/analytics/customEvent.ts +++ b/app/services/analytics/customEvent.ts @@ -1,9 +1,9 @@ -import { hasTrackingConsent } from "./gdprCookie.server"; import { config } from "../env/web"; import { parse } from "cookie"; import { getPosthogClient } from "./posthogClient.server"; function idFromCookie(request: Request) { + // console.log("request", request) // Note: can't use cookie.parse(): https://github.com/remix-run/remix/discussions/5198 // Returns ENVIRONMENT if posthog's distinct_id can't be extracted const { POSTHOG_API_KEY, ENVIRONMENT } = config(); @@ -14,20 +14,25 @@ function idFromCookie(request: Request) { return phCookieObject["distinct_id"] ?? ENVIRONMENT; } -export async function sendCustomEvent( - eventName: string, - context: Record, - request: Request, -) { - if (!(await hasTrackingConsent({ request }))) return; - +export function sendCustomEvent({ + request, + eventName, + properties, +}: { + request: Request; + eventName: string; + properties?: Record< + string, + string | boolean | Record + >; +}) { getPosthogClient()?.capture({ distinctId: idFromCookie(request), event: eventName, properties: { // eslint-disable-next-line camelcase $current_url: new URL(request.url).pathname, - ...context, + ...properties, }, }); } diff --git a/app/services/analytics/gdprCookie.server.ts b/app/services/analytics/gdprCookie.server.ts index a74d9dfc8..d546d0a01 100644 --- a/app/services/analytics/gdprCookie.server.ts +++ b/app/services/analytics/gdprCookie.server.ts @@ -1,6 +1,7 @@ import { createCookie } from "@remix-run/node"; import { acceptCookiesFieldName } from "./Analytics"; import { useSecureCookie } from "~/util/useSecureCookie"; +import { sendCustomEvent } from "./customEvent"; export const consentCookieName = "gdpr-consent"; @@ -38,9 +39,16 @@ async function createTrackingCookie({ }: CookieArgs & { consent?: boolean }) { const cookie = await parseTrackingCookie({ request }); const stringifiedConsentValue = consent ? "true" : "false"; + if (cookie[acceptCookiesFieldName] === stringifiedConsentValue) + return {} as HeadersInit; cookie[acceptCookiesFieldName] = consent === undefined ? undefined : stringifiedConsentValue; - return gdprCookie.serialize(cookie); + sendCustomEvent({ + eventName: "cookie consent given", + request, + properties: { consent: stringifiedConsentValue }, + }); + return { "Set-Cookie": await gdprCookie.serialize(cookie) } as HeadersInit; } export async function consentCookieFromRequest({ diff --git a/app/services/feedback/handleFeedback.ts b/app/services/feedback/handleFeedback.ts index 5bd6b98c5..adb9207eb 100644 --- a/app/services/feedback/handleFeedback.ts +++ b/app/services/feedback/handleFeedback.ts @@ -6,9 +6,8 @@ import { } from "~/components/UserFeedback/FeedbackFormBox"; import { userRatingFieldname } from "~/components/UserFeedback/RatingBox"; import { validationError } from "remix-validated-form"; -import { config } from "../env/web"; import { type Session, redirect } from "@remix-run/node"; -import { getPosthogClient } from "../analytics/posthogClient.server"; +import { sendCustomEvent } from "../analytics/customEvent"; export const bannerStateName = "bannerState"; @@ -30,14 +29,12 @@ export const handleFeedback = async (formData: FormData, request: Request) => { return validationError(result.error, result.submittedData); } bannerState[pathname] = BannerState.FeedbackGiven; - getPosthogClient()?.capture({ - distinctId: config().ENVIRONMENT, - event: "feedback given", + sendCustomEvent({ + eventName: "feedback given", + request, properties: { wasHelpful: userRating[pathname], feedback: result.data?.feedback ?? "", - // eslint-disable-next-line camelcase - $current_url: pathname, context, }, });