Files
rengine/shared/utils/tracking.py
T
Yogesh Ojha a2d67cab83 feat(correlation): tracking accounts as a correlation kind
Every web asset carries the analytics, tag manager and ads accounts its
page loads (Universal Analytics folded to its account, GA4, GTM, Google
Ads, AdSense, Meta pixel, Hotjar, Clarity, Yandex, HubSpot), read at
write and by the stored-response backfill. tracking is a correlation
kind, a host grammar field and the second cross link after the
certificate, judged by the page rule so a parked or default page never
vouches for its provider's account.

generic_page kept only ASCII, so a Devanagari or Chinese title read as
empty and every hub of a non-Latin estate was the server's. It keeps
Unicode word characters now.
2026-09-24 23:47:45 +05:30

37 lines
1.4 KiB
Python

"""Analytics, tag manager and ads account IDs a page loads."""
from __future__ import annotations
import re
MAX_TRACKING_IDS = 20
BODY_SCAN_BYTES = 131_072
_QUOTED = r"""(?<=[\"'=/])"""
_PATTERNS: tuple[tuple[re.Pattern[str], str], ...] = (
(re.compile(_QUOTED + r"UA-(\d{4,10})-\d{1,4}(?![\w-])"), "UA-{}"),
(re.compile(_QUOTED + r"(G-[A-Z0-9]{8,12})(?![\w-])"), "{}"),
(re.compile(_QUOTED + r"(GTM-[A-Z0-9]{4,9})(?![\w-])"), "{}"),
(re.compile(_QUOTED + r"(AW-\d{8,12})(?![\w-])"), "{}"),
(re.compile(r"(ca-pub-\d{10,20})(?!\d)"), "{}"),
(re.compile(r"""fbq\(\s*['"]init['"]\s*,\s*['"](\d{10,20})['"]"""), "fb:{}"),
(re.compile(r"hjid\s*:\s*(\d{5,10})"), "hotjar:{}"),
(re.compile(r"clarity\.ms/tag/([a-z0-9]{8,12})", re.IGNORECASE), "clarity:{}"),
(re.compile(r"\bym\(\s*(\d{5,10})\s*,"), "ym:{}"),
(re.compile(r"js\.hs-scripts\.com/(\d{5,10})\.js"), "hubspot:{}"),
)
def tracking_ids(body: str | None) -> list[str]:
"""Every account a page names, a Universal Analytics property folded to its account."""
if not body:
return []
text = body[:BODY_SCAN_BYTES]
found: dict[str, None] = {}
for pattern, shape in _PATTERNS:
for match in pattern.findall(text):
found.setdefault(shape.format(match), None)
if len(found) >= MAX_TRACKING_IDS:
return sorted(found)
return sorted(found)