Jak połączyć VoxCRM z GoogleAds?

System voxDeveloper CRM umożliwia automatyczny eksport danych o skonwertowanych leadach do Google Ads w postaci konwersji offline. Dzięki temu kampanie reklamowe w Google Ads mogą być optymalizowane pod realne zdarzenia biznesowe (sprzedaż, umowa rezerwacyjna, kwalifikowany lead), a nie jedynie pod wypełnienie formularza.

Integracja opiera się na endpoincie gclid-conversions (część modułu Power BI), arkuszu Google Sheets oraz skrypcie Google Apps Script, który cyklicznie pobiera dane z voxCRM i zapisuje je w arkuszu. Tak przygotowany arkusz może zostać wykorzystany jako źródło konwersji offline w Google Ads.

⚠ Ważne: Warunkiem działania integracji jest zbieranie parametru gclid przez formularze na stronie internetowej. Jeżeli formularz dewelopera nie przekazuje parametru gclid do voxCRM, leady nie będą posiadały identyfikatora kliknięcia i nie zostaną zwrócone przez endpoint. Aby uzyskać klucz API oraz zweryfikować konfigurację, prosimy o kontakt z działem wsparcia technicznego.

Słowniczek pojęć

Pojęcie Wyjaśnienie
GCLID Google Click Identifier — unikatowy identyfikator każdego kliknięcia w reklamę Google Ads, generowany automatycznie i dołączany do adresu URL strony docelowej.
Konwersja offline Zdarzenie biznesowe (np. podpisanie umowy, sprzedaż) zachodzące po kliknięciu w reklamę, ale poza stroną internetową. Przekazywane do Google Ads z opóźnieniem w celu optymalizacji kampanii.
Google Apps Script Platforma skryptowa Google pozwalająca automatyzować zadania w arkuszach, Gmailu i innych usługach Google.
Właściwości skryptu Parametry konfiguracyjne zapisywane w bezpieczny sposób w projekcie Apps Script (nie w kodzie) i dostępne dla skryptu w czasie działania.
Wyzwalacz czasowy Reguła Google Apps Script określająca kiedy skrypt ma zostać automatycznie uruchomiony (np. co 1 godzinę).
Endpoint gclid-conversions Adres API voxCRM zwracający listę skonwertowanych leadów z uzupełnionym polem GCLID. Szczegóły w artykule „Endpointy Power BI — lista dostępnych źródeł danych".

 

Jak działa integracja

Proces przekazywania konwersji offline do Google Ads przebiega w następujących etapach:

  1. Użytkownik klika w reklamę Google Ads — w adresie URL strony docelowej pojawia się parametr ?gclid=<identyfikator>.
  2. Formularz na stronie dewelopera zapisuje wartość gclid jako ukryte pole i przekazuje ją razem z pozostałymi danymi do voxCRM.
  3. W voxCRM powstaje lead z uzupełnionym polem GCLID.
  4. Po skonwertowaniu leada (powiązanie z klientem, nadanie klasyfikacji kwalifikującej jako konwersja) lead staje się dostępny w endpoincie gclid-conversions.
  5. Skrypt Google Apps Script uruchamiany cyklicznie (co określony czas) pobiera nowe konwersje z voxCRM i dopisuje je do arkusza Google Sheets.
  6. Arkusz Google Sheets stanowi źródło danych dla Google Ads — dane wgrywane są ręcznie lub przez zaplanowany import cykliczny.

 

Wymagania wstępne

Przed przystąpieniem do konfiguracji należy upewnić się, że spełnione są następujące warunki:

  • Aktywny moduł webservice / Power BI w voxCRM.
  • Wygenerowany klucz API do voxCRM — w celu jego uzyskania prosimy o kontakt z działem wsparcia technicznego.
  • Formularze na stronie internetowej przekazują parametr gclid do voxCRM (ukryte pole odczytujące wartość z adresu URL). Weryfikację tego warunku można przeprowadzić w karcie leada — w sekcji danych UTM powinno być widoczne pole GCLID.
  • Konto Google z uprawnieniami do tworzenia arkuszy Google Sheets oraz projektów Google Apps Script.
  • Dostęp do konta Google Ads, w którym skonfigurowane będą konwersje offline.
💡 Wskazówka: Jeżeli w leadach w voxCRM pole GCLID pozostaje puste, oznacza to, że formularz na stronie dewelopera nie przekazuje tego parametru. W takiej sytuacji konieczna jest modyfikacja formularza po stronie dewelopera (dodanie ukrytego pola gclid oraz kodu JavaScript odczytującego parametr z URL).

 


Konfiguracja krok po kroku

Krok 1. Utworzenie nowego arkusza Google Sheets

Należy zalogować się do konta Google, otworzyć aplikację Google Sheets i utworzyć nowy, pusty arkusz kalkulacyjny. Arkusz będzie pełnił funkcję magazynu danych o konwersjach pobieranych z voxCRM.

Zaleca się nadanie arkuszowi rozpoznawalnej nazwy, np. „Konwersje Google Ads — voxCRM".

 

Krok 2. Otwarcie edytora Google Apps Script

W utworzonym arkuszu należy wybrać z menu Rozszerzenia → Apps Script. W nowej karcie przeglądarki otworzy się edytor Google Apps Script z domyślnym, pustym plikiem Kod.gs.

 

Krok 3. Wklejenie kodu skryptu

Domyślną zawartość pliku Kod.gs należy usunąć, a następnie wkleić poniższy kod:

function importDataFromAPI() {
    var lock = LockService.getScriptLock();
    try {
        lock.waitLock(5000);
    } catch (e) {
        Logger.log('Could not acquire lock - another instance is running');
        return;
    }
    try {
        var apiKey = PropertiesService.getScriptProperties().getProperty('API_KEY');
        var crmUrl = PropertiesService.getScriptProperties().getProperty('CRM_URL');
        var classification = PropertiesService.getScriptProperties().getProperty('LEAD_CLASSIFICATION');
        var investments = PropertiesService.getScriptProperties().getProperty('INVESTMENTS');
        if (!apiKey || !crmUrl) {
            Logger.log('API_KEY or CRM_URL is not set in script properties');
            return;
        }
        var lastUpdate = PropertiesService.getScriptProperties().getProperty('LAST_UPDATE');
        var now = formatDateToYmdHis(new Date());
        var syncDateUpdated = false;
        if (!lastUpdate) {
            lastUpdate = now;
            PropertiesService.getScriptProperties().setProperty('LAST_UPDATE', now);
            syncDateUpdated = true;
        }
        crmUrl = crmUrl.replace(/\/+$/, '');
        var apiUrl = crmUrl + '/webservice/power-bi/source/gclid-conversions';
        const searchParams = {
            'from': lastUpdate,
        };
        if (classification) {
            searchParams['lead-classifications'] = classification;
        }
        if (investments) {
            searchParams['investments'] = investments;
        }
        var sheet = SpreadsheetApp.getActiveSheet();
        var headers = {
            'gclid': 'Google Click ID',
            'conversion_name': 'Conversion Name',
            'conversion_time': 'Conversion Time',
            'email_address': 'Email Address',
            'investment': 'Inwestycja',
        }
        var lastDataRow = sheet.getLastRow();
        if (lastDataRow === 0) {
            sheet.getRange(1, 1, 1, Object.keys(headers).length).setValues([Object.values(headers)]);
            lastDataRow = 1;
        }
        var response = UrlFetchApp.fetch(apiUrl + '?' + toSearchParams(searchParams), {
            headers: { 'Api-Key': apiKey }
        });
        if (response.getResponseCode() !== 200) {
            throw new Error(
                'API request failed with response code ' + response.getResponseCode() + ': ' +
                response.getContentText()
            );
        }
        var data = JSON.parse(response.getContentText());
        if (!data || data.length === 0) {
            Logger.log("No data received from API");
            return;
        }
        var rows = data.map(function (item) {
            return Object.keys(headers).map(function (key) {
                return item[key];
            });
        });
        sheet.getRange(lastDataRow + 1, 1, rows.length, Object.keys(headers).length).setValues(rows);
        if (!syncDateUpdated) {
            PropertiesService.getScriptProperties().setProperty('LAST_UPDATE', now);
        }
        function formatDateToYmdHis(date) {
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const hours = String(date.getHours()).padStart(2, '0');
            const minutes = String(date.getMinutes()).padStart(2, '0');
            const seconds = String(date.getSeconds()).padStart(2, '0');
            return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
        }
        function toSearchParams(payload) {
            return Object.keys(payload).map(key =>
                encodeURIComponent(key) + '=' + encodeURIComponent(payload[key])
            ).join('&')
        }
    } finally {
        lock.releaseLock();
    }
}

Po wklejeniu kodu należy zapisać skrypt — ikona dyskietki w górnym pasku lub skrót klawiszowy Ctrl + S (Windows) / Cmd + S (macOS).

💡 Wskazówka: Kod skryptu wykorzystuje mechanizm LockService zabezpieczający przed równoległym uruchomieniem wielu instancji oraz parametr LAST_UPDATE — dzięki temu przy każdym uruchomieniu pobierane są wyłącznie nowe konwersje (dane inkrementalne), a nie całe zestawienie od początku.

 

Krok 4. Konfiguracja właściwości skryptu

Należy przejść do zakładki Ustawienia projektu (ikona koła zębatego w lewym menu edytora Apps Script). W dolnej części strony znajduje się sekcja Właściwości skryptu. W sekcji tej należy kolejno dodać cztery właściwości klikając przycisk Dodaj właściwość skryptu:

Nazwa właściwości Wartość Wymagana Opis
CRM_URL https://<nazwa>.voxdeveloper.com Tak Adres Państwa systemu voxCRM (bez ukośnika na końcu).
API_KEY <klucz API> Tak Klucz autoryzacyjny do voxCRM. W celu wygenerowania klucza prosimy o kontakt z działem wsparcia technicznego.
LEAD_CLASSIFICATION np. Ciepły lead Nie Nazwa klasyfikacji leadów, które mają być przekazywane do Google Ads. Pozostawienie pola pustego oznacza przekazywanie wszystkich skonwertowanych leadów z uzupełnionym GCLID.
INVESTMENTS np. Inwestycja A,Inwestycja B Nie Lista nazw inwestycji oddzielonych przecinkami. Pozostawienie pola pustego oznacza przekazywanie danych dla wszystkich inwestycji.

Po uzupełnieniu wszystkich wymaganych pól należy kliknąć przycisk Zapisz właściwości skryptu.

⚠ Ważne: Nazwy właściwości są rozpoznawane po wielkości liter. Należy zachować zapis dokładnie w formie CRM_URL, API_KEY, LEAD_CLASSIFICATION, INVESTMENTS. Nazwy inwestycji muszą być zgodne z nazwami używanymi w voxCRM.

 

Krok 5. Konfiguracja wyzwalacza czasowego

Aby skrypt uruchamiał się automatycznie, należy dodać wyzwalacz czasowy. W lewym menu edytora Apps Script należy kliknąć zakładkę Reguły (ikona zegara), a następnie w prawym dolnym rogu strony przycisk Dodaj wyzwalacz.

W oknie konfiguracji wyzwalacza należy ustawić następujące wartości:

  • Wybierz funkcję do uruchomienia: importDataFromAPI
  • Wybierz wdrożenie do uruchomienia: Główne
  • Wybierz źródło wydarzenia: Na podstawie czasu
  • Wybierz rodzaj wyzwalacza opartego na czasie: Licznik w godzinach
  • Wybierz częstotliwość w godzinach: Co 1 godzinę (zalecane)

Po ustawieniu wartości należy kliknąć przycisk Zapisz.

 

Krok 6. Autoryzacja skryptu

Przy pierwszym zapisaniu wyzwalacza system Google wyświetli okno z prośbą o autoryzację skryptu. Proces autoryzacji przebiega następująco:

  1. Należy wybrać konto Google powiązane z utworzonym wcześniej arkuszem.
  2. Może zostać wyświetlony komunikat „Google hasn't verified this app" — jest to standardowa informacja Google przy skryptach niezwerifykowanych publicznie. W celu kontynuacji należy kliknąć odnośnik Show Advanced, a następnie Go to Projekt bez nazwy (unsafe).
  3. W oknie uprawnień pokazującym zakres dostępu skryptu (odczyt i zapis arkuszy, wysyłanie żądań do zewnętrznych serwisów) należy kliknąć przycisk Allow.
💡 Wskazówka: Komunikat o nieautoryzowanej aplikacji jest standardowym zachowaniem Google dla skryptów Apps Script napisanych przez użytkowników końcowych. Skrypt zostaje uruchomiony na koncie Google właściciela arkusza i posiada dostęp wyłącznie do jego własnych danych.

 

Krok 7. Weryfikacja działania

Po prawidłowym skonfigurowaniu wyzwalacza skrypt będzie uruchamiał się automatycznie zgodnie z ustaloną częstotliwością. W celu weryfikacji poprawnego działania można skorzystać z następujących metod:

  • Zakładka Uruchomienia w edytorze Apps Script — wyświetla historię wszystkich uruchomień skryptu (godzina rozpoczęcia, czas trwania, stan: Ukończono lub Niepowodzenie).
  • Arkusz Google Sheets — po pierwszym uruchomieniu w pierwszym wierszu pojawią się nagłówki kolumn, a w kolejnych wierszach dane o konwersjach.

Struktura danych zapisywanych w arkuszu:

Kolumna Opis
Google Click ID Identyfikator GCLID pochodzący z kliknięcia w reklamę Google Ads.
Conversion Name Nazwa konwersji — domyślnie „Konwersja offline".
Conversion Time Data i godzina konwersji leada w voxCRM (format YYYY-MM-DD HH:MM:SS).
Email Address Adres e-mail klienta powiązanego z leadem.
Innvestment Nazwa inwestycji, z którą powiązany jest lead.

 


Import danych do Google Ads

Przygotowany arkusz Google Sheets może zostać wykorzystany jako źródło konwersji offline w Google Ads. Platforma Google Ads umożliwia dwa sposoby importu:

  • Ręczny upload pliku — pobranie arkusza jako plik CSV i ręczne wgranie w panelu Google Ads (Narzędzia → Konwersje → Uploads).
  • Zaplanowany import z Google Sheets — Google Ads cyklicznie pobiera dane bezpośrednio z arkusza, co eliminuje konieczność manualnego uploadu.

Szczegółowy opis wymaganego formatu danych oraz pełna instrukcja konfiguracji importu dostępne są w oficjalnej dokumentacji Google Ads: https://support.google.com/google-ads/answer/7014069.

⚠ Ważne: Dane wgrywane do Google Ads muszą spełniać wymogi formatu określone przez Google (m.in. kolumny Google Click ID, Conversion Name, Conversion Time). Dostarczany przez skrypt arkusz generuje dane w formacie zgodnym z wymaganiami Google.

 


Najczęstsze problemy

Skrypt nie pobiera żadnych danych

Możliwe przyczyny:

  • Brak parametru gclid w leadach — formularz na stronie internetowej nie przekazuje tego parametru do voxCRM. Weryfikację można wykonać otwierając kartę dowolnego leada i sprawdzając czy pole GCLID zostało uzupełnione.
  • Błędny klucz API lub URL w sekcji Właściwości skryptu — należy zweryfikować poprawność adresu (bez ukośnika na końcu) oraz klucza.
  • Brak leadów spełniających warunki endpointu — endpoint zwraca wyłącznie leady z uzupełnionym polem GCLID oraz oznaczone jako skonwertowane (powiązane z klientem).
  • Niepoprawna nazwa klasyfikacji w polu LEAD_CLASSIFICATION — należy upewnić się, że nazwa klasyfikacji jest zgodna z nazwą używaną w voxCRM.

Skrypt zwraca błąd autoryzacji

Może wystąpić gdy:

  • Wyzwalacz wymaga ponownej autoryzacji — należy usunąć istniejący wyzwalacz i utworzyć go ponownie, przechodząc przez pełen proces autoryzacji opisany w Kroku 6.
  • Konto Google uruchamiające skrypt nie posiada uprawnień do arkusza — należy zalogować się na właściwym koncie Google.

W arkuszu pojawiają się duplikaty

Skrypt wykorzystuje właściwość LAST_UPDATE do pobierania wyłącznie nowych danych od ostatniej synchronizacji. Duplikaty mogą się pojawić jeśli właściwość LAST_UPDATE została zmodyfikowana ręcznie lub usunięta. Aby zresetować arkusz i pobrać dane od początku, należy usunąć właściwość LAST_UPDATE z sekcji Właściwości skryptu.

Chcielibyśmy zmienić częstotliwość uruchamiania skryptu

Wystarczy przejść do zakładki Reguły, usunąć istniejący wyzwalacz i utworzyć nowy z wybraną częstotliwością. Zalecane są wartości w zakresie od 15 minut do 6 godzin — większa częstotliwość oznacza szybsze przekazywanie konwersji do Google Ads, ale większe wykorzystanie limitów Apps Script.

 


Integracja voxCRM z Google Ads przez konwersje offline pozwala na precyzyjne mierzenie skuteczności kampanii reklamowych i ich optymalizację pod realne zdarzenia biznesowe. Mogą Państwo w prosty sposób zdefiniować jakie klasyfikacje leadów oraz które inwestycje mają zasilać Google Ads.

W przypadku pytań, problemów z konfiguracją lub potrzeby wygenerowania klucza API prosimy o kontakt z działem wsparcia technicznego: kontakt@voxcommerce.pl