# Рекламная атрибуция

Клик по рекламе, который привёл клиента, сохраняется до сделки в CRM и возвращается в Google Ads

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

Посетитель кликает по объявлению, читает пару страниц, открывает чат и оставляет заявку. В CRM появляется сделка — но в ней нет ничего о том, какая кампания заплатила за этот визит. Теперь Happ сохраняет клик на всём пути: страница → чат → сделка → обратно в рекламную систему.

Включать ничего не нужно. Любой виджет с актуальным сниппетом начинает собирать данные со следующего просмотра страницы.

## Что собирается [#what-gets-collected]

На первой странице посетителя скрипт виджета считывает рекламные параметры из URL и сохраняет их на вашем же домене:

| Группа            | Параметры                                                                       |
| ----------------- | ------------------------------------------------------------------------------- |
| Google            | `gclid`, `gbraid`, `wbraid`                                                     |
| Meta              | `fbclid`                                                                        |
| TikTok, Microsoft | `ttclid`, `msclkid`                                                             |
| Метки кампании    | `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `utm_id` |

Вместе с ними — страница входа и реферер.

Сохраняются два касания, а не одно:

* **первое касание** — кампания, которая привела этого человека;
* **последнее касание** — то, на что он кликнул, возвращаясь; именно ему рекламные системы приписывают конверсию.

Параметры переживают переходы: посетитель может зайти по рекламной ссылке, полистать пять страниц с чистой адресной строкой и открыть чат через час — кампания всё равно будет известна. Визит без рекламных параметров никогда не затирает сохранённое, поэтому клиент, который вернулся напрямую, чтобы купить, остаётся приписан к кампании, которая его привела.

Разговоры из рекламы Click-to-Messenger и Click-to-Instagram несут свой рекламный контекст так же — с ID объявления и названием креатива вместо click id.

## Куда это попадает [#where-it-ends-up]

### В карточку CRM [#in-the-crm-record]

Каждая CRM-интеграция, которая создаёт лиды или сделки, дописывает происхождение в комментарий карточки:

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

Формат «ключ: значение» выбран намеренно: его читает менеджер, а скрипт, формула в таблице или сценарий n8n разбирают его без запроса выгрузки у нас.

Агенту ничего из этого передавать не нужно. Click id — это сотня бессмысленных символов, и модель, которой поручили его скопировать, обрежет его или выдумает правдоподобный. Неверный click id хуже отсутствующего: он выгрузится как чужая конверсия. Поэтому платформа подставляет его на сервере, полностью вне разговора.

**NetHunt** дополнительно показывает каждое поле как параметр для сопоставления — `attribution_gclid`, `attribution_utm_campaign`, `attribution_note` и остальные, — поэтому в настройках интеграции каждое можно направить в отдельную колонку своей папки.

### В ваш вебхук [#in-your-webhook]

Если подключена интеграция **Вебхук чатов**, в теле каждого сообщения приходит объект `attribution`, а при фактическом создании заявки — отдельное событие:

```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` не меняется при повторах — дедуплицируйте по нему. Если конверсия пришлась на более позднюю кампанию, чем та, что привела посетителя, первое касание передаётся рядом, в поле `attribution.first`.

`phone` нужен для [Enhanced Conversions for Leads](https://support.google.com/google-ads/answer/13258081): они сопоставляются по хешу номера и вообще не требуют click id — запасной путь для посетителей, у которых `gclid` так и не попал в URL.

Тела без поля `event` — это обычные сообщения, как и раньше.

### На странице, для GTM и GA4 [#on-the-page-for-gtm-and-ga4]

Когда заявка создана, виджет кладёт событие в `dataLayer` вашей страницы:

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

Так считается именно заявка, а не открытие чата: чат открывает каждый любопытный посетитель, и такая конверсия ничему не научит автоматические стратегии ставок. Событие дедуплицируется в браузере, а `happ_event_id` совпадает с `eventId` из вебхука, поэтому по нему сводится серверная копия той же конверсии.

В GTM: создайте триггер **Custom Event** на `happ_lead_created`, повесьте на него тег события GA4 или конверсии Google Ads, а `happ_event_id` передайте как ID транзакции/события, чтобы конверсия из двух источников засчиталась один раз.

## Как замкнуть цикл с Google Ads [#closing-the-loop-with-google-ads]

1. Возьмите сделки, которые в CRM отмечены как успешные.
2. Для каждой извлеките `gclid` из блока атрибуции (или из колонки, в которую вы его направили).
3. Загрузите их как [офлайн-конверсии](https://support.google.com/google-ads/answer/2998031) — с ценностью и временем конверсии.

Для сделок без click id — посетитель из органики, iOS-посетитель, у которого `gclid` не появился, — используйте Enhanced Conversions for Leads по номеру телефона.

## Ограничения [#limits]

* Параметры хранятся в `localStorage` браузера на вашем домене. Посетитель, который очистил данные сайта, сменил устройство или сидит в приватном окне, считается новым визитом; первое касание, уже записанное в его разговоре, от этого не затирается.
* Голосовой звонок из виджета пока не передаёт атрибуцию в CRM — чат передаёт.
* Атрибуция отражает то, что было в URL. Если реклама ведёт на страницу с редиректом, который отрезает query-строку, собирать нечего — проверьте, что ваши редиректы её сохраняют.
