# Attribution publicitaire

Conservez le clic publicitaire qui a amené un client jusqu'à l'affaire dans votre CRM et renvoyez-le vers Google Ads

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

Un visiteur clique sur votre annonce, lit quelques pages, ouvre la conversation et laisse une demande. Votre CRM reçoit l'affaire — mais sans rien indiquant quelle campagne a payé cette visite. Happ transporte désormais le clic tout au long de la chaîne : page → conversation → affaire → retour vers le réseau publicitaire.

Rien à activer. Tout widget chargé avec le snippet d'intégration actuel commence la collecte dès la page vue suivante.

## Ce qui est collecté [#what-gets-collected]

Sur la première page du visiteur, le script d'intégration lit les paramètres publicitaires dans l'URL et les stocke sur votre propre domaine :

| Groupe               | Paramètres                                                                      |
| -------------------- | ------------------------------------------------------------------------------- |
| Google               | `gclid`, `gbraid`, `wbraid`                                                     |
| Meta                 | `fbclid`                                                                        |
| TikTok, Microsoft    | `ttclid`, `msclkid`                                                             |
| Libellés de campagne | `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `utm_id` |

Il conserve aussi la page d'atterrissage et le référent.

Deux points de contact sont conservés, pas un seul :

* **premier contact** — la campagne qui a fait découvrir la marque à cette personne ;
* **dernier contact** — ce sur quoi elle a cliqué en revenant, c'est à lui que les réseaux publicitaires attribuent une conversion.

Les paramètres survivent à la navigation : un visiteur peut arriver sur l'URL de l'annonce, parcourir cinq pages avec une barre d'adresse propre et ouvrir la conversation une heure plus tard — la campagne est toujours là. Une visite sans paramètres publicitaires n'écrase jamais ce qui a été stocké, donc un client qui revient directement pour convertir reste attribué à la campagne qui l'a gagné.

Les conversations issues d'une annonce Click-to-Messenger ou Click-to-Instagram portent leur contexte publicitaire de la même façon, avec l'id de l'annonce et le titre de la création à la place d'un id de clic.

## Où cela aboutit [#where-it-ends-up]

### Dans la fiche CRM [#in-the-crm-record]

Chaque intégration CRM qui crée des leads ou des affaires écrit l'origine dans le commentaire de la fiche :

```
--- 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
```

Des lignes clé-valeur à dessein : un manager les lit, et un script, une formule de tableur ou un flux n8n les analyse sans nous demander d'export.

On ne demande jamais à l'assistant de transmettre quoi que ce soit de tout cela. Un id de clic fait une centaine de caractères opaques, et un modèle chargé d'en copier un le tronquera ou en inventera un plausible — un mauvais id de clic est pire que pas d'id du tout, car il est importé comme la conversion de quelqu'un d'autre. La plateforme l'attache côté serveur, entièrement en dehors de la conversation.

**NetHunt** expose en plus chaque champ comme paramètre mappable — `attribution_gclid`, `attribution_utm_campaign`, `attribution_note` et les autres — pour que vous puissiez diriger chacun vers une colonne de votre propre dossier dans les paramètres de l'intégration.

### Dans votre webhook [#in-your-webhook]

Si l'intégration **Chat webhook** est connectée, chaque corps de message porte un objet `attribution`, et un nouvel événement se déclenche lorsqu'une demande est réellement créée :

```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` reste stable entre les nouvelles tentatives — dédupliquez sur lui. Lorsque le visiteur a converti sur une campagne postérieure à celle qui l'a fait venir, le premier contact est joint sous `attribution.first`.

`phone` est présent pour les [conversions avancées pour les leads](https://support.google.com/google-ads/answer/13258081), qui font la correspondance sur un numéro de téléphone haché et n'ont besoin d'aucun id de clic — la solution de repli pour les visiteurs dont le `gclid` n'est jamais arrivé dans l'URL.

Les corps sans champ `event` sont des messages ordinaires, comme avant.

### Sur la page, pour GTM et GA4 [#on-the-page-for-gtm-and-ga4]

Lorsqu'une demande est créée, le widget pousse un événement dans `dataLayer` sur la page hôte :

```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_..."
}
```

Cela compte la demande, pas l'ouverture de la conversation — chaque visiteur curieux ouvre la conversation, et une conversion définie ainsi n'apprend rien aux enchères. L'événement est dédupliqué dans le navigateur, et `happ_event_id` correspond à l'`eventId` du webhook, de sorte qu'une copie côté serveur de la même conversion peut être rapprochée avec lui.

Dans GTM : créez un déclencheur **Événement personnalisé** sur `happ_lead_created`, utilisez-le pour votre événement GA4 ou votre balise de conversion Google Ads, et passez `happ_event_id` comme id de transaction/d'événement pour que les deux sources ne soient comptées qu'une fois.

## Boucler la boucle avec Google Ads [#closing-the-loop-with-google-ads]

1. Prenez les affaires que votre CRM marque comme gagnées.
2. Pour chacune, lisez le `gclid` dans la note d'attribution (ou dans la colonne vers laquelle vous l'avez mappé).
3. Importez-les comme [conversions hors ligne](https://support.google.com/google-ads/answer/2998031) avec la valeur et l'heure de la conversion.

Pour les affaires sans id de clic — un visiteur venant de la recherche naturelle, un visiteur iOS dont le `gclid` n'est jamais apparu — utilisez plutôt les conversions avancées pour les leads sur le numéro de téléphone.

## Limites [#limits]

* Les paramètres sont stockés dans le `localStorage` du navigateur sur votre domaine. Un visiteur qui efface les données du site, change d'appareil ou navigue en fenêtre privée arrive comme une nouvelle visite ; le premier contact déjà enregistré sur sa conversation n'est pas écrasé.
* Un appel vocal lancé depuis le widget ne transmet pas encore l'attribution au CRM — la conversation, si.
* L'attribution reflète ce qui figurait dans l'URL. Si vos annonces mènent à une page qui redirige et perd la query string, il n'y a rien à capturer ; vérifiez que vos redirections la conservent.
