Calltouch Analytics Integration

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Calltouch Analytics Integration

Calltouch is call tracking with an analytics core: dynamic number replacement, call and lead attribution, dashboards by source. Integration covers tracker installation, event setup, lead data submission via API, and proper functioning in SPA environments.

Tracker Architecture

Calltouch works through the JS library ct.js, which:

  • Sets cookies _ct_session and _ct_lead with visit identifiers
  • Replaces phone numbers on the page via CSS classes or data-ct-phone attributes
  • Sends interaction events to Calltouch servers
<!-- Tracker installed in <head> as high as possible -->
<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 is the identifier from "Settings → Integrations" in your account.

Getting session_id for Lead Submission

Before sending a lead to the backend, get the current session_id. Calltouch provides a synchronous method:

// Get session ID
function getCalltouchSessionId() {
  if (typeof ct === 'undefined') return null;

  try {
    // Returns { sessionId: '...', ... }
    const data = ct('getSessionId');
    return data?.sessionId ?? null;
  } catch (e) {
    console.warn('Calltouch: failed to get session ID', e);
    return null;
  }
}

// Use on form submit
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 });
});

Submitting Leads via Calltouch API

After saving a lead on the backend, send it to Calltouch so the system can attribute it to the source.

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=Lead from website&name=John Smith&phoneNumber=79001234567&[email protected]&requestUrl=https://example.com/contact&sessionToken=YOUR_TOKEN'

Parameters:

  • sessionId — from ct('getSessionId')
  • sessionToken — site token from account (API section)
  • subject — lead subject (free text)
  • phoneNumber — phone without + and spaces
  • requestUrl — URL of the page the lead came from

PHP Implementation

// 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'] ?? 'Lead from website',
            '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: Correct Number Replacement

In React/Vue/Angular apps, ct.js performs replacement once after load. On navigation without full reload, numbers stop being replaced. Fix by calling ct('reInit') on route change:

// 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') {
      // Small delay — let component render new numbers
      setTimeout(() => window.ct('reInit'), 300);
    }
  }, [location.pathname]);

  return null;
}

For Vue Router:

router.afterEach(() => {
  setTimeout(() => window.ct?.('reInit'), 300);
});

Setting Up Goals via Calltouch Events API

Beyond calls and leads, send arbitrary conversion events:

// Event "add to cart"
ct('send', 'event', {
  eventName: 'add_to_cart',
  value: 2990,
  currency: 'RUB',
  orderId: 'CART-456',
});

// Event "purchase"
ct('send', 'event', {
  eventName: 'purchase',
  value: 14500,
  currency: 'RUB',
  orderId: 'ORDER-789',
  items: [
    { id: 'SKU-001', name: 'Product A', quantity: 2, price: 7250 }
  ],
});

Webhook for Incoming Calls

Calltouch can send a POST request to your server on each call — useful for auto-creating deals in CRM.

Example payload:

{
  "callId": "CT-12345",
  "sessionId": "abc...xyz",
  "phoneNumber": "+79001234567",
  "duration": 124,
  "status": "answered",
  "source": "google/cpc",
  "medium": "cpc",
  "campaign": "brand-search",
  "keyword": "our brand"
}

Webhook endpoint is registered in account → "Integrations → Webhook".

Debugging

Verification checklist:

  • DevTools → Network: check that init.js?id=SITE_ID loads without errors (200)
  • Console: ct('getSessionId') should return an object with non-empty sessionId
  • Number replacement: page should show Calltouch pool number, not original
  • Account → "Lead Log": verify test lead appears with correct source

Timeline

Installing tracker and setting up number replacement — 3–4 hours. Backend API implementation for lead submission — 4–6 hours. Webhook setup and CRM integration — separate task, 1–2 days depending on CRM.