37 lines
3.9 KiB
Markdown
37 lines
3.9 KiB
Markdown
# MoreminiMore tracking
|
|
|
|
Tracking is enabled in production builds and omitted from the Astro development server so local previews do not pollute production data. Production starts with every non-essential Google Consent Mode signal denied. No analytics, advertising, or recorder script is requested until ConsentOS emits the verified `consentos:consent-change` event with the corresponding accepted category.
|
|
|
|
## Installed tools
|
|
|
|
- ConsentOS — the loader follows a non-networking denied-default bootstrap and runs before any tracking tag. Its `analytics` category gates GA4, Umami, and the recorder; `marketing` gates Meta Pixel.
|
|
- Google Analytics 4 — measurement ID `G-74BHREDLC3`.
|
|
- Meta Pixel — pixel ID `418349260078648`, including PageView event IDs.
|
|
- Umami Analytics — website ID `b2e87a6c-0b64-43c8-bb09-e406ffca0af1`.
|
|
- Umami Recorder — 15% sample rate, strict masking, five-minute maximum sessions. `.contact-form` is excluded through both the recorder block selector and rrweb's `rr-block` class.
|
|
|
|
If a visitor withdraws analytics or marketing consent after a tag was loaded, the page reloads after ConsentOS stores the new choice. The reloaded page stays tag-free for the withdrawn category. The Meta noscript fallback is intentionally omitted because it cannot be safely consent-gated without JavaScript.
|
|
|
|
## Events
|
|
|
|
| Event | Trigger | Properties |
|
|
| --- | --- | --- |
|
|
| `page_view` / `PageView` | Each production page load | Automatic page data |
|
|
| `contact_clicked` / `Contact` | Phone, email, or LINE link | `method`, `location` |
|
|
| `service_selected` / `ViewContent` | Service landing-page link | `service_path`, `location` |
|
|
| `form_started` | First focus inside a contact form | `form_location` |
|
|
| `form_submitted` / `Lead` | Contact API confirms a successful submission | `form_location`, shared random event ID for Meta deduplication |
|
|
|
|
No names, phone numbers, email addresses, form values, or other personally identifiable information are included in these client-side events.
|
|
|
|
## Contact-form tracking
|
|
|
|
Each page uses the same short contact form. `form_started` is emitted once on the first focus. The client creates a UUID event ID for each validated submission and sends a boolean snapshot of the already-applied ConsentOS state. The same ID is retained across network or ambiguous-response retries; it rotates only after confirmed success or an actual edit to the form contents. `form_submitted` and the Meta standard `Lead` browser event are emitted only after `/api/contact` returns success. The browser event contains only the page or service location and reuses the same event ID as Meta CAPI for deduplication.
|
|
|
|
The contact endpoint sends email through Amazon SES first. Only after SES succeeds:
|
|
|
|
- With marketing consent and `META_ACCESS_TOKEN`, Meta CAPI receives `Lead`, the shared event ID, server IP/user agent, validated `_fbp`/`_fbc`, and normalized name/contact values hashed with SHA-256. Thai phone numbers are normalized to country code `66` before hashing. Raw form values are not sent to Meta.
|
|
- With analytics consent, `GA4_API_SECRET`, and a safely retrieved GA client ID, Google Measurement Protocol receives `form_submitted`, session/context identifiers, explicit advertising consent state, and no PII, hashes, or user properties. The browser helper skips its GA copy to avoid a duplicate event; Umami still receives the PII-free event.
|
|
|
|
Provider requests have short timeouts and are handled with `Promise.allSettled`, so missing tokens, upstream errors, or timeouts never change a successful form response. There is no public conversion relay route. Event IDs are UUID-v4 validated and retained in a bounded 15-minute pending/completed registry. Concurrent pending requests receive a processing response; a retry of a completed delivery receives success without sending a second email, while failed SES attempts release the ID for retry. Delivery and provider logs contain status only and never include form values, credentials, tokens, or upstream response bodies.
|