Отправка offline-конверсий в Campaign Manager 360 (DoubleClick)

Была поставлена задача сделать отправку офлайн-конверсий в Google Campaign Manager 360 (далее GCM). Тот что DoubleClick. Думал, что может быть проще, чем дернуть пару методов API от Google. Работа растянулась на 3 недели. Хочу поделиться опытом, вдруг кому пригодится.

Схема работы такова:

  • Пользователь приходит на сайт. По рекламе или прямым заходом;

  • В GCM отправляется лид с frontend-части;

  • Пользователь что-то делает. Например, оформляет заказ, оставляет заявку или делает звонок;

  • С сервера отправляется offline-конверсия.

Т.е. пользователь достиг цели, о чем нужно уведомить GCM, чтобы иметь полноценную картинку в отчетах и аналитике.

Авторизация

Для взаимодействия с любым API от Google нужен авторизационный токен, который выдается приложению, зарегистрированному в панели разработчика.

Если не зарегистрированы – зарегистрируйтесь. Если нет приложения – создайте.

Заходим в раздел OAuth consent screen и по шагам настраиваем экран авторизации, который будет видеть пользователь.

Скрины
Выбираем external
Выбираем external
Заполняем поля
Заполняем поля
Указываем права для доступа к API Campaign Manager 360
Указываем права для доступа к API Campaign Manager 360
Добавляем тестировщиков. Себя добавлять не надо.
Добавляем тестировщиков. Себя добавлять не надо.

На странице приложения сверху есть кнопка «Enable APIs and services». Нажав на нее, переходим в библиотеку API. В поиске вбиваем «campaign manager 360 api», кликаем по единственному элементу. И жмем Enable.

Скрины
Жмем на кнопку
Жмем на кнопку
Ищем нужный API
Ищем нужный API
Подключаем
Подключаем

Возвращаемся в раздел «APIs and services» и создаем реквизиты для OAuth2. Жмем «Create credentials» и выбираем «OAuth client ID». И указываем все что просит. Тип приложения (у меня это Web application) и URL для переадресации.

Скрины
Создаем ключи для OAuth
Создаем ключи для OAuth
Указываем тип и URL для возврата пользователя
Указываем тип и URL для возврата пользователя
Получаем пару ключей.
Получаем пару ключей.

В итоге у нас есть Client ID и Client secret.

Чтобы самостоятельно не реализовывать всю логику авторизации и другой работы с API, можно взять одну из готовых библиотек. Т.к. у меня система на PHP, беру https://github.com/googleapis/google-api-php-client.

Сразу создаем клиент:

<?php

$client = new \Google_Client();
$client->setApplicationName('MyApplication');
$client->addScope(\Google_Service_Dfareporting::DFAREPORTING);
$client->addScope(\Google_Service_Dfareporting::DFATRAFFICKING);
$client->addScope(\Google_Service_Dfareporting::DDMCONVERSIONS);
$client->setAccessType('offline');
$client->setAuthConfig([
   'client_id'     => $options['googleApi.client_id'],
   'client_secret' => $options['googleApi.client_secret'],
   'redirect_uris' => $options['googleApi.redirect_uris'],
]);

if (!empty($accessToken)) {
   $client->setAccessToken($accessToken);
}

Массив $options содержит настройки, полученные в консоли разработчика Google.

Сначала получаем URL, на который нужно будет переадресовать пользователя, чтобы он выдал разрешения нашему приложению.

<?php

$client->createAuthUrl();

Как только пользователь выдал разрешения, его переадресует на URL из настроек приложения с параметром code. По этому параметру нужно получить токен (AccessToken).

<?php

$tokenData = $client ->fetchAccessTokenWithAuthCode($code);

Результатом выполнения будет объект, содержащий параметры:

  • Авторизационный токен - AccessToken

  • Токен для обновления авторизационного – RefreshToken

  • Дата, до которой действует авторизационный токен

Все эти параметры надо где-то сохранить.

За временем жизни токена нужно следить. Если время истекло, необходимо его обновить с помощью refresh-токена.

<?php

$client->refreshToken($refreshToken);

Клиентская часть

Теперь нужно организовать отправку лида с клиента, с нашего сайта.

Есть два варианта.

Первый, думаю, наиболее правильный, добавить событий в DataLayer.

<script>
 window.dataLayer = window.dataLayer || [];

 function gtag(){dataLayer.push(arguments);}

 gtag('set', 'allow_ad_personalization_signals', false);
 
 gtag('js', new Date());

 
 gtag('config', 'DC-[floodlightConfigID]');
  gtag('event', 'purchase', {
    'allow_custom_scripts': true,
    'send_to': 'DC-[floodlightConfigID]/[activityGroupTagString]/[activityTagString]+[countingMethod]',
    'dc_custom_params': {
      'match_id':[your_match_id],
    }
  });
</script>

Второй – вставить пиксель в код страницы.

<img 
     src="https://ad.doubleclick.net/ddm/activity/src=[floodlightConfigID];
          type=[activityGroupTagString];cat=[activityTagString];
          match_id=[your_match_id]" 
     width="1" height="1" alt=""/>

Есть несколько вариантов сопоставления лидов с фронта и офлайн-конверсий. Про них можно почитать в документации. Я выбрал самый простой – использовать свой ID, который передается в параметре match_id. У меня это id сессии, который закрепляется за посетителем. Если есть регистрация, то можно передавать id пользователя.

Серверная часть

Нам нужно отправить offline-конверсию в том случае, когда пользователь достиг некоторой цели. Отправил заявку, позвонил, оформил заказ и т.д.

Делаем это с помощью той же библиотеки, что использовалась в авторизации.

<?php

$service = new \Google_Service_Dfareporting($client);
$currentTimeInMicros = time() * 1000 * 1000;

$activity = $service->floodlightActivities->get(
   $profileId,
   $floodlightActivityId
);

$floodlightConfigId = $activity->getFloodlightConfigurationId();

$conversion = new \Google_Service_Dfareporting_Conversion();
$conversion->setMatchId($matchId);
$conversion->setFloodlightActivityId($floodlightActivityId);
$conversion->setFloodlightConfigurationId($floodlightConfigId);
$conversion->setOrdinal($currentTimeInMicros);
$conversion->setTimestampMicros($currentTimeInMicros);

Предопределенные настройки:

  • $profileId – ID профиля пользователя

Скрин
  • $floodlightActivityId

Скрин
  • $matchId – ID пользователя/ID сессии. То, что передавали с фронта

Свои собственные переменные u1...uN можно передавать или нет. Передаются так:

<?php

$customVariable = new CustomFloodlightVariable();
$customVariable->setKind('dfareporting#customFloodlightVariable');
$customVariable->setType('u1'); // u2…uN
$customVariable->setValue('Супер кампания');

$conversion->setCustomVariables([$customVariables]);
$batch = new \Google_Service_Dfareporting_ConversionsBatchInsertRequest();
$batch->setConversions($conversions);

$result = $service->conversions->batchinsert(
   $profileId,
   $batch
);

В общем-то и все. Выглядит не сложно. Но есть нюанс.

К сожалению, в документации не увидел предупреждения, что лиды обрабатываются GCM-ом примерно за 15-20 минут. Пока лид не обработан, будем получать ошибку и сообщение, что пользователь не найден. По истечении некоторого времени GCM все примет и в ответе ошибок не будет. Обнаружил это экспериментальным путем.

Нужно подобное решение?

Оставьте свой номер телефона и мы обязательно с Вами свяжемся в самое ближайшее время, обсудим проблему и предложим решение

БЛОГ

Наши мысли

Пишем про интересные кейсы из нашей практики. И не только на технические темы.