{
  "$meta": {
    "package": "@walkeros/transformer-ga4",
    "version": "4.5.0",
    "type": "transformer",
    "platform": [
      "server",
      "web"
    ],
    "docs": "https://www.walkeros.io/docs/transformers/ga4",
    "source": "https://github.com/elbwalker/walkerOS/tree/main/packages/transformers/ga4/src"
  },
  "schemas": {},
  "examples": {
    "step": {
      "addToCart": {
        "title": "Add to cart",
        "description": "A GA4 add_to_cart hit decoded to a walkerOS product add event with currency and value.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=add_to_cart&ep.currency=EUR&epn.value=129.99"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "product add",
              "entity": "product",
              "action": "add",
              "data": {
                "currency": "EUR",
                "value": 129.99
              }
            }
          ]
        ]
      },
      "batchPost": {
        "title": "Batched POST (fan-out)",
        "description": "A single POST request carrying two newline-separated events fans out into two walkerOS events.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000",
          "body": "en=add_to_cart&ep.currency=EUR&epn.value=19.99\nen=add_to_cart&ep.currency=EUR&epn.value=29.99"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "product add",
              "entity": "product",
              "action": "add",
              "data": {
                "currency": "EUR",
                "value": 19.99
              }
            }
          ],
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "product add",
              "entity": "product",
              "action": "add",
              "data": {
                "currency": "EUR",
                "value": 29.99
              }
            }
          ]
        ]
      },
      "beginCheckout": {
        "title": "Begin checkout",
        "description": "A GA4 begin_checkout hit decoded to a walkerOS order start event with currency, value, and coupon.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=begin_checkout&ep.currency=EUR&epn.value=149.97&ep.coupon=WELCOME10"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "order start",
              "entity": "order",
              "action": "start",
              "data": {
                "currency": "EUR",
                "value": 149.97,
                "coupon": "WELCOME10"
              }
            }
          ]
        ]
      },
      "consentDenied": {
        "title": "Consent denied (gcs=G100)",
        "description": "A page_view hit with gcs=G100 still maps, with consent.{marketing,analytics} both false on the resulting event.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&gcs=G100&en=page_view&dl=https%3A%2F%2Fx&dt=X"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {
                "marketing": false,
                "analytics": false
              },
              "name": "page view",
              "entity": "page",
              "action": "view",
              "data": {
                "id": "https://x",
                "title": "X"
              }
            }
          ]
        ]
      },
      "customEvent": {
        "title": "Custom event (* fallback)",
        "description": "Unknown GA4 event names hit the * fallback rule and surface as a ga4 track event carrying the original name.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=newsletter_subscribe&ep.source=footer"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "ga4 track",
              "entity": "ga4",
              "action": "track",
              "data": {
                "event_name": "newsletter_subscribe"
              }
            }
          ]
        ]
      },
      "login": {
        "title": "Login",
        "description": "A GA4 login hit decoded to a walkerOS session login event with the auth method.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=login&ep.method=google"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "session login",
              "entity": "session",
              "action": "login",
              "data": {
                "method": "google"
              }
            }
          ]
        ]
      },
      "pageView": {
        "title": "Page view",
        "description": "A standard GA4 page_view hit decoded to a walkerOS page view with id, title, and referrer.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=page_view&dl=https%3A%2F%2Fshop.example.com%2Fproducts%2Fsku-123&dt=Trail%20Runner%20Pro&dr=https%3A%2F%2Fshop.example.com%2F"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "page view",
              "entity": "page",
              "action": "view",
              "data": {
                "id": "https://shop.example.com/products/sku-123",
                "title": "Trail Runner Pro",
                "referrer": "https://shop.example.com/"
              }
            }
          ]
        ]
      },
      "purchase": {
        "title": "Purchase (canary)",
        "description": "A GA4 purchase hit decoded to a walkerOS order complete event with id, currency, total, tax, shipping, and coupon.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=purchase&ep.transaction_id=T-9001&ep.currency=EUR&epn.value=149.97&epn.tax=23.97&epn.shipping=4.95&ep.coupon=WELCOME10"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "order complete",
              "entity": "order",
              "action": "complete",
              "data": {
                "id": "T-9001",
                "currency": "EUR",
                "total": 149.97,
                "tax": 23.97,
                "shipping": 4.95,
                "coupon": "WELCOME10"
              }
            }
          ]
        ]
      },
      "scroll": {
        "title": "Scroll",
        "description": "A GA4 scroll hit decoded to a walkerOS page scroll event with the percent_scrolled value.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=scroll&epn.percent_scrolled=90"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "page scroll",
              "entity": "page",
              "action": "scroll",
              "data": {
                "percent": 90
              }
            }
          ]
        ]
      },
      "search": {
        "title": "Search",
        "description": "A GA4 search hit decoded to a walkerOS search submit event carrying the search term.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=search&ep.search_term=trail%20runner"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "search submit",
              "entity": "search",
              "action": "submit",
              "data": {
                "term": "trail runner"
              }
            }
          ]
        ]
      },
      "userEngagementIgnored": {
        "title": "user_engagement (ignored)",
        "description": "Auto-fired GA4 user_engagement events are dropped by default — the transformer returns false.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=user_engagement&_et=1500"
        },
        "out": [
          [
            "return",
            false
          ]
        ]
      },
      "viewItem": {
        "title": "View item",
        "description": "A GA4 view_item hit decoded to a walkerOS product view event with currency and value.",
        "in": {
          "url": "https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=1700000000&en=view_item&ep.currency=EUR&epn.value=129.99"
        },
        "out": [
          [
            "return",
            {
              "id": "p1",
              "timestamp": 1700000000000,
              "timing": 0,
              "trigger": "ga4",
              "user": {
                "device": "cid-1",
                "session": "1700000000"
              },
              "globals": {},
              "source": {
                "type": "ga4"
              },
              "consent": {},
              "name": "product view",
              "entity": "product",
              "action": "view",
              "data": {
                "currency": "EUR",
                "value": 129.99
              }
            }
          ]
        ]
      }
    }
  },
  "hints": {
    "wiring": {
      "text": "This is a request-decoder: it reads the raw GA4 hit from ctx.ingest (ctx.ingest.url, optional ctx.ingest.body) and decodes it into walkerOS events. Place it on a server source's before chain (source.before), NOT on source.next and NOT on a destination.before chain; it runs before the collector to turn the incoming request into events. The source populates ctx.ingest from its config.ingest, which MUST be a map operator: { map: { url: { key: 'url' }, path: { key: 'path' }, method: { key: 'method' }, body: { key: 'body' } } }. The keys are direct fields on the Express req (no req. prefix): url is the full request URL with query string (what the decoder reads), path drives the /g/collect before match, method and body carry POST batches. A bare object like { url: 'req.url' } is silently inert: with no map operator the source passes the whole req through getMappingValue, a real Express req fails the property check (it carries functions and circular refs), ctx.ingest stays empty, and the decoder skips the hit. A pre-parsed JSON body will not decode; pass the raw body text.",
      "code": [
        {
          "lang": "json",
          "code": "{\n  \"sources\": {\n    \"http\": {\n      \"package\": \"@walkeros/server-source-express\",\n      \"config\": {\n        \"ingest\": {\n          \"map\": {\n            \"url\": {\n              \"key\": \"url\"\n            },\n            \"path\": {\n              \"key\": \"path\"\n            },\n            \"method\": {\n              \"key\": \"method\"\n            },\n            \"body\": {\n              \"key\": \"body\"\n            }\n          }\n        }\n      },\n      \"before\": \"ga4\"\n    }\n  },\n  \"transformers\": {\n    \"ga4\": {\n      \"package\": \"@walkeros/transformer-ga4\"\n    }\n  }\n}"
        }
      ]
    }
  }
}