[{"data":1,"prerenderedAt":1910},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fes\u002Fdata\u002Fservidor-sgtm-conversion-api-produccion":11},{"i18nKey":4,"paths":5},"data-001-2026-06",{"de":6,"en":7,"es":8,"fr":9,"it":10},"\u002Fde\u002Fdata\u002Fserver-side-gtm-conversion-api-produktion","\u002Fen\u002Fdata\u002Fserver-side-gtm-conversion-api-production","\u002Fes\u002Fdata\u002Fservidor-sgtm-conversion-api-produccion","\u002Ffr\u002Fdata\u002Fserveur-gtm-conversion-api-production","\u002Fit\u002Fdata\u002Fserver-side-gtm-conversion-api-production",{"_path":8,"_dir":12,"_draft":13,"_partial":13,"_locale":14,"title":15,"description":16,"publishedAt":17,"modifiedAt":17,"category":12,"i18nKey":4,"tags":18,"readingTime":24,"author":25,"body":26,"_type":1904,"_id":1905,"_source":1906,"_file":1907,"_stem":1908,"_extension":1909},"data",false,"","Server-Side GTM y Conversion API: De Cero a Producción","Guía para construir infraestructura de medición server-side en Cloud Run o Workers. Template de contenedor, lógica de deduplicación y checklist de producción.","2026-06-28",[19,20,21,22,23],"server-side-gtm","conversion-api","cloud-run","container-deduplication","first-party-data",9,"Roibase",{"type":27,"children":28,"toc":1892},"root",[29,37,44,49,54,59,65,70,84,188,216,229,306,311,448,461,468,473,1011,1016,1022,1027,1047,1059,1156,1190,1240,1266,1272,1301,1334,1354,1459,1482,1488,1500,1505,1661,1674,1680,1685,1709,1719,1737,1747,1765,1770,1875,1881,1886],{"type":30,"tag":31,"props":32,"children":33},"element","p",{},[34],{"type":35,"value":36},"text","Con la era de las cookies llegando a su fin, si tu infraestructura de medición sigue funcionando en un contenedor web, estás aceptando pérdidas de atribución. Los números de ROAS en Facebook que cayeron entre 30-40% después de iOS 14.5 no son coincidencia — son prueba de que el tagging client-side ya no refleja la realidad. Server-side tagging y Conversion API son el nuevo estándar para transportar estas señales a las plataformas sin las restricciones del navegador. En este artículo construimos desde cero una infraestructura de server-side GTM lista para producción en Google Cloud Run o Cloudflare Workers.",{"type":30,"tag":38,"props":39,"children":41},"h2",{"id":40},"el-final-del-tagging-client-side-el-comienzo-del-server-side",[42],{"type":35,"value":43},"El Final del Tagging Client-Side, el Comienzo del Server-Side",{"type":30,"tag":31,"props":45,"children":46},{},[47],{"type":35,"value":48},"Google Tag Manager ejecutándose en un contenedor web corre JavaScript en el navegador del visitante. En este escenario cada píxel, cada SDK de plataforma, envía solicitudes desde la IP del cliente. Con Safari ITP 2.0, la vida útil de las cookies de first-party bajó a 7 días; con Consent Mode v2, la tasa de rechazo alcanzó 60%. Cuando el navegador elimina estas cookies, la API de la plataforma pierde la identidad — la señal de conversión queda huérfana, la atribución se colapsa.",{"type":30,"tag":31,"props":50,"children":51},{},[52],{"type":35,"value":53},"Server-side GTM invierte esta lógica. El contenedor web recopila datos mínimos del visitante (nombre del evento, user agent, IP) y los POST a tu propio servidor. El contenedor GTM ejecutándose en tu servidor (imagen Docker) recibe este evento, lo enriquece y lo envía server-to-server a la API de la plataforma. En este flujo la cookie no vive en el navegador sino en tu servidor, su vida útil la defines tú, se evita el ad blocker. Meta Conversion API o el Measurement Protocol de Google Analytics 4 se alimentan directamente desde tu servidor — la pérdida de datos baja de 60% a 10-15%.",{"type":30,"tag":31,"props":55,"children":56},{},[57],{"type":35,"value":58},"Esta diferencia requiere profundidad técnica. La elección del proveedor cloud, la versión del contenedor, la estrategia de deduplicación, el esquema de mapeo de eventos — todo es crítico. Ahora los construimos.",{"type":30,"tag":38,"props":60,"children":62},{"id":61},"configurar-server-side-container-en-google-cloud-run",[63],{"type":35,"value":64},"Configurar Server-Side Container en Google Cloud Run",{"type":30,"tag":31,"props":66,"children":67},{},[68],{"type":35,"value":69},"Google Cloud Run es un runtime de contenedores serverless. Compila imagen desde Dockerfile, escala bajo demanda, baja a cero cuando está inactivo. El método de deployment oficial para server-side GTM no es Cloud Run (se prefieren App Engine o GCE manual) pero Cloud Run ofrece ventaja de costo — para 5-10 millones de eventos mensuales, cuesta ~$10-20 en lugar de $30-50.",{"type":30,"tag":31,"props":71,"children":72},{},[73,75,82],{"type":35,"value":74},"El primer paso es abrir un nuevo proyecto en Google Cloud Console. Si tienes ",{"type":30,"tag":76,"props":77,"children":79},"code",{"className":78},[],[80],{"type":35,"value":81},"gcloud",{"type":35,"value":83}," CLI instalado, la línea de comandos es más rápida:",{"type":30,"tag":85,"props":86,"children":90},"pre",{"className":87,"code":88,"language":89,"meta":14,"style":14},"language-bash shiki shiki-themes github-dark","gcloud projects create roibase-sgtm-prod --name=\"Roibase sGTM Production\"\ngcloud config set project roibase-sgtm-prod\ngcloud services enable run.googleapis.com containerregistry.googleapis.com\n","bash",[91],{"type":30,"tag":76,"props":92,"children":93},{"__ignoreMap":14},[94,132,160],{"type":30,"tag":95,"props":96,"children":99},"span",{"class":97,"line":98},"line",1,[100,105,111,116,121,127],{"type":30,"tag":95,"props":101,"children":103},{"style":102},"--shiki-default:#B392F0",[104],{"type":35,"value":81},{"type":30,"tag":95,"props":106,"children":108},{"style":107},"--shiki-default:#9ECBFF",[109],{"type":35,"value":110}," projects",{"type":30,"tag":95,"props":112,"children":113},{"style":107},[114],{"type":35,"value":115}," create",{"type":30,"tag":95,"props":117,"children":118},{"style":107},[119],{"type":35,"value":120}," roibase-sgtm-prod",{"type":30,"tag":95,"props":122,"children":124},{"style":123},"--shiki-default:#79B8FF",[125],{"type":35,"value":126}," --name=",{"type":30,"tag":95,"props":128,"children":129},{"style":107},[130],{"type":35,"value":131},"\"Roibase sGTM Production\"\n",{"type":30,"tag":95,"props":133,"children":135},{"class":97,"line":134},2,[136,140,145,150,155],{"type":30,"tag":95,"props":137,"children":138},{"style":102},[139],{"type":35,"value":81},{"type":30,"tag":95,"props":141,"children":142},{"style":107},[143],{"type":35,"value":144}," config",{"type":30,"tag":95,"props":146,"children":147},{"style":107},[148],{"type":35,"value":149}," set",{"type":30,"tag":95,"props":151,"children":152},{"style":107},[153],{"type":35,"value":154}," project",{"type":30,"tag":95,"props":156,"children":157},{"style":107},[158],{"type":35,"value":159}," roibase-sgtm-prod\n",{"type":30,"tag":95,"props":161,"children":163},{"class":97,"line":162},3,[164,168,173,178,183],{"type":30,"tag":95,"props":165,"children":166},{"style":102},[167],{"type":35,"value":81},{"type":30,"tag":95,"props":169,"children":170},{"style":107},[171],{"type":35,"value":172}," services",{"type":30,"tag":95,"props":174,"children":175},{"style":107},[176],{"type":35,"value":177}," enable",{"type":30,"tag":95,"props":179,"children":180},{"style":107},[181],{"type":35,"value":182}," run.googleapis.com",{"type":30,"tag":95,"props":184,"children":185},{"style":107},[186],{"type":35,"value":187}," containerregistry.googleapis.com\n",{"type":30,"tag":31,"props":189,"children":190},{},[191,193,199,201,206,208,214],{"type":35,"value":192},"En Google Tag Manager crea un contenedor de tipo ",{"type":30,"tag":194,"props":195,"children":196},"strong",{},[197],{"type":35,"value":198},"Servidor",{"type":35,"value":200},". En Configuración > Configuración de Contenedor anota la ",{"type":30,"tag":194,"props":202,"children":203},{},[204],{"type":35,"value":205},"URL del Servidor de Etiquetado",{"type":35,"value":207}," (ej. ",{"type":30,"tag":76,"props":209,"children":211},{"className":210},[],[212],{"type":35,"value":213},"https:\u002F\u002Fsgtm.roibase.io",{"type":35,"value":215},"). Este dominio personalizado apuntará al servicio de Cloud Run.",{"type":30,"tag":31,"props":217,"children":218},{},[219,221,227],{"type":35,"value":220},"La imagen oficial de Google ",{"type":30,"tag":76,"props":222,"children":224},{"className":223},[],[225],{"type":35,"value":226},"gcr.io\u002Fcloud-tagging-10302018\u002Fgtm-cloud-image:stable",{"type":35,"value":228}," es segura para producción pero sin bloqueo de versión. Nuestro enfoque es escribir nuestro propio Dockerfile fijando la imagen base:",{"type":30,"tag":85,"props":230,"children":234},{"className":231,"code":232,"language":233,"meta":14,"style":14},"language-dockerfile shiki shiki-themes github-dark","FROM gcr.io\u002Fcloud-tagging-10302018\u002Fgtm-cloud-image:stable\n\nENV CONTAINER_CONFIG=\"\u003CGTM container ID>\"\nENV PREVIEW_SERVER_URL=\"https:\u002F\u002Fsgtm-preview.roibase.io\"\n\nEXPOSE 8080\n\nCMD [\"\u002Fbin\u002Fsh\", \"-c\", \"\u002Fapp\u002Fstart_server\"]\n","dockerfile",[235],{"type":30,"tag":76,"props":236,"children":237},{"__ignoreMap":14},[238,246,255,263,272,280,289,297],{"type":30,"tag":95,"props":239,"children":240},{"class":97,"line":98},[241],{"type":30,"tag":95,"props":242,"children":243},{},[244],{"type":35,"value":245},"FROM gcr.io\u002Fcloud-tagging-10302018\u002Fgtm-cloud-image:stable\n",{"type":30,"tag":95,"props":247,"children":248},{"class":97,"line":134},[249],{"type":30,"tag":95,"props":250,"children":252},{"emptyLinePlaceholder":251},true,[253],{"type":35,"value":254},"\n",{"type":30,"tag":95,"props":256,"children":257},{"class":97,"line":162},[258],{"type":30,"tag":95,"props":259,"children":260},{},[261],{"type":35,"value":262},"ENV CONTAINER_CONFIG=\"\u003CGTM container ID>\"\n",{"type":30,"tag":95,"props":264,"children":266},{"class":97,"line":265},4,[267],{"type":30,"tag":95,"props":268,"children":269},{},[270],{"type":35,"value":271},"ENV PREVIEW_SERVER_URL=\"https:\u002F\u002Fsgtm-preview.roibase.io\"\n",{"type":30,"tag":95,"props":273,"children":275},{"class":97,"line":274},5,[276],{"type":30,"tag":95,"props":277,"children":278},{"emptyLinePlaceholder":251},[279],{"type":35,"value":254},{"type":30,"tag":95,"props":281,"children":283},{"class":97,"line":282},6,[284],{"type":30,"tag":95,"props":285,"children":286},{},[287],{"type":35,"value":288},"EXPOSE 8080\n",{"type":30,"tag":95,"props":290,"children":292},{"class":97,"line":291},7,[293],{"type":30,"tag":95,"props":294,"children":295},{"emptyLinePlaceholder":251},[296],{"type":35,"value":254},{"type":30,"tag":95,"props":298,"children":300},{"class":97,"line":299},8,[301],{"type":30,"tag":95,"props":302,"children":303},{},[304],{"type":35,"value":305},"CMD [\"\u002Fbin\u002Fsh\", \"-c\", \"\u002Fapp\u002Fstart_server\"]\n",{"type":30,"tag":31,"props":307,"children":308},{},[309],{"type":35,"value":310},"Deploy esta imagen a Cloud Run:",{"type":30,"tag":85,"props":312,"children":314},{"className":87,"code":313,"language":89,"meta":14,"style":14},"gcloud builds submit --tag gcr.io\u002Froibase-sgtm-prod\u002Fsgtm-container\ngcloud run deploy sgtm-service \\\n  --image gcr.io\u002Froibase-sgtm-prod\u002Fsgtm-container \\\n  --platform managed \\\n  --region europe-west1 \\\n  --allow-unauthenticated \\\n  --set-env-vars CONTAINER_CONFIG=GTM-XXXXXX\n",[315],{"type":30,"tag":76,"props":316,"children":317},{"__ignoreMap":14},[318,345,372,389,406,423,435],{"type":30,"tag":95,"props":319,"children":320},{"class":97,"line":98},[321,325,330,335,340],{"type":30,"tag":95,"props":322,"children":323},{"style":102},[324],{"type":35,"value":81},{"type":30,"tag":95,"props":326,"children":327},{"style":107},[328],{"type":35,"value":329}," builds",{"type":30,"tag":95,"props":331,"children":332},{"style":107},[333],{"type":35,"value":334}," submit",{"type":30,"tag":95,"props":336,"children":337},{"style":123},[338],{"type":35,"value":339}," --tag",{"type":30,"tag":95,"props":341,"children":342},{"style":107},[343],{"type":35,"value":344}," gcr.io\u002Froibase-sgtm-prod\u002Fsgtm-container\n",{"type":30,"tag":95,"props":346,"children":347},{"class":97,"line":134},[348,352,357,362,367],{"type":30,"tag":95,"props":349,"children":350},{"style":102},[351],{"type":35,"value":81},{"type":30,"tag":95,"props":353,"children":354},{"style":107},[355],{"type":35,"value":356}," run",{"type":30,"tag":95,"props":358,"children":359},{"style":107},[360],{"type":35,"value":361}," deploy",{"type":30,"tag":95,"props":363,"children":364},{"style":107},[365],{"type":35,"value":366}," sgtm-service",{"type":30,"tag":95,"props":368,"children":369},{"style":123},[370],{"type":35,"value":371}," \\\n",{"type":30,"tag":95,"props":373,"children":374},{"class":97,"line":162},[375,380,385],{"type":30,"tag":95,"props":376,"children":377},{"style":123},[378],{"type":35,"value":379},"  --image",{"type":30,"tag":95,"props":381,"children":382},{"style":107},[383],{"type":35,"value":384}," gcr.io\u002Froibase-sgtm-prod\u002Fsgtm-container",{"type":30,"tag":95,"props":386,"children":387},{"style":123},[388],{"type":35,"value":371},{"type":30,"tag":95,"props":390,"children":391},{"class":97,"line":265},[392,397,402],{"type":30,"tag":95,"props":393,"children":394},{"style":123},[395],{"type":35,"value":396},"  --platform",{"type":30,"tag":95,"props":398,"children":399},{"style":107},[400],{"type":35,"value":401}," managed",{"type":30,"tag":95,"props":403,"children":404},{"style":123},[405],{"type":35,"value":371},{"type":30,"tag":95,"props":407,"children":408},{"class":97,"line":274},[409,414,419],{"type":30,"tag":95,"props":410,"children":411},{"style":123},[412],{"type":35,"value":413},"  --region",{"type":30,"tag":95,"props":415,"children":416},{"style":107},[417],{"type":35,"value":418}," europe-west1",{"type":30,"tag":95,"props":420,"children":421},{"style":123},[422],{"type":35,"value":371},{"type":30,"tag":95,"props":424,"children":425},{"class":97,"line":282},[426,431],{"type":30,"tag":95,"props":427,"children":428},{"style":123},[429],{"type":35,"value":430},"  --allow-unauthenticated",{"type":30,"tag":95,"props":432,"children":433},{"style":123},[434],{"type":35,"value":371},{"type":30,"tag":95,"props":436,"children":437},{"class":97,"line":291},[438,443],{"type":30,"tag":95,"props":439,"children":440},{"style":123},[441],{"type":35,"value":442},"  --set-env-vars",{"type":30,"tag":95,"props":444,"children":445},{"style":107},[446],{"type":35,"value":447}," CONTAINER_CONFIG=GTM-XXXXXX\n",{"type":30,"tag":31,"props":449,"children":450},{},[451,453,459],{"type":35,"value":452},"Para agregar un dominio personalizado al servicio de Cloud Run, ve a Cloud Run > Domain Mappings > Add Mapping. En tu proveedor DNS agrega un registro CNAME (",{"type":30,"tag":76,"props":454,"children":456},{"className":455},[],[457],{"type":35,"value":458},"sgtm.roibase.io",{"type":35,"value":460}," → URL de Cloud Run). El certificado SSL se aprovisiona automáticamente (Let's Encrypt).",{"type":30,"tag":462,"props":463,"children":465},"h3",{"id":464},"alternativa-cloudflare-workers",[466],{"type":35,"value":467},"Alternativa: Cloudflare Workers",{"type":30,"tag":31,"props":469,"children":470},{},[471],{"type":35,"value":472},"Si prefieres estar fuera del ecosistema de Google, Cloudflare Workers es más flexible. La imagen de contenedor de server-side GTM no corre en Workers pero puedes escribir un proxy de tagging personalizado en Workers. El siguiente script proxy todos los eventos GTM y los envía al Measurement Protocol de GA4:",{"type":30,"tag":85,"props":474,"children":478},{"className":475,"code":476,"language":477,"meta":14,"style":14},"language-javascript shiki shiki-themes github-dark","addEventListener('fetch', event => {\n  event.respondWith(handleRequest(event.request))\n})\n\nasync function handleRequest(request) {\n  const url = new URL(request.url)\n  if (url.pathname === '\u002Fgtm') {\n    const payload = await request.json()\n    const measurementId = 'G-XXXXXXXXXX'\n    const apiSecret = 'YOUR_API_SECRET'\n    \n    const response = await fetch(\n      `https:\u002F\u002Fwww.google-analytics.com\u002Fmp\u002Fcollect?measurement_id=${measurementId}&api_secret=${apiSecret}`,\n      {\n        method: 'POST',\n        body: JSON.stringify({\n          client_id: payload.client_id,\n          events: [{ name: payload.event_name, params: payload.event_params }]\n        })\n      }\n    )\n    return new Response('OK', { status: 200 })\n  }\n  return new Response('Not Found', { status: 404 })\n}\n","javascript",[479],{"type":30,"tag":76,"props":480,"children":481},{"__ignoreMap":14},[482,523,550,558,565,597,630,657,694,715,737,746,777,811,820,838,867,876,885,894,903,912,954,963,1002],{"type":30,"tag":95,"props":483,"children":484},{"class":97,"line":98},[485,490,496,501,506,512,518],{"type":30,"tag":95,"props":486,"children":487},{"style":102},[488],{"type":35,"value":489},"addEventListener",{"type":30,"tag":95,"props":491,"children":493},{"style":492},"--shiki-default:#E1E4E8",[494],{"type":35,"value":495},"(",{"type":30,"tag":95,"props":497,"children":498},{"style":107},[499],{"type":35,"value":500},"'fetch'",{"type":30,"tag":95,"props":502,"children":503},{"style":492},[504],{"type":35,"value":505},", ",{"type":30,"tag":95,"props":507,"children":509},{"style":508},"--shiki-default:#FFAB70",[510],{"type":35,"value":511},"event",{"type":30,"tag":95,"props":513,"children":515},{"style":514},"--shiki-default:#F97583",[516],{"type":35,"value":517}," =>",{"type":30,"tag":95,"props":519,"children":520},{"style":492},[521],{"type":35,"value":522}," {\n",{"type":30,"tag":95,"props":524,"children":525},{"class":97,"line":134},[526,531,536,540,545],{"type":30,"tag":95,"props":527,"children":528},{"style":492},[529],{"type":35,"value":530},"  event.",{"type":30,"tag":95,"props":532,"children":533},{"style":102},[534],{"type":35,"value":535},"respondWith",{"type":30,"tag":95,"props":537,"children":538},{"style":492},[539],{"type":35,"value":495},{"type":30,"tag":95,"props":541,"children":542},{"style":102},[543],{"type":35,"value":544},"handleRequest",{"type":30,"tag":95,"props":546,"children":547},{"style":492},[548],{"type":35,"value":549},"(event.request))\n",{"type":30,"tag":95,"props":551,"children":552},{"class":97,"line":162},[553],{"type":30,"tag":95,"props":554,"children":555},{"style":492},[556],{"type":35,"value":557},"})\n",{"type":30,"tag":95,"props":559,"children":560},{"class":97,"line":265},[561],{"type":30,"tag":95,"props":562,"children":563},{"emptyLinePlaceholder":251},[564],{"type":35,"value":254},{"type":30,"tag":95,"props":566,"children":567},{"class":97,"line":274},[568,573,578,583,587,592],{"type":30,"tag":95,"props":569,"children":570},{"style":514},[571],{"type":35,"value":572},"async",{"type":30,"tag":95,"props":574,"children":575},{"style":514},[576],{"type":35,"value":577}," function",{"type":30,"tag":95,"props":579,"children":580},{"style":102},[581],{"type":35,"value":582}," handleRequest",{"type":30,"tag":95,"props":584,"children":585},{"style":492},[586],{"type":35,"value":495},{"type":30,"tag":95,"props":588,"children":589},{"style":508},[590],{"type":35,"value":591},"request",{"type":30,"tag":95,"props":593,"children":594},{"style":492},[595],{"type":35,"value":596},") {\n",{"type":30,"tag":95,"props":598,"children":599},{"class":97,"line":282},[600,605,610,615,620,625],{"type":30,"tag":95,"props":601,"children":602},{"style":514},[603],{"type":35,"value":604},"  const",{"type":30,"tag":95,"props":606,"children":607},{"style":123},[608],{"type":35,"value":609}," url",{"type":30,"tag":95,"props":611,"children":612},{"style":514},[613],{"type":35,"value":614}," =",{"type":30,"tag":95,"props":616,"children":617},{"style":514},[618],{"type":35,"value":619}," new",{"type":30,"tag":95,"props":621,"children":622},{"style":102},[623],{"type":35,"value":624}," URL",{"type":30,"tag":95,"props":626,"children":627},{"style":492},[628],{"type":35,"value":629},"(request.url)\n",{"type":30,"tag":95,"props":631,"children":632},{"class":97,"line":291},[633,638,643,648,653],{"type":30,"tag":95,"props":634,"children":635},{"style":514},[636],{"type":35,"value":637},"  if",{"type":30,"tag":95,"props":639,"children":640},{"style":492},[641],{"type":35,"value":642}," (url.pathname ",{"type":30,"tag":95,"props":644,"children":645},{"style":514},[646],{"type":35,"value":647},"===",{"type":30,"tag":95,"props":649,"children":650},{"style":107},[651],{"type":35,"value":652}," '\u002Fgtm'",{"type":30,"tag":95,"props":654,"children":655},{"style":492},[656],{"type":35,"value":596},{"type":30,"tag":95,"props":658,"children":659},{"class":97,"line":299},[660,665,670,674,679,684,689],{"type":30,"tag":95,"props":661,"children":662},{"style":514},[663],{"type":35,"value":664},"    const",{"type":30,"tag":95,"props":666,"children":667},{"style":123},[668],{"type":35,"value":669}," payload",{"type":30,"tag":95,"props":671,"children":672},{"style":514},[673],{"type":35,"value":614},{"type":30,"tag":95,"props":675,"children":676},{"style":514},[677],{"type":35,"value":678}," await",{"type":30,"tag":95,"props":680,"children":681},{"style":492},[682],{"type":35,"value":683}," request.",{"type":30,"tag":95,"props":685,"children":686},{"style":102},[687],{"type":35,"value":688},"json",{"type":30,"tag":95,"props":690,"children":691},{"style":492},[692],{"type":35,"value":693},"()\n",{"type":30,"tag":95,"props":695,"children":696},{"class":97,"line":24},[697,701,706,710],{"type":30,"tag":95,"props":698,"children":699},{"style":514},[700],{"type":35,"value":664},{"type":30,"tag":95,"props":702,"children":703},{"style":123},[704],{"type":35,"value":705}," measurementId",{"type":30,"tag":95,"props":707,"children":708},{"style":514},[709],{"type":35,"value":614},{"type":30,"tag":95,"props":711,"children":712},{"style":107},[713],{"type":35,"value":714}," 'G-XXXXXXXXXX'\n",{"type":30,"tag":95,"props":716,"children":718},{"class":97,"line":717},10,[719,723,728,732],{"type":30,"tag":95,"props":720,"children":721},{"style":514},[722],{"type":35,"value":664},{"type":30,"tag":95,"props":724,"children":725},{"style":123},[726],{"type":35,"value":727}," apiSecret",{"type":30,"tag":95,"props":729,"children":730},{"style":514},[731],{"type":35,"value":614},{"type":30,"tag":95,"props":733,"children":734},{"style":107},[735],{"type":35,"value":736}," 'YOUR_API_SECRET'\n",{"type":30,"tag":95,"props":738,"children":740},{"class":97,"line":739},11,[741],{"type":30,"tag":95,"props":742,"children":743},{"style":492},[744],{"type":35,"value":745},"    \n",{"type":30,"tag":95,"props":747,"children":749},{"class":97,"line":748},12,[750,754,759,763,767,772],{"type":30,"tag":95,"props":751,"children":752},{"style":514},[753],{"type":35,"value":664},{"type":30,"tag":95,"props":755,"children":756},{"style":123},[757],{"type":35,"value":758}," response",{"type":30,"tag":95,"props":760,"children":761},{"style":514},[762],{"type":35,"value":614},{"type":30,"tag":95,"props":764,"children":765},{"style":514},[766],{"type":35,"value":678},{"type":30,"tag":95,"props":768,"children":769},{"style":102},[770],{"type":35,"value":771}," fetch",{"type":30,"tag":95,"props":773,"children":774},{"style":492},[775],{"type":35,"value":776},"(\n",{"type":30,"tag":95,"props":778,"children":780},{"class":97,"line":779},13,[781,786,791,796,801,806],{"type":30,"tag":95,"props":782,"children":783},{"style":107},[784],{"type":35,"value":785},"      `https:\u002F\u002Fwww.google-analytics.com\u002Fmp\u002Fcollect?measurement_id=${",{"type":30,"tag":95,"props":787,"children":788},{"style":492},[789],{"type":35,"value":790},"measurementId",{"type":30,"tag":95,"props":792,"children":793},{"style":107},[794],{"type":35,"value":795},"}&api_secret=${",{"type":30,"tag":95,"props":797,"children":798},{"style":492},[799],{"type":35,"value":800},"apiSecret",{"type":30,"tag":95,"props":802,"children":803},{"style":107},[804],{"type":35,"value":805},"}`",{"type":30,"tag":95,"props":807,"children":808},{"style":492},[809],{"type":35,"value":810},",\n",{"type":30,"tag":95,"props":812,"children":814},{"class":97,"line":813},14,[815],{"type":30,"tag":95,"props":816,"children":817},{"style":492},[818],{"type":35,"value":819},"      {\n",{"type":30,"tag":95,"props":821,"children":823},{"class":97,"line":822},15,[824,829,834],{"type":30,"tag":95,"props":825,"children":826},{"style":492},[827],{"type":35,"value":828},"        method: ",{"type":30,"tag":95,"props":830,"children":831},{"style":107},[832],{"type":35,"value":833},"'POST'",{"type":30,"tag":95,"props":835,"children":836},{"style":492},[837],{"type":35,"value":810},{"type":30,"tag":95,"props":839,"children":841},{"class":97,"line":840},16,[842,847,852,857,862],{"type":30,"tag":95,"props":843,"children":844},{"style":492},[845],{"type":35,"value":846},"        body: ",{"type":30,"tag":95,"props":848,"children":849},{"style":123},[850],{"type":35,"value":851},"JSON",{"type":30,"tag":95,"props":853,"children":854},{"style":492},[855],{"type":35,"value":856},".",{"type":30,"tag":95,"props":858,"children":859},{"style":102},[860],{"type":35,"value":861},"stringify",{"type":30,"tag":95,"props":863,"children":864},{"style":492},[865],{"type":35,"value":866},"({\n",{"type":30,"tag":95,"props":868,"children":870},{"class":97,"line":869},17,[871],{"type":30,"tag":95,"props":872,"children":873},{"style":492},[874],{"type":35,"value":875},"          client_id: payload.client_id,\n",{"type":30,"tag":95,"props":877,"children":879},{"class":97,"line":878},18,[880],{"type":30,"tag":95,"props":881,"children":882},{"style":492},[883],{"type":35,"value":884},"          events: [{ name: payload.event_name, params: payload.event_params }]\n",{"type":30,"tag":95,"props":886,"children":888},{"class":97,"line":887},19,[889],{"type":30,"tag":95,"props":890,"children":891},{"style":492},[892],{"type":35,"value":893},"        })\n",{"type":30,"tag":95,"props":895,"children":897},{"class":97,"line":896},20,[898],{"type":30,"tag":95,"props":899,"children":900},{"style":492},[901],{"type":35,"value":902},"      }\n",{"type":30,"tag":95,"props":904,"children":906},{"class":97,"line":905},21,[907],{"type":30,"tag":95,"props":908,"children":909},{"style":492},[910],{"type":35,"value":911},"    )\n",{"type":30,"tag":95,"props":913,"children":915},{"class":97,"line":914},22,[916,921,925,930,934,939,944,949],{"type":30,"tag":95,"props":917,"children":918},{"style":514},[919],{"type":35,"value":920},"    return",{"type":30,"tag":95,"props":922,"children":923},{"style":514},[924],{"type":35,"value":619},{"type":30,"tag":95,"props":926,"children":927},{"style":102},[928],{"type":35,"value":929}," Response",{"type":30,"tag":95,"props":931,"children":932},{"style":492},[933],{"type":35,"value":495},{"type":30,"tag":95,"props":935,"children":936},{"style":107},[937],{"type":35,"value":938},"'OK'",{"type":30,"tag":95,"props":940,"children":941},{"style":492},[942],{"type":35,"value":943},", { status: ",{"type":30,"tag":95,"props":945,"children":946},{"style":123},[947],{"type":35,"value":948},"200",{"type":30,"tag":95,"props":950,"children":951},{"style":492},[952],{"type":35,"value":953}," })\n",{"type":30,"tag":95,"props":955,"children":957},{"class":97,"line":956},23,[958],{"type":30,"tag":95,"props":959,"children":960},{"style":492},[961],{"type":35,"value":962},"  }\n",{"type":30,"tag":95,"props":964,"children":966},{"class":97,"line":965},24,[967,972,976,980,984,989,993,998],{"type":30,"tag":95,"props":968,"children":969},{"style":514},[970],{"type":35,"value":971},"  return",{"type":30,"tag":95,"props":973,"children":974},{"style":514},[975],{"type":35,"value":619},{"type":30,"tag":95,"props":977,"children":978},{"style":102},[979],{"type":35,"value":929},{"type":30,"tag":95,"props":981,"children":982},{"style":492},[983],{"type":35,"value":495},{"type":30,"tag":95,"props":985,"children":986},{"style":107},[987],{"type":35,"value":988},"'Not Found'",{"type":30,"tag":95,"props":990,"children":991},{"style":492},[992],{"type":35,"value":943},{"type":30,"tag":95,"props":994,"children":995},{"style":123},[996],{"type":35,"value":997},"404",{"type":30,"tag":95,"props":999,"children":1000},{"style":492},[1001],{"type":35,"value":953},{"type":30,"tag":95,"props":1003,"children":1005},{"class":97,"line":1004},25,[1006],{"type":30,"tag":95,"props":1007,"children":1008},{"style":492},[1009],{"type":35,"value":1010},"}\n",{"type":30,"tag":31,"props":1012,"children":1013},{},[1014],{"type":35,"value":1015},"El runtime de Workers inicia en menos de 50ms, Cloud Run tiene cold start de 2-3 segundos. Pero en Workers no tienes el Visual Tag Builder de GTM — necesitas escribir cada tag de plataforma como código. Cloud Run por ahora es más práctico.",{"type":30,"tag":38,"props":1017,"children":1019},{"id":1018},"deduplicación-de-eventos-no-contar-dos-veces-la-misma-conversión",[1020],{"type":35,"value":1021},"Deduplicación de Eventos: No Contar Dos Veces la Misma Conversión",{"type":30,"tag":31,"props":1023,"children":1024},{},[1025],{"type":35,"value":1026},"Al migrar a tagging server-side, el contenedor web y el servidor trabajan en paralelo. El visitante realiza una compra → el píxel de Facebook client-side se dispara → el contenedor server-side también recibe el evento de purchase → la API de Facebook ve la misma conversión dos veces. El ROAS sube 200%, el optimizer de presupuesto recibe señal falsa.",{"type":30,"tag":31,"props":1028,"children":1029},{},[1030,1032,1038,1040,1045],{"type":35,"value":1031},"La solución es deduplicación de eventos. Asigna a cada conversión un ",{"type":30,"tag":76,"props":1033,"children":1035},{"className":1034},[],[1036],{"type":35,"value":1037},"event_id",{"type":35,"value":1039}," único, que cliente y servidor envíen el mismo ID. Facebook ignora el segundo evento con el mismo ",{"type":30,"tag":76,"props":1041,"children":1043},{"className":1042},[],[1044],{"type":35,"value":1037},{"type":35,"value":1046},". La ventana de deduplicación es 48 horas (por defecto).",{"type":30,"tag":31,"props":1048,"children":1049},{},[1050,1052,1057],{"type":35,"value":1051},"En el contenedor web de GTM, agrega el parámetro ",{"type":30,"tag":76,"props":1053,"children":1055},{"className":1054},[],[1056],{"type":35,"value":1037},{"type":35,"value":1058}," a la configuración del tag de Facebook:",{"type":30,"tag":85,"props":1060,"children":1062},{"className":475,"code":1061,"language":477,"meta":14,"style":14},"fbq('track', 'Purchase', {\n  value: 99.99,\n  currency: 'TRY'\n}, {\n  eventID: '{{Transaction ID}}_{{Random Number}}'\n});\n",[1063],{"type":30,"tag":76,"props":1064,"children":1065},{"__ignoreMap":14},[1066,1097,1114,1127,1135,1148],{"type":30,"tag":95,"props":1067,"children":1068},{"class":97,"line":98},[1069,1074,1078,1083,1087,1092],{"type":30,"tag":95,"props":1070,"children":1071},{"style":102},[1072],{"type":35,"value":1073},"fbq",{"type":30,"tag":95,"props":1075,"children":1076},{"style":492},[1077],{"type":35,"value":495},{"type":30,"tag":95,"props":1079,"children":1080},{"style":107},[1081],{"type":35,"value":1082},"'track'",{"type":30,"tag":95,"props":1084,"children":1085},{"style":492},[1086],{"type":35,"value":505},{"type":30,"tag":95,"props":1088,"children":1089},{"style":107},[1090],{"type":35,"value":1091},"'Purchase'",{"type":30,"tag":95,"props":1093,"children":1094},{"style":492},[1095],{"type":35,"value":1096},", {\n",{"type":30,"tag":95,"props":1098,"children":1099},{"class":97,"line":134},[1100,1105,1110],{"type":30,"tag":95,"props":1101,"children":1102},{"style":492},[1103],{"type":35,"value":1104},"  value: ",{"type":30,"tag":95,"props":1106,"children":1107},{"style":123},[1108],{"type":35,"value":1109},"99.99",{"type":30,"tag":95,"props":1111,"children":1112},{"style":492},[1113],{"type":35,"value":810},{"type":30,"tag":95,"props":1115,"children":1116},{"class":97,"line":162},[1117,1122],{"type":30,"tag":95,"props":1118,"children":1119},{"style":492},[1120],{"type":35,"value":1121},"  currency: ",{"type":30,"tag":95,"props":1123,"children":1124},{"style":107},[1125],{"type":35,"value":1126},"'TRY'\n",{"type":30,"tag":95,"props":1128,"children":1129},{"class":97,"line":265},[1130],{"type":30,"tag":95,"props":1131,"children":1132},{"style":492},[1133],{"type":35,"value":1134},"}, {\n",{"type":30,"tag":95,"props":1136,"children":1137},{"class":97,"line":274},[1138,1143],{"type":30,"tag":95,"props":1139,"children":1140},{"style":492},[1141],{"type":35,"value":1142},"  eventID: ",{"type":30,"tag":95,"props":1144,"children":1145},{"style":107},[1146],{"type":35,"value":1147},"'{{Transaction ID}}_{{Random Number}}'\n",{"type":30,"tag":95,"props":1149,"children":1150},{"class":97,"line":282},[1151],{"type":30,"tag":95,"props":1152,"children":1153},{"style":492},[1154],{"type":35,"value":1155},"});\n",{"type":30,"tag":31,"props":1157,"children":1158},{},[1159,1161,1166,1168,1174,1176,1181,1183,1189],{"type":35,"value":1160},"En el contenedor server-side, en el tag de Meta Conversion API, mapea el mismo ",{"type":30,"tag":76,"props":1162,"children":1164},{"className":1163},[],[1165],{"type":35,"value":1037},{"type":35,"value":1167}," como variable definida por el usuario. GTM no tiene una variable ",{"type":30,"tag":76,"props":1169,"children":1171},{"className":1170},[],[1172],{"type":35,"value":1173},"Event ID",{"type":35,"value":1175}," integrada, necesitas crear una manualmente. Elige tipo variable Data Layer, nombre de variable ",{"type":30,"tag":76,"props":1177,"children":1179},{"className":1178},[],[1180],{"type":35,"value":1037},{"type":35,"value":1182},", valor por defecto ",{"type":30,"tag":76,"props":1184,"children":1186},{"className":1185},[],[1187],{"type":35,"value":1188},"{{Page Path}}_{{Random Number}}",{"type":35,"value":856},{"type":30,"tag":31,"props":1191,"children":1192},{},[1193,1195,1201,1203,1209,1211,1216,1218,1223,1225,1230,1232,1238],{"type":35,"value":1194},"Para Google Analytics 4 la situación es diferente. GA4 ya fusiona eventos client-side y Measurement Protocol (si el ",{"type":30,"tag":76,"props":1196,"children":1198},{"className":1197},[],[1199],{"type":35,"value":1200},"client_id",{"type":35,"value":1202}," y ",{"type":30,"tag":76,"props":1204,"children":1206},{"className":1205},[],[1207],{"type":35,"value":1208},"session_id",{"type":35,"value":1210}," son iguales). Sin deduplicación adicional, pero la consistencia de ",{"type":30,"tag":76,"props":1212,"children":1214},{"className":1213},[],[1215],{"type":35,"value":1200},{"type":35,"value":1217}," es obligatoria. En el contenedor web, en la configuración del tag de GA4, selecciona ",{"type":30,"tag":194,"props":1219,"children":1220},{},[1221],{"type":35,"value":1222},"Enviar datos proporcionados por el usuario",{"type":35,"value":1224},", en el field ",{"type":30,"tag":76,"props":1226,"children":1228},{"className":1227},[],[1229],{"type":35,"value":1200},{"type":35,"value":1231}," usa la variable GTM ",{"type":30,"tag":76,"props":1233,"children":1235},{"className":1234},[],[1236],{"type":35,"value":1237},"{{GA Client ID}}",{"type":35,"value":1239},". En el contenedor del servidor usa el mismo valor.",{"type":30,"tag":31,"props":1241,"children":1242},{},[1243,1245,1251,1253,1258,1259,1264],{"type":35,"value":1244},"Antes de llevar esta lógica a producción, pruébala en Preview mode. En el contenedor server GTM crea una URL de Preview, desde el contenedor web apunta a esa URL. En Chrome DevTools > pestañas Network, inspecciona las solicitudes POST al endpoint ",{"type":30,"tag":76,"props":1246,"children":1248},{"className":1247},[],[1249],{"type":35,"value":1250},"\u002Fgtm",{"type":35,"value":1252}," — los fields ",{"type":30,"tag":76,"props":1254,"children":1256},{"className":1255},[],[1257],{"type":35,"value":1037},{"type":35,"value":1202},{"type":30,"tag":76,"props":1260,"children":1262},{"className":1261},[],[1263],{"type":35,"value":1200},{"type":35,"value":1265}," deben estar tanto en el payload del cliente como del servidor.",{"type":30,"tag":38,"props":1267,"children":1269},{"id":1268},"first-party-cookie-y-session-stitching",[1270],{"type":35,"value":1271},"First-Party Cookie y Session Stitching",{"type":30,"tag":31,"props":1273,"children":1274},{},[1275,1277,1283,1285,1291,1293,1299],{"type":35,"value":1276},"La potencia de la medición server-side reside en fijar la identidad del usuario a través de first-party cookies. El contenedor web mantiene ",{"type":30,"tag":76,"props":1278,"children":1280},{"className":1279},[],[1281],{"type":35,"value":1282},"_ga",{"type":35,"value":1284}," durante 2 años pero Safari la reduce a 7 días. El contenedor server-side puede establecer su propia cookie (",{"type":30,"tag":76,"props":1286,"children":1288},{"className":1287},[],[1289],{"type":35,"value":1290},"_sgtm",{"type":35,"value":1292}," por ejemplo) usando el header ",{"type":30,"tag":76,"props":1294,"children":1296},{"className":1295},[],[1297],{"type":35,"value":1298},"Set-Cookie",{"type":35,"value":1300}," — como coincide el subdominio, evita ITP.",{"type":30,"tag":31,"props":1302,"children":1303},{},[1304,1306,1311,1313,1318,1320,1325,1327,1332],{"type":35,"value":1305},"En el contenedor server GTM, bajo la sección ",{"type":30,"tag":194,"props":1307,"children":1308},{},[1309],{"type":35,"value":1310},"Client",{"type":35,"value":1312},", selecciona el tipo de cliente ",{"type":30,"tag":194,"props":1314,"children":1315},{},[1316],{"type":35,"value":1317},"Google Analytics: GA4",{"type":35,"value":1319},". Este cliente extrae ",{"type":30,"tag":76,"props":1321,"children":1323},{"className":1322},[],[1324],{"type":35,"value":1200},{"type":35,"value":1326}," de la solicitud HTTP entrante y lo escribe en la cookie ",{"type":30,"tag":76,"props":1328,"children":1330},{"className":1329},[],[1331],{"type":35,"value":1282},{"type":35,"value":1333},". Pero esta cookie se agrega al header de respuesta, no al navegador — para que el navegador la vea, necesitas redireccionamiento GET desde el contenedor web al servidor en lugar de POST (complicado).",{"type":30,"tag":31,"props":1335,"children":1336},{},[1337,1339,1344,1346,1352],{"type":35,"value":1338},"Método más simple: agrega ",{"type":30,"tag":76,"props":1340,"children":1342},{"className":1341},[],[1343],{"type":35,"value":1200},{"type":35,"value":1345}," a DataLayer en el contenedor web, el contenedor del servidor lo recibe y lo almacena en tu propia base de datos. Por ejemplo, tabla ",{"type":30,"tag":76,"props":1347,"children":1349},{"className":1348},[],[1350],{"type":35,"value":1351},"user_sessions",{"type":35,"value":1353}," en BigQuery:",{"type":30,"tag":85,"props":1355,"children":1359},{"className":1356,"code":1357,"language":1358,"meta":14,"style":14},"language-sql shiki shiki-themes github-dark","CREATE TABLE analytics.user_sessions (\n  client_id STRING,\n  session_id STRING,\n  first_visit_timestamp TIMESTAMP,\n  last_event_timestamp TIMESTAMP,\n  device_category STRING,\n  geo_country STRING\n);\n","sql",[1360],{"type":30,"tag":76,"props":1361,"children":1362},{"__ignoreMap":14},[1363,1386,1394,1402,1419,1435,1443,1451],{"type":30,"tag":95,"props":1364,"children":1365},{"class":97,"line":98},[1366,1371,1376,1381],{"type":30,"tag":95,"props":1367,"children":1368},{"style":514},[1369],{"type":35,"value":1370},"CREATE",{"type":30,"tag":95,"props":1372,"children":1373},{"style":514},[1374],{"type":35,"value":1375}," TABLE",{"type":30,"tag":95,"props":1377,"children":1378},{"style":102},[1379],{"type":35,"value":1380}," analytics",{"type":30,"tag":95,"props":1382,"children":1383},{"style":492},[1384],{"type":35,"value":1385},".user_sessions (\n",{"type":30,"tag":95,"props":1387,"children":1388},{"class":97,"line":134},[1389],{"type":30,"tag":95,"props":1390,"children":1391},{"style":492},[1392],{"type":35,"value":1393},"  client_id STRING,\n",{"type":30,"tag":95,"props":1395,"children":1396},{"class":97,"line":162},[1397],{"type":30,"tag":95,"props":1398,"children":1399},{"style":492},[1400],{"type":35,"value":1401},"  session_id STRING,\n",{"type":30,"tag":95,"props":1403,"children":1404},{"class":97,"line":265},[1405,1410,1415],{"type":30,"tag":95,"props":1406,"children":1407},{"style":492},[1408],{"type":35,"value":1409},"  first_visit_timestamp ",{"type":30,"tag":95,"props":1411,"children":1412},{"style":514},[1413],{"type":35,"value":1414},"TIMESTAMP",{"type":30,"tag":95,"props":1416,"children":1417},{"style":492},[1418],{"type":35,"value":810},{"type":30,"tag":95,"props":1420,"children":1421},{"class":97,"line":274},[1422,1427,1431],{"type":30,"tag":95,"props":1423,"children":1424},{"style":492},[1425],{"type":35,"value":1426},"  last_event_timestamp ",{"type":30,"tag":95,"props":1428,"children":1429},{"style":514},[1430],{"type":35,"value":1414},{"type":30,"tag":95,"props":1432,"children":1433},{"style":492},[1434],{"type":35,"value":810},{"type":30,"tag":95,"props":1436,"children":1437},{"class":97,"line":282},[1438],{"type":30,"tag":95,"props":1439,"children":1440},{"style":492},[1441],{"type":35,"value":1442},"  device_category STRING,\n",{"type":30,"tag":95,"props":1444,"children":1445},{"class":97,"line":291},[1446],{"type":30,"tag":95,"props":1447,"children":1448},{"style":492},[1449],{"type":35,"value":1450},"  geo_country STRING\n",{"type":30,"tag":95,"props":1452,"children":1453},{"class":97,"line":299},[1454],{"type":30,"tag":95,"props":1455,"children":1456},{"style":492},[1457],{"type":35,"value":1458},");\n",{"type":30,"tag":31,"props":1460,"children":1461},{},[1462,1464,1469,1471,1480],{"type":35,"value":1463},"Cada evento server-side que llega, MERGE a esta tabla. Si el mismo ",{"type":30,"tag":76,"props":1465,"children":1467},{"className":1466},[],[1468],{"type":35,"value":1200},{"type":35,"value":1470}," aparece en diferentes sesiones, puedes hacer resolución de identidad — ",{"type":30,"tag":1472,"props":1473,"children":1477},"a",{"href":1474,"rel":1475},"https:\u002F\u002Fwww.roibase.com.tr\u002Fes\u002Ffirstparty",[1476],"nofollow",[1478],{"type":35,"value":1479},"First-Party Veri & Medición Arquitectura",{"type":35,"value":1481}," profundiza en el diseño de esquema necesario para este tipo de stitching cross-session.",{"type":30,"tag":462,"props":1483,"children":1485},{"id":1484},"user-agent-client-hints-e-ip-enrichment",[1486],{"type":35,"value":1487},"User-Agent Client Hints e IP Enrichment",{"type":30,"tag":31,"props":1489,"children":1490},{},[1491,1493,1498],{"type":35,"value":1492},"El contenedor server-side obtiene user agent e IP de los headers de solicitud del cliente. Pero con Chrome 110+ el string User-Agent está congelado — la información detallada de navegador\u002FSO ahora está en ",{"type":30,"tag":194,"props":1494,"children":1495},{},[1496],{"type":35,"value":1497},"User-Agent Client Hints",{"type":35,"value":1499}," (UA-CH). En el contenedor del servidor necesitas parsear estos hints.",{"type":30,"tag":31,"props":1501,"children":1502},{},[1503],{"type":35,"value":1504},"En el contenedor server GTM, define una variable JavaScript personalizada:",{"type":30,"tag":85,"props":1506,"children":1508},{"className":475,"code":1507,"language":477,"meta":14,"style":14},"function() {\n  const headers = getAllEventData().headers || {};\n  const uach = {\n    brand: headers['sec-ch-ua'],\n    mobile: headers['sec-ch-ua-mobile'],\n    platform: headers['sec-ch-ua-platform']\n  };\n  return uach;\n}\n",[1509],{"type":30,"tag":76,"props":1510,"children":1511},{"__ignoreMap":14},[1512,1525,1561,1581,1599,1616,1634,1642,1654],{"type":30,"tag":95,"props":1513,"children":1514},{"class":97,"line":98},[1515,1520],{"type":30,"tag":95,"props":1516,"children":1517},{"style":514},[1518],{"type":35,"value":1519},"function",{"type":30,"tag":95,"props":1521,"children":1522},{"style":492},[1523],{"type":35,"value":1524},"() {\n",{"type":30,"tag":95,"props":1526,"children":1527},{"class":97,"line":134},[1528,1532,1537,1541,1546,1551,1556],{"type":30,"tag":95,"props":1529,"children":1530},{"style":514},[1531],{"type":35,"value":604},{"type":30,"tag":95,"props":1533,"children":1534},{"style":123},[1535],{"type":35,"value":1536}," headers",{"type":30,"tag":95,"props":1538,"children":1539},{"style":514},[1540],{"type":35,"value":614},{"type":30,"tag":95,"props":1542,"children":1543},{"style":102},[1544],{"type":35,"value":1545}," getAllEventData",{"type":30,"tag":95,"props":1547,"children":1548},{"style":492},[1549],{"type":35,"value":1550},"().headers ",{"type":30,"tag":95,"props":1552,"children":1553},{"style":514},[1554],{"type":35,"value":1555},"||",{"type":30,"tag":95,"props":1557,"children":1558},{"style":492},[1559],{"type":35,"value":1560}," {};\n",{"type":30,"tag":95,"props":1562,"children":1563},{"class":97,"line":162},[1564,1568,1573,1577],{"type":30,"tag":95,"props":1565,"children":1566},{"style":514},[1567],{"type":35,"value":604},{"type":30,"tag":95,"props":1569,"children":1570},{"style":123},[1571],{"type":35,"value":1572}," uach",{"type":30,"tag":95,"props":1574,"children":1575},{"style":514},[1576],{"type":35,"value":614},{"type":30,"tag":95,"props":1578,"children":1579},{"style":492},[1580],{"type":35,"value":522},{"type":30,"tag":95,"props":1582,"children":1583},{"class":97,"line":265},[1584,1589,1594],{"type":30,"tag":95,"props":1585,"children":1586},{"style":492},[1587],{"type":35,"value":1588},"    brand: headers[",{"type":30,"tag":95,"props":1590,"children":1591},{"style":107},[1592],{"type":35,"value":1593},"'sec-ch-ua'",{"type":30,"tag":95,"props":1595,"children":1596},{"style":492},[1597],{"type":35,"value":1598},"],\n",{"type":30,"tag":95,"props":1600,"children":1601},{"class":97,"line":274},[1602,1607,1612],{"type":30,"tag":95,"props":1603,"children":1604},{"style":492},[1605],{"type":35,"value":1606},"    mobile: headers[",{"type":30,"tag":95,"props":1608,"children":1609},{"style":107},[1610],{"type":35,"value":1611},"'sec-ch-ua-mobile'",{"type":30,"tag":95,"props":1613,"children":1614},{"style":492},[1615],{"type":35,"value":1598},{"type":30,"tag":95,"props":1617,"children":1618},{"class":97,"line":282},[1619,1624,1629],{"type":30,"tag":95,"props":1620,"children":1621},{"style":492},[1622],{"type":35,"value":1623},"    platform: headers[",{"type":30,"tag":95,"props":1625,"children":1626},{"style":107},[1627],{"type":35,"value":1628},"'sec-ch-ua-platform'",{"type":30,"tag":95,"props":1630,"children":1631},{"style":492},[1632],{"type":35,"value":1633},"]\n",{"type":30,"tag":95,"props":1635,"children":1636},{"class":97,"line":291},[1637],{"type":30,"tag":95,"props":1638,"children":1639},{"style":492},[1640],{"type":35,"value":1641},"  };\n",{"type":30,"tag":95,"props":1643,"children":1644},{"class":97,"line":299},[1645,1649],{"type":30,"tag":95,"props":1646,"children":1647},{"style":514},[1648],{"type":35,"value":971},{"type":30,"tag":95,"props":1650,"children":1651},{"style":492},[1652],{"type":35,"value":1653}," uach;\n",{"type":30,"tag":95,"props":1655,"children":1656},{"class":97,"line":24},[1657],{"type":30,"tag":95,"props":1658,"children":1659},{"style":492},[1660],{"type":35,"value":1010},{"type":30,"tag":31,"props":1662,"children":1663},{},[1664,1666,1672],{"type":35,"value":1665},"Envía estos datos al field ",{"type":30,"tag":76,"props":1667,"children":1669},{"className":1668},[],[1670],{"type":35,"value":1671},"user_data.client_user_agent",{"type":35,"value":1673}," de Meta Conversion API. Para IP enrichment usa la base de datos MaxMind GeoIP2 (móntala en la instancia de Cloud Run). Alternativa: API de geolocalización IP integrada de Google Cloud (de pago).",{"type":30,"tag":38,"props":1675,"children":1677},{"id":1676},"checklist-de-producción-rate-limit-monitoring-fallback",[1678],{"type":35,"value":1679},"Checklist de Producción: Rate Limit, Monitoring, Fallback",{"type":30,"tag":31,"props":1681,"children":1682},{},[1683],{"type":35,"value":1684},"Antes de llevar el contenedor server-side a producción, estos controles son obligatorios:",{"type":30,"tag":31,"props":1686,"children":1687},{},[1688,1693,1695,1699,1701,1707],{"type":30,"tag":194,"props":1689,"children":1690},{},[1691],{"type":35,"value":1692},"1. Rate limiting:",{"type":35,"value":1694}," Las APIs de plataforma establecen límites máximos de solicitudes por segundo (Meta Conversion API 200 req\u002Fs, GA4 Measurement Protocol 1000 req\u002Fs). En la configuración del ",{"type":30,"tag":194,"props":1696,"children":1697},{},[1698],{"type":35,"value":1310},{"type":35,"value":1700}," del contenedor GTM, establece el valor throttle. Limita el número máximo de instancias de Cloud Run (",{"type":30,"tag":76,"props":1702,"children":1704},{"className":1703},[],[1705],{"type":35,"value":1706},"--max-instances 5",{"type":35,"value":1708},").",{"type":30,"tag":31,"props":1710,"children":1711},{},[1712,1717],{"type":30,"tag":194,"props":1713,"children":1714},{},[1715],{"type":35,"value":1716},"2. Error handling y retry:",{"type":35,"value":1718}," Si un tag server-side recibe HTTP 500, implementa lógica de reintentos. GTM no tiene retry integrado — necesitas escribir una plantilla de tag personalizada. Cuando Meta API devuelve 429 (Too Many Requests), aplica backoff exponencial.",{"type":30,"tag":31,"props":1720,"children":1721},{},[1722,1727,1729,1735],{"type":30,"tag":194,"props":1723,"children":1724},{},[1725],{"type":35,"value":1726},"3. Monitoring:",{"type":35,"value":1728}," Los logs de Cloud Run van a Stackdriver. Con ",{"type":30,"tag":76,"props":1730,"children":1732},{"className":1731},[],[1733],{"type":35,"value":1734},"gcloud logging read",{"type":35,"value":1736}," busca patrones de error. Métricas críticas: latencia de solicitud (p95 \u003C 500ms), tasa de error (\u003C 1%), uso de memoria del contenedor (512MB por defecto, 1GB ideal).",{"type":30,"tag":31,"props":1738,"children":1739},{},[1740,1745],{"type":30,"tag":194,"props":1741,"children":1742},{},[1743],{"type":35,"value":1744},"4. Mecanismo de fallback:",{"type":35,"value":1746}," Si el contenedor del servidor cae, el contenedor web sigue enviando píxeles. Pero los eventos solo servidor (conversiones backend) se pierden. Para fallback, escribe eventos a Pub\u002FSub, reproduce desde la dead-letter queue.",{"type":30,"tag":31,"props":1748,"children":1749},{},[1750,1755,1757,1763],{"type":30,"tag":194,"props":1751,"children":1752},{},[1753],{"type":35,"value":1754},"5. Integración Consent Mode v2:",{"type":35,"value":1756}," El contenedor server GTM no puede leer las señales de CMP (corre client-side). En el contenedor web, escribe el estado de consentimiento a DataLayer (",{"type":30,"tag":76,"props":1758,"children":1760},{"className":1759},[],[1761],{"type":35,"value":1762},"ad_storage: 'denied'",{"type":35,"value":1764},"), el contenedor del servidor lo lee y ejecuta tags de plataforma de forma condicional.",{"type":30,"tag":31,"props":1766,"children":1767},{},[1768],{"type":35,"value":1769},"Métricas de la primera semana en producción:",{"type":30,"tag":1771,"props":1772,"children":1773},"table",{},[1774,1798],{"type":30,"tag":1775,"props":1776,"children":1777},"thead",{},[1778],{"type":30,"tag":1779,"props":1780,"children":1781},"tr",{},[1782,1788,1793],{"type":30,"tag":1783,"props":1784,"children":1785},"th",{},[1786],{"type":35,"value":1787},"Métrica",{"type":30,"tag":1783,"props":1789,"children":1790},{},[1791],{"type":35,"value":1792},"Objetivo",{"type":30,"tag":1783,"props":1794,"children":1795},{},[1796],{"type":35,"value":1797},"Monitoreo",{"type":30,"tag":1799,"props":1800,"children":1801},"tbody",{},[1802,1821,1839,1857],{"type":30,"tag":1779,"props":1803,"children":1804},{},[1805,1811,1816],{"type":30,"tag":1806,"props":1807,"children":1808},"td",{},[1809],{"type":35,"value":1810},"Event delivery rate",{"type":30,"tag":1806,"props":1812,"children":1813},{},[1814],{"type":35,"value":1815},"> 98%",{"type":30,"tag":1806,"props":1817,"children":1818},{},[1819],{"type":35,"value":1820},"Logs de Cloud Run",{"type":30,"tag":1779,"props":1822,"children":1823},{},[1824,1829,1834],{"type":30,"tag":1806,"props":1825,"children":1826},{},[1827],{"type":35,"value":1828},"Deduplication accuracy",{"type":30,"tag":1806,"props":1830,"children":1831},{},[1832],{"type":35,"value":1833},"\u003C 2% duplicate",{"type":30,"tag":1806,"props":1835,"children":1836},{},[1837],{"type":35,"value":1838},"Dashboards de plataforma",{"type":30,"tag":1779,"props":1840,"children":1841},{},[1842,1847,1852],{"type":30,"tag":1806,"props":1843,"children":1844},{},[1845],{"type":35,"value":1846},"Latency p95",{"type":30,"tag":1806,"props":1848,"children":1849},{},[1850],{"type":35,"value":1851},"\u003C 500ms",{"type":30,"tag":1806,"props":1853,"children":1854},{},[1855],{"type":35,"value":1856},"Cloud Monitoring",{"type":30,"tag":1779,"props":1858,"children":1859},{},[1860,1865,1870],{"type":30,"tag":1806,"props":1861,"children":1862},{},[1863],{"type":35,"value":1864},"Cost per 1M events",{"type":30,"tag":1806,"props":1866,"children":1867},{},[1868],{"type":35,"value":1869},"\u003C $5",{"type":30,"tag":1806,"props":1871,"children":1872},{},[1873],{"type":35,"value":1874},"GCP Billing",{"type":30,"tag":38,"props":1876,"children":1878},{"id":1877},"qué-hacer-ahora",[1879],{"type":35,"value":1880},"Qué Hacer Ahora",{"type":30,"tag":31,"props":1882,"children":1883},{},[1884],{"type":35,"value":1885},"La infraestructura de server-side GTM se configura una vez, se optimiza continuamente. El primer paso es auditar tu contenedor web actual — qué tags deben permanecer client-side (herramientas A\u002FB test), cuáles pueden migrarse al servidor (analytics, conversion tracking). El siguiente paso es validar deduplicación en ambiente de prueba — en producción no se acepta tasa de duplicados > 2%. El deployment en Cloud Run es suficiente al inicio pero si el volumen de eventos supera 50 millones mensuales, un cluster GKE es más eficiente en costos. Server-side measurement ya no es opcional — es infraestructura obligatoria para atribución confiable.",{"type":30,"tag":1887,"props":1888,"children":1889},"style",{},[1890],{"type":35,"value":1891},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":14,"searchDepth":162,"depth":162,"links":1893},[1894,1895,1898,1899,1902,1903],{"id":40,"depth":134,"text":43},{"id":61,"depth":134,"text":64,"children":1896},[1897],{"id":464,"depth":162,"text":467},{"id":1018,"depth":134,"text":1021},{"id":1268,"depth":134,"text":1271,"children":1900},[1901],{"id":1484,"depth":162,"text":1487},{"id":1676,"depth":134,"text":1679},{"id":1877,"depth":134,"text":1880},"markdown","content:es:data:servidor-sgtm-conversion-api-produccion.md","content","es\u002Fdata\u002Fservidor-sgtm-conversion-api-produccion.md","es\u002Fdata\u002Fservidor-sgtm-conversion-api-produccion","md",1785247481548]