← back to Ga4 Fleet

batch_create_19.py

110 lines

#!/usr/bin/env python3
"""Batch-create 19 GA4 properties under accounts/136095445.
Idempotency: caller must pre-verify none exist (done by analytics agent).
"""
from __future__ import annotations
import json
import os
import sys
import time
from pathlib import Path

KEY_PATH = Path.home() / ".config" / "ga-analytics-agent" / "service-account.json"
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = str(KEY_PATH)

ACCOUNT_ID = "accounts/136095445"

DOMAINS = [
    ("astek.designerwallcoverings.com",          "Astek DW"),
    ("crcp.agentabrams.com",                     "CRCP"),
    ("designersalesreps.com",                    "Designer Sales Reps"),
    ("fallingstar.designerwallcoverings.com",    "Falling Star DW"),
    ("grant.agentabrams.com",                    "Grant"),
    ("homesonspec.com",                          "Homes On Spec"),
    ("leads.venturaclaw.com",                    "Leads Ventura Claw"),
    ("new.engine.designerwallcoverings.com",     "New Engine DW"),
    ("pairs.designerwallcoverings.com",          "Pairs DW"),
    ("patterndesignlab.com",                     "Pattern Design Lab"),
    ("pitchguard.designerwallcoverings.com",     "Pitchguard DW"),
    ("quadrille.designerwallcoverings.com",      "Quadrille DW"),
    ("reidwitlin.designerwallcoverings.com",     "Reid Witlin DW"),
    ("rentv.agentabrams.com",                    "RENTV"),
    ("sixskills.agentabrams.com",                "Six Skills"),
    ("sublease.agentabrams.com",                 "Sublease"),
    ("textiletuesday.com",                       "Textile Tuesday"),
    ("tools.designerwallcoverings.com",          "Tools DW"),
    ("trending.designerwallcoverings.com",       "Trending DW"),
]

MEASUREMENT_IDS_PATH = Path("/Users/macstudio3/Projects/ga4-fleet/measurement-ids.json")


def load_existing():
    if MEASUREMENT_IDS_PATH.exists():
        return json.loads(MEASUREMENT_IDS_PATH.read_text())
    return {}


def save_ids(ids: dict):
    MEASUREMENT_IDS_PATH.write_text(json.dumps(ids, indent=2, sort_keys=True) + "\n")


def main():
    from google.analytics.admin import AnalyticsAdminServiceClient
    from google.analytics.admin_v1alpha.types import Property, DataStream

    client = AnalyticsAdminServiceClient()
    results = []

    existing_ids = load_existing()

    for domain, display_name in DOMAINS:
        if domain in existing_ids:
            print(f"SKIP (already in JSON): {domain} -> {existing_ids[domain]}")
            results.append((domain, existing_ids[domain], "ALREADY-IN-JSON"))
            continue

        print(f"Creating property for {domain} ...", flush=True)
        try:
            prop = Property(
                parent=ACCOUNT_ID,
                display_name=display_name,
                time_zone="America/Los_Angeles",
                currency_code="USD",
                industry_category="HOME_AND_GARDEN",
            )
            created = client.create_property(property=prop)
            prop_name = created.name

            stream = DataStream(
                type_=DataStream.DataStreamType.WEB_DATA_STREAM,
                display_name=f"{display_name} Web",
                web_stream_data=DataStream.WebStreamData(
                    default_uri=f"https://{domain}",
                ),
            )
            stream = client.create_data_stream(parent=prop_name, data_stream=stream)
            measurement_id = stream.web_stream_data.measurement_id

            print(f"  OK: {prop_name} -> {measurement_id}")
            existing_ids[domain] = measurement_id
            save_ids(existing_ids)
            results.append((domain, measurement_id, "CREATED"))

            # Small delay to be courteous to the API
            time.sleep(0.5)

        except Exception as e:
            print(f"  ERROR: {e}")
            results.append((domain, "ERROR", str(e)))

    print("\n=== RESULTS ===")
    for domain, mid, status in results:
        print(f"{domain:<55} {mid:<20} {status}")

    return results


if __name__ == "__main__":
    main()