← back to Ga Allsites

resolve_orphan_ga4.py

36 lines

#!/usr/bin/env python3
"""Resolve the 3 orphan measurement IDs -> GA4 property (+ verify domain), DRY RUN (no delete)."""
import pathlib

from google.analytics.admin import AnalyticsAdminServiceClient

KEY = pathlib.Path.home()/".config"/"ga-analytics-agent"/"service-account.json"
ORPHANS = {
 "G-9K93LH6GH1": "momentumdw.com",
 "G-JZRGWSY1F6": "nosarabeachfrontrentals.com",
 "G-QG3DGNYWZX": "goodquestion.com",
}
c = AnalyticsAdminServiceClient.from_service_account_file(str(KEY))
found = {}
for acct in c.list_account_summaries():
    for ps in acct.property_summaries:
        prop = ps.property  # "properties/NNN"
        try:
            for ds in c.list_data_streams(parent=prop):
                mid = getattr(getattr(ds, "web_stream_data", None), "measurement_id", "")
                if mid in ORPHANS:
                    uri = ds.web_stream_data.default_uri
                    found[mid] = {"property": prop, "prop_name": ps.display_name,
                                  "acct": acct.display_name, "stream_uri": uri,
                                  "expected_domain": ORPHANS[mid]}
        except Exception:
            pass
print(f"Resolved {len(found)}/3 orphan measurement IDs:\n")
for mid, info in found.items():
    dom = info["expected_domain"]
    match = dom in (info["stream_uri"] or "")
    print(f"  {mid}  -> {info['property']}  '{info['prop_name']}'  (acct: {info['acct']})")
    print(f"      stream_uri={info['stream_uri']}  expected={dom}  DOMAIN_MATCH={match}")
missing = set(ORPHANS) - set(found)
if missing: print("\n  NOT FOUND (SA has no access / already deleted):", ", ".join(missing))