Geschrieben von

Der Client im Google Tag Manager-Server

Webtracking

Was ist ein Client?

Diese Frage müsste eigentlich erweitert werden um “…im Google Tag Manager Server-Container?”. Beim Wort Client können unterschiedliche Dinge gemeint sein. In der Webentwicklung meint man mit “Client” einfach nur den “Browser” beispielsweise. In Bezug auf den GTM-Server ist ein Client ein Programm, welches eingehende HTTP-Requests annimmt, verarbeitet und weiterschickt.

Im Detail erklärt:
Beim serverseitigem Google Tag Manager werden Hits grundsätzlich zunächst an den GTM-Server geschickt. Von dort aus können sie dann weiter an diverse Endpoints (Google Analytics, Facebook, etc.) versendet werden.

Damit das reibungslos ablaufen kann, muss der GTM-Server einiges an Arbeit leisten. Hier etwas im Detail was konkret passiert:

  1. Ein Nutzer kommt auf eure Website.
  2. Mittles dem Web-Container des Google Tag Mangers oder dem Measurement Protocol werden Hits an den Google Tag Manager-Server geschickt.
  3. Im Google Tag Manager-Server wartet ein “Client” auf ankommende HTTP-Requests.
  4. Der Client wird so programmiert, dass er meist nach einem bestimmten Muster im HTTP-Request Ausschau hält. Bspw. würde ein Universal Analytics-Client laufend prüfen, ob der ankommende Request ein “/collect” in der URL aufweist.
  5. Falls das Muster mit den hinterlegten Anforderungen im Client übereinstimmt, “beansprucht” der Client den Request für sich. Falls aber ein Request an den GTM-Server geschickt wird, den kein Client beansprucht, dann passiert im Server-Container auch nichts. Als Antwort wird ein HTTP-Error zurückgegeben.
  6. Was der Client im nächsten Schritt macht, hängt davon ab, wie man den Client programmiert hat. Eine Aufgabe kann es sein, dass der Client eine Antwort zurück liefert (z.B. einen Status Code) oder dass bestimmte Daten aus dem Request gelöscht werden (z.B. PII-Daten).
  7. Im Falle eines Universal Analytics-Clients wird dieser den Hit annehmen und ihn im nächsten Schritt in das für Universal Analytics notwendige Daten-Model überführen. Konkret werden die Parameter im Hit als Tabelle mit Schlüssel-Werte-Paar dargestellt.
  8. Ab diesem Zeitpunkt kann die Arbeit des Clients als “Abgeschlossen” gelten.
  9. Sind die Daten in das notwendige Daten-Modell überführt, kann darauf ein Universal Analytics-Tag auslösen, der die Daten an Google Analytics für das Reporting schickt.

Zusammengefasst kann man also sagen:

Ein Client ist vereinfacht ausgedrückt ein Parser, der die eingehenden HTTP-Requests annimmt und die Daten für den Weitertransport verarbeitet. Wenn ein Request an der Serverside-Endpoint geschickt wird, dann kann folgendes passieren:

  • Gibt es keinen Client der nach dem Format des eingehenden Requests Ausschau hält, dann passiert nichts. Der eigene Server antwortet mit einer Fehlermeldung.
  • Wurde ein Client erstellt der genau nach dem Format des eingehenden Requests Ausschau hält, dann nimmt der Client diesen Request entgegen und verarbeitet diesen.
Wichtig zu wissen
Wenn es 2 Clients gibt, die den gleichen Request für sich beanspruchen wollen, dann gewinnt derjenige mit der höheren, angegeben Priorität in den Client-Einstellungen.

Einen Client erstellen

Im GTM-Server sind Clients grundsätzlich unter dem Menü-Punkt “Clients” zu finden. Dort kann ein neuer Client angelegt werden. Aktuell (08.03.2021) sind standardmäßig folgende Clients verfügbar:

  • “Google Analytics: GA4” für das Verarbeiten von Google Analytics 4-Hits.
  • “Google Analytics: Universal Analytics” für das Verarbeiten von Universal Analytics-Hits.
  • “Google Tag Manager: Webcontainer”, um den Web-Container über die eigene Domain auszuspielen.
  • “Measurement Protocol” für das Verarbeiten von Hits, die per Measurement Protocol (Universal Analytics-Struktur)einlaufen.
  • “Measurement Protocol” für das Verarbeiten von Hits, die per Measurement Protocol (Google Analytics 4-Struktur) einlaufen.

In Zukunft wird sich dieser Bereich sicherlich noch füllen. Bis dorthin – wenn man mit eigenen Clients arbeiten möchte – muss man den Weg über Client-Templates gehen. Heißt:

  • Entweder gibt es für den vorgesehenen Zweck schon ein Template, welches man importieren kann.
  • Oder man erstellt ein eigenes Template für die eigenen Bedürfnisse.

Zum letzten Punkt schauen wir uns kurz an, was die Minimal-Anforderungen sind. Wenn du also in der Navigation unter “Vorlagen” gehst und dann unter “Client-Vorlagen” auf “Neu” klickst, dann siehst du im Tab “Code” schon die ersten Zeilen Code:

Client

Die dort enthaltene Zeile…

require('claimRequest')();

…ruft die claimRequest-API auf, mit derer der Client die Anfrage entgegen nehmen soll.

Um “besser” damit zu arbeiten, kann der API-Aufruf gerne in einer Konstante gespeichert werden:

const claimRequest = require('claimRequest')();

Aufgerufen kann die API dann im folgenden nur mit “claimRequest();”. Und das ist auch schon das Minimal-Kriterium für den Client – also die “Beanspruchung” des einlaufenden Requests. Das macht hier natürlich nicht so viel Sinn, da der Client sonst nichts macht. Aber nur zu Demonstrationszwecken einmal gezeigt, was ein Client unbedingt haben muss.

Fangen wir jedoch von vorne an und bauen einen Client mit sinnvollen Minimal-Anforderungen. Grob gesagt wären die “sinnvollen” Minimal-Anforderungen wie folgt:

  1. Der Client beansprucht den HTTP-Request für sich.
  2. Der Client macht was mit dem Request – also verarbeitet die Daten.
  3. Der Client gibt eine Antwort zurück.

Gehen wir also vom folgenden Case aus:

  • Wir möchten einen individuellen Google Analytics Hit an unseren GTM-Server schicken.
  • Der Hit wird an unseren URL-Endpoint sst.domain.com geschickt.
  • Der Client soll nach /hit in der URL Ausschau halten und ihn erst dann beanspruchen.
  • Die angekommenen Daten sollen in das Daten-Modell für Universal Analytics überführt werden.
  • Der Client soll dann eine Antwort zurück liefern, wenn der Vorgang erfolgreich war.

Im ersten Schritt müssen wir zunächst die notwendigen APIs laden:

const claimRequest = require('claimRequest');
const getPathFromRequest = require('getRequestPath');
const getQueryParams = require('getRequestQueryParameters');
const returnResponse = require('returnResponse');
const runContainer = require('runContainer');
const setResponseBody = require('setResponseBody');
const setResponseStatus = require('setResponseStatus');

Gehen wir nun davon aus, dass unser Request an den GTM-Server wie folgt aussieht:

https://sst.domain.com/hit/?cid=12345&en=page_view&lg=en_us

In diesem Fall müssen wir dem Client beibringen, dass er diesen Request beanspruchen soll. Heißt:

if (getPathFromRequest() === '/hit/') {
  claimRequest();
};

Das ist das – wie vorhin schon erwähnt – das absolute Minimum. Der Client beansprucht also den Request für sich. Nun möchten wir wie oben definiert, dass der Client mit dem Request was macht:

  • Konkret: Das der Request verarbeitet wird.
  • Noch konkreter: Das der Hit mit den Parametern in das Daten-Modell von Universal Analytics überführt wird.

Unser Code muss also erweitert werden. Wir werden ein Event-Objekt erstellen, welcher die Werte aus dem Hit “cid=12345&en=page_view&lg=en_us” herausnimmt und sie in die für Google Analytics notwendige Syntax bringt. Das Event-Daten-Modell kannst du hier nachlesen.

Erweitern wir also unseren Code:

if (getPathFromRequest() === '/hit/') {
  claimRequest();
 
  const event = {
    event_name: getQueryParams().en,
    client_id: getQueryParams().cid,
    language: getQueryParams().lg
  };
}

Hier wird mit einem if geprüft, ob der Request in der URL “hit” enthält. Falls ja, dann soll der Client den Request beanspruchen und in ein Event-Objekt überführen. Die Werte aus dem Request werden dabei mit für Universal Analytics notwendigen Syntax gematcht. Zum Schluss wird noch der Container mit den Event-Daten ausgeführt und liefert den erfolgreichen Status Code:

runContainer(event, () => {
  setResponseStatus(200);
  setResponseBody('Request successfully claimed.');
  returnResponse();
  });

Der komplette Code sieht also wie folgt aus:

const claimRequest = require('claimRequest');
const getPathFromRequest = require('getRequestPath');
const getQueryParams = require('getRequestQueryParameters');
const returnResponse = require('returnResponse');
const runContainer = require('runContainer');
const setResponseBody = require('setResponseBody');
const setResponseStatus = require('setResponseStatus');
 
if (getPathFromRequest() === '/hit/') {
  claimRequest();
 
  const event = {
    event_name: getQueryParams().en,
    client_id: getQueryParams().cid,
    language: getQueryParams().lg
  };
 
runContainer(event, () => {
  setResponseStatus(200);
  setResponseBody('Request successfully claimed.');
  returnResponse();
  });
}

Der Code muss nur an der entsprechenden Stelle in der Vorlagen hinzugefügt werden:

Client

Client vs. Tag

Man könnte nun einen GTM-Server haben, der nur mit Clients arbeitet. Der Client könnte dann…

  • …den eingehenden Request für sich beanspruchen.
  • …die Informationen aus dem Requests extrahieren.
  • …die extrahierten Informationen prüfen.
  • …einen HTTP-Request an den gewünschten Endpoint (z.B. Google Analytics) raussenden.
  • …beim Versenden des ausgehenden Requests Header-Informationen mitschicken (z.B. Cookie-Informationen).
  • …eine HTTP-Antwort zurückliefern.

Theoretisch könnte man auch ohne Tags auskommen. Dennoch ist es nicht ratsam die komplette Arbeit den Clients zu überlassen, da dies sehr ineffizient wäre. Für jedes Tracking-Tool bräuchte man dann einen Client:

  • Google Analytics 4 Hit -> Google Analytics 4 Client -> Google Analytics 4-Server
  • Universal Analytics Hit -> Universal Analytics Client -> Universal Analytics Server
  • Facebook Hit -> Facebook Client -> Facebook Server
  • etc.

In diesem Fall müsste z.B. ein GA4-Hit von einem GA4-Client beansprucht werden, um ihn dann an den GA-Server zu schicken. Ziel sollte es – aus Effizienz-Gründen – sein, dass so viele eingehende Requests von so wenigen Clients wie möglich beansprucht werden. Die Daten werden dann jedoch über Tags an die Tracking-Dienst geschickt. Heißt:

  • Google Analytics 4 Hit -> Allgemeiner Client -> Google Analytics 4-Server
  • Universal Analytics Hit -> Allgemeiner Client -> Universal Analytics Server
  • Facebook Hit -> Allgemeiner Client -> Facebook Server
  • etc.

Hier sieht man, dass 1 Client mehrere Requests entgegennimmt und dann weiter als Trigger für die Tags agiert.