Tło problemu
Jeden z naszych klientów prowadzi działania reklamowe, których celem jest uzyskanie kontaktu telefonicznego od potencjalnych klientów. Takie podejście jest kluczowe, ponieważ bezpośredni kontakt telefoniczny często prowadzi do wyższej konwersji i lepszej obsługi klienta, co przekłada się na większe zadowolenie klientów i wyższą sprzedaż.
Standardowe rozwiązania umożliwiają pomiar konwersji telefonicznych w określonych przypadkach. Możemy korzystać z website call conversion proponowanych przez Google, które pozwalają śledzić połączenia telefoniczne bezpośrednio z witryny internetowej. Popularnym rozwiązaniem jest również pomiar kliknięcia w przycisk z numerem telefonu, co pozwala na łatwe śledzenie połączeń inicjowanych bezpośrednio ze strony.
W przypadku naszego klienta lwia część ruchu pochodzi z komputerów osobistych. Z tego powodu powstaje problem — nie posiadamy żadnej możliwości pomiaru ilości połączeń telefonicznych w sytuacji, gdy użytkownik przepisuje numer telefonu ze strony na swój telefon i wykonuje połączenie.
Nasze rozwiązanie
Konfigurację przeprowadziliśmy, dodając niestandardowe rozwiązanie w Google Tag Manager. Dodatkowym wymaganiem było utworzenie przez klienta specjalnego numeru telefonu, którego aktywność monitorowaliśmy. W zależności od potrzeb można utworzyć kilka numerów, po jednym dla każdego badanego źródła ruchu.
Efektem działania naszego rozwiązania jest podmiana numeru na stronie, jeśli ruch pochodzi z interesującego nas kanału. W naszym przypadku był to ruch płatny z Google Ads oraz Criteo. Ruch z takich źródeł jest oznaczony odpowiednimi parametrami URL, takimi jak UTMy czy automatyczny parametr gclid. Przykładowy URL może wyglądać w następujący sposób:
https://example.pl/?utm_source=google&utm_medium=cpc&utm_campaign=nazwa_kampanii&utm_content=search_non-brand&gad_source=1&gclid=CjwKCAjwqMO0BhA8EiwAFTLgINPFtJAUUJvRpygygakr8yJwt19BTfcrrXqMj5vnSCuPo6PVgVoDxhoCjRAQAvD_BwE
URL oraz referral strony dla ruchu organicznego zapisujemy w session_storage. Jest to obszar pamięci przeglądarki, który przechowuje dane dla danej sesji przeglądania i jest usuwany po zamknięciu przeglądarki. Ograniczeniem session storage jest fakt, że dane są dostępne tylko w obrębie jednej sesji, co zapewnia większą stabilność w kontekście monitorowania bieżącego ruchu.
W tym celu konfigurujemy customowy tag html w GTM o następującym działaniu:
- <script>
- function parseQueryParams() {
- // Pobiera parametry zapytania z adresu URL
- var queryString = window.location.search;
- var urlParams = new URLSearchParams(queryString);
- // Pobiera wartość parametru 'utm_source' i konwertuje na małe litery
- var utmSource = urlParams.get(’utm_source');
- if (utmSource) {
- utmSource = utmSource.toLowerCase();
- }
- // Pobiera wartość parametru 'utm_medium' i konwertuje na małe litery
- var utmMedium = urlParams.get(’utm_medium');
- if (utmMedium) {
- utmMedium = utmMedium.toLowerCase();
- }
- // Pobiera wartość parametru 'gclid'
- var gclid = urlParams.get(’gclid');
- // Funkcja zwracająca wartość źródła ruchu na podstawie parametrów utmSource i utmMedium
- function getTrafficSourceValue(utmSource, utmMedium) {
- if (!utmSource) {
- return ”;
- }
- if (utmSource === 'direct') {
- return 'direct';
- }
- if (utmSource === 'google' && utmMedium === 'cpc') {
- return 'ps';
- }
- if (utmSource === 'google' && utmMedium === 'organic') {
- return 'google organic';
- }
- if (utmSource === 'facebook' && utmMedium === 'cpc') {
- return 'fb-paid';
- }
- if (utmSource === 'facebook' && utmMedium !== 'cpc') {
- return 'fb';
- }
- if (utmSource === 'criteo' && utmMedium === 'display') {
- return 'criteo';
- }
- return 'other';
- }
- // Zmienna przechowująca wartość źródła ruchu
- var value = ”;
- // Referer strony
- var referrer = document.referrer;
- // Logika ustalania wartości źródła ruchu
- if (utmSource) {
- value = getTrafficSourceValue(utmSource, utmMedium);
- } else if (gclid) {
- value = 'google cpc';
- } else if (referrer.includes(’https://www.google.com/')) {
- value = 'google organic';
- } else if (referrer) {
- value = 'other';
- }
- // Zapisuje wartość źródła ruchu w sessionStorage
- if (value !== ”) {
- sessionStorage.setItem(’trafficSource', value);
- }
- // Zwraca wartość źródła ruchu dla ewentualnego dalszego użycia
- return value;
- }
- // Wywołuje funkcję bezpośrednio, aby uruchomiła się od razu po załadowaniu skryptu
- parseQueryParams();
- </script>
Kod powinien zostać wywołany jak najwcześniej, w naszym przypadku użyliśmy triggera DOM ready.
Dlaczego session storage?
Wcześniej w tym celu wykorzystywaliśmy ciasteczka. Zrezygnowaliśmy jednak z tego rozwiązania na rzecz session storage, które jest bardziej stabilne. W obliczu rosnącej liczby przeglądarek, blokujących ciasteczka trzecich stron, session storage oferuje bardziej niezawodne i bezpieczne rozwiązanie, które jest przypisywane na całą sesję użytkownika. Dodatkowo, w kontekście „cookieless world” (świata bez ciasteczek), session storage staje się coraz bardziej preferowaną metodą przechowywania danych sesyjnych.
Podmiana numeru telefonu
Następnym elementem procesu jest wywołanie drugiego tagu, który sprawdza, czy na stronie występuje element zawierający określony numer telefonu, który chcemy podmienić. Kod zamienia wartość tekstu oraz zawartość linku na inny numer — specjalnie przygotowany do rejestrowania ruchu z danego źródła.
- <script>
- if ({{local storage – trafficSource}} == „google cpc” || {{local storage – trafficSource}} == „criteo” || {{source – url}} == „google cpc” || {{source – url}} == „criteo”){
- var oldNumbers = [
- '[href*=”tel:123 456 789″]',
- '[href*=”tel://123456789″]',
- '[href*=”tel://123 456 789″]'
- ];
- var newNumber = „tel:987 654 321”;
- var newNumberText = „987 654 321”;
- oldNumbers.forEach(function(selector) {
- var elements = document.querySelectorAll(selector);
- for (var i = 0; i < elements.length; i++){
- elements[i].href = newNumber;
- elements[i].text = newNumberText;
- }
- });
- }
- </script>
Zmienna pomocnicza
W naszym rozwiązaniu korzystamy z pomocniczej zmiennej, która przechowuje wartość źródła ruchu w local storage:
- function() {
- return localStorage.getItem(’trafficSource') || 'unknown';
- }
Proces działania kodu
Po załadowaniu strony, skrypt parseQueryParams pobiera parametry URL oraz referer strony, aby określić źródło ruchu. Na przykład, jeśli URL zawiera utm_source=google i utm_medium=cpc, to źródło ruchu jest oznaczone jako google cpc. Wartość ta jest następnie zapisywana w session storage.
Gdy użytkownik przemieszcza się po stronie, drugi skrypt sprawdza, czy w session storage zapisana jest wartość źródła ruchu odpowiadająca naszym kryteriom (np. google cpc). Jeśli tak, skrypt podmienia numery telefonów na stronie na specjalny numer, który jest monitorowany pod kątem połączeń telefonicznych.
Zalety naszego rozwiązania
Nasze rozwiązanie posiada wiele zalet, które znacząco poprawiają efektywność pomiaru konwersji telefonicznych:
- Precyzyjne śledzenie: Możemy dokładnie monitorować połączenia telefoniczne pochodzące z konkretnych źródeł ruchu.
- Zwiększona stabilność: Session storage zapewnia bardziej stabilne przechowywanie danych w porównaniu do ciasteczek, które mogą być blokowane.
- Skalowalność: Rozwiązanie można łatwo dostosować do różnych kampanii reklamowych i kanałów ruchu.
- Dostosowanie do trendów: Przygotowanie na przyszłość bez ciasteczek trzecich stron, co jest zgodne z najnowszymi trendami w ochronie prywatności w Internecie.
Podsumowanie
Dzięki wdrożeniu niestandardowego rozwiązania w Google Tag Manager, nasz klient może teraz skutecznie śledzić konwersje telefoniczne z ruchu komputerowego. Pomimo rosnących wyzwań związanych z ochroną prywatności i zmianami w technologii przeglądarek, nasza metoda zapewnia stabilność i precyzję, pozwalając na dokładne monitorowanie efektywności kampanii reklamowych. Dzięki temu klient może lepiej dostosowywać swoje strategie marketingowe i osiągać lepsze wyniki sprzedażowe.