# Atribución de anuncios

Conserva el clic en el anuncio que trajo a un cliente hasta el trato en tu CRM y de vuelta a Google Ads

> Full REST + WebSocket API reference: https://api.happ.tools/reference

Un visitante hace clic en tu anuncio, lee un par de páginas, abre el chat y deja una solicitud. Tu CRM recibe el trato, pero sin nada que diga qué campaña pagó esa visita. Ahora Happ lleva el clic por toda la cadena: página → chat → trato → de vuelta a la red publicitaria.

No hay nada que activar. Cualquier widget cargado con el snippet de inserción actual empieza a recopilar en su siguiente vista de página.

## Qué se recopila [#what-gets-collected]

En la primera página del visitante, el script de inserción lee los parámetros del anuncio de la URL y los guarda en tu propio dominio:

| Grupo                | Parámetros                                                                      |
| -------------------- | ------------------------------------------------------------------------------- |
| Google               | `gclid`, `gbraid`, `wbraid`                                                     |
| Meta                 | `fbclid`                                                                        |
| TikTok, Microsoft    | `ttclid`, `msclkid`                                                             |
| Etiquetas de campaña | `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `utm_id` |

También guarda la página de aterrizaje y el referrer.

Se guardan dos contactos, no uno:

* **primer contacto**: la campaña que presentó a esta persona;
* **último contacto**: en qué hizo clic al volver, que es a lo que las redes publicitarias atribuyen una conversión.

Los parámetros sobreviven a la navegación: un visitante puede llegar por la URL del anuncio, recorrer cinco páginas con la barra de direcciones limpia y abrir el chat una hora después, y la campaña sigue ahí. Una visita sin parámetros de anuncio nunca sobrescribe lo guardado, así que un cliente que vuelve directamente para convertir sigue atribuido a la campaña que lo captó.

Las conversaciones que llegan desde un anuncio Click-to-Messenger o Click-to-Instagram llevan su contexto de anuncio de la misma forma, con el id del anuncio y el título del creativo en lugar de un click id.

## Dónde acaba [#where-it-ends-up]

### En el registro del CRM [#in-the-crm-record]

Toda integración de CRM que crea leads o tratos escribe el origen en el comentario del registro:

```
--- Happ attribution ---
channel: widget
gclid: Cj0KCQjw...
utm_source: google
utm_medium: cpc
utm_campaign: raiden-brand
landing: /catalog
captured: 2026-09-19T08:12:44.000Z
```

Líneas clave-valor a propósito: un gestor las lee, y un script, una fórmula de hoja de cálculo o un flujo de n8n las analiza sin pedirnos una exportación.

Nunca se le pide al agente que pase nada de esto. Un click id son cien caracteres opacos, y un modelo al que se le pide copiarlo lo recortará o inventará uno verosímil; un click id erróneo es peor que ninguno, porque se sube como la conversión de otra persona. La plataforma lo adjunta en el servidor, totalmente fuera de la conversación.

**NetHunt** además expone cada campo como un parámetro asignable (`attribution_gclid`, `attribution_utm_campaign`, `attribution_note` y el resto), para que puedas dirigir cada uno a una columna de tu propia carpeta en la configuración de la integración.

### En tu webhook [#in-your-webhook]

Si tienes conectada la integración **Chat webhook**, el cuerpo de cada mensaje lleva un objeto `attribution`, y se dispara un evento nuevo cuando realmente se crea una solicitud:

```json
{
  "event": "lead.created",
  "eventId": "6f2a...:8821",
  "chatId": "6f2a1c84-...",
  "companyId": "8fb075ae-...",
  "toolName": "keepincrm_create",
  "entityId": "8821",
  "entityType": "leads",
  "phone": "+380731234567",
  "createdAt": "2026-09-19T08:14:02.000Z",
  "attribution": {
    "channel": "widget",
    "clickId": "Cj0KCQjw...",
    "clickNetwork": "google",
    "utmSource": "google",
    "utmMedium": "cpc",
    "utmCampaign": "raiden-brand",
    "landingPage": "/catalog",
    "referrer": "https://www.google.com/",
    "capturedAt": "2026-09-19T08:12:44.000Z",
    "note": "--- Happ attribution ---\nchannel: widget\ngclid: Cj0KCQjw..."
  }
}
```

`eventId` es estable entre reintentos: deduplica por él. Cuando el visitante convirtió en una campaña posterior a la que lo presentó, el primer contacto viaja en `attribution.first`.

`phone` está para [Enhanced Conversions for Leads](https://support.google.com/google-ads/answer/13258081), que hacen coincidir por un número de teléfono hasheado y no necesitan click id: la alternativa para visitantes cuyo `gclid` nunca llegó a la URL.

Los cuerpos sin campo `event` son mensajes normales, como antes.

### En la página, para GTM y GA4 [#on-the-page-for-gtm-and-ga4]

Cuando se crea una solicitud, el widget envía un evento a `dataLayer` en la página anfitriona:

```js
{
  event: "happ_lead_created",
  happ_event_id: "6f2a...:8821",
  happ_chat_id: "6f2a1c84-...",
  happ_entity_id: "8821",
  happ_entity_type: "leads",
  happ_widget_id: "wgt_..."
}
```

Esto cuenta la solicitud, no la apertura del chat: todo visitante curioso abre el chat, y una conversión definida así no le enseña nada a la puja. El evento se deduplica en el navegador, y `happ_event_id` coincide con el `eventId` del webhook, así que una copia de la misma conversión desde el servidor se concilia con él.

En GTM: crea un activador **Custom Event** sobre `happ_lead_created`, úsalo para tu evento de GA4 o tu etiqueta de conversión de Google Ads, y pasa `happ_event_id` como id de transacción/evento para que las dos fuentes se cuenten una sola vez.

## Cerrar el ciclo con Google Ads [#closing-the-loop-with-google-ads]

1. Toma los tratos que tu CRM marca como ganados.
2. Para cada uno, lee `gclid` de la nota de atribución (o de la columna a la que lo asignaste).
3. Súbelos como [conversiones offline](https://support.google.com/google-ads/answer/2998031) con el valor y la hora de la conversión.

Para tratos sin click id (un visitante de búsqueda orgánica, un visitante de iOS cuyo `gclid` nunca apareció), usa en su lugar Enhanced Conversions for Leads con el número de teléfono.

## Límites [#limits]

* Los parámetros se guardan en el `localStorage` del navegador en tu dominio. Un visitante que borra los datos del sitio, cambia de dispositivo o navega en una ventana privada llega como una visita nueva; el primer contacto ya registrado en su conversación no se sobrescribe.
* Una llamada de voz iniciada desde el widget todavía no lleva la atribución al CRM; el chat sí.
* La atribución refleja lo que había en la URL. Si tus anuncios llevan a una página que redirige y pierde la query string, no hay nada que capturar; comprueba que tus redirecciones la conservan.
