Интеграция Calltouch аналитики на сайт
Calltouch — коллтрекинг с аналитическим ядром: динамическая подмена номеров, атрибуция звонков и заявок, дашборды по источникам. Интеграция охватывает установку счётчика, настройку событий, передачу данных о заявках через API и корректную работу коллтрекинга в SPA-окружении.
Архитектура счётчика
Calltouch работает через JS-библиотеку ct.js, которая:
- устанавливает cookie
_ct_sessionи_ct_leadс идентификаторами визита - подменяет телефонные номера на странице через CSS-классы или атрибуты
data-ct-phone - отправляет события о взаимодействиях на серверы Calltouch
<!-- Счётчик устанавливается в <head> как можно выше -->
<script>
(function(w, n) {
w[n] = w[n] || [];
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = '//mod.calltouch.ru/init.js?id=SITE_ID';
var f = document.getElementsByTagName('script')[0];
f.parentNode.insertBefore(s, f);
})(window, 'ct');
</script>
SITE_ID — идентификатор из раздела «Настройки → Интеграции» личного кабинета.
Получение session_id для передачи заявок
Перед отправкой заявки на бэкенд нужно получить текущий session_id. Calltouch предоставляет синхронный метод:
// Получение session ID
function getCalltouchSessionId() {
if (typeof ct === 'undefined') return null;
try {
// Метод возвращает объект { sessionId: '...', ... }
const data = ct('getSessionId');
return data?.sessionId ?? null;
} catch (e) {
console.warn('Calltouch: не удалось получить session ID', e);
return null;
}
}
// Использование при сабмите формы
document.getElementById('lead-form').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
formData.append('ct_session_id', getCalltouchSessionId() ?? '');
await fetch('/api/leads', { method: 'POST', body: formData });
});
Передача заявки в Calltouch через API
После сохранения заявки на бэкенде отправляем её в Calltouch, чтобы система смогла атрибутировать лид к источнику.
Endpoint: POST https://api.calltouch.ru/calls-service/RestAPI/requests/[siteId]/register/
curl -X POST \
'https://api.calltouch.ru/calls-service/RestAPI/requests/12345/register/' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'sessionId=SESSION_ID_FROM_COOKIE&subject=Заявка с сайта&name=Иван Петров&phoneNumber=79001234567&[email protected]&requestUrl=https://example.com/contact&sessionToken=YOUR_TOKEN'
Параметры:
-
sessionId— изct('getSessionId') -
sessionToken— токен сайта из ЛК (раздел API) -
subject— тема заявки (свободный текст) -
phoneNumber— телефон без+и пробелов -
requestUrl— URL страницы, с которой пришла заявка
PHP-реализация
// app/Services/CalltouchService.php
class CalltouchService
{
private string $siteId;
private string $sessionToken;
private string $apiBase = 'https://api.calltouch.ru/calls-service/RestAPI/requests';
public function __construct()
{
$this->siteId = config('services.calltouch.site_id');
$this->sessionToken = config('services.calltouch.token');
}
public function registerRequest(array $data, string $sessionId): array
{
$url = "{$this->apiBase}/{$this->siteId}/register/";
$response = Http::asForm()->timeout(5)->post($url, [
'sessionId' => $sessionId,
'sessionToken' => $this->sessionToken,
'subject' => $data['subject'] ?? 'Заявка с сайта',
'name' => $data['name'] ?? '',
'phoneNumber' => preg_replace('/\D/', '', $data['phone'] ?? ''),
'email' => $data['email'] ?? '',
'requestUrl' => $data['url'] ?? '',
'comment' => $data['comment'] ?? '',
]);
if (!$response->ok()) {
Log::error('Calltouch API error', [
'status' => $response->status(),
'body' => $response->body(),
'session' => $sessionId,
]);
}
return $response->json() ?? [];
}
}
SPA: корректная подмена номеров
В React/Vue/Angular приложениях ct.js выполняет подмену один раз после загрузки. При навигации между страницами без полной перезагрузки номера перестают подменяться. Исправляется вызовом ct('reInit') при смене маршрута:
// React Router v6
import { useLocation } from 'react-router-dom';
import { useEffect } from 'react';
export function CalltouchReinit() {
const location = useLocation();
useEffect(() => {
if (typeof window.ct === 'function') {
// Небольшая задержка — дать компоненту отрендерить новые номера
setTimeout(() => window.ct('reInit'), 300);
}
}, [location.pathname]);
return null;
}
Для Vue Router:
router.afterEach(() => {
setTimeout(() => window.ct?.('reInit'), 300);
});
Настройка целей через Calltouch API событий
Помимо звонков и заявок можно передавать произвольные конверсионные события:
// Событие "добавление в корзину"
ct('send', 'event', {
eventName: 'add_to_cart',
value: 2990,
currency: 'RUB',
orderId: 'CART-456',
});
// Событие "оформление заказа"
ct('send', 'event', {
eventName: 'purchase',
value: 14500,
currency: 'RUB',
orderId: 'ORDER-789',
items: [
{ id: 'SKU-001', name: 'Товар A', quantity: 2, price: 7250 }
],
});
Webhook для входящих звонков
Calltouch умеет слать POST-запрос на ваш сервер при каждом звонке — удобно для автоматического создания сделок в CRM.
Пример payload:
{
"callId": "CT-12345",
"sessionId": "abc...xyz",
"phoneNumber": "+79001234567",
"duration": 124,
"status": "answered",
"source": "google/cpc",
"medium": "cpc",
"campaign": "brand-search",
"keyword": "наш бренд"
}
Endpoint для webhook регистрируется в ЛК → «Интеграции → Webhook».
Отладка
Проверочный чеклист:
- В DevTools → Network проверить, что
init.js?id=SITE_IDзагружается без ошибок (200) - В консоли:
ct('getSessionId')— должен вернуть объект с непустымsessionId - Подмена номеров: на странице должен быть номер из пула Calltouch, не оригинальный
- В ЛК → «Журнал заявок» проверить, что тестовая заявка появилась с корректным источником
Сроки
Установка счётчика и настройка подмены номеров — 3–4 часа. Реализация API передачи заявок на бэкенде — 4–6 часов. Настройка webhook и интеграция с CRM — отдельная задача, 1–2 дня в зависимости от CRM.







