Zum Hauptinhalt springen
Kostenlos25 minutesExperte

Serverseitiges Tracking

Senden Sie Ereignisse und Seitenaufrufe direkt vom Server an den Zenovay-Tracking-Endpunkt für Immunität gegen Werbeblocker und vollständige Kontrolle über die Datenerfassung.

server-sideapitrackingbackendprivacy
Zuletzt aktualisiert:

Senden Sie Analyseereignisse direkt vom Backend an Zenovay. Serverseitiges Tracking ist immun gegen Werbeblocker, ermöglicht das Erfassen von Ereignissen, die nur auf dem Server stattfinden (bestätigte Käufe, Webhook-gesteuerte Abonnements), und gibt Ihnen vollständige Kontrolle über das, was gesendet wird.

Warum serverseitiges Tracking?

Vorteile

VorteilBeschreibung
Immunität gegen WerbeblockerEreignisse erreichen Zenovay auch wenn das Client-Skript im Browser blockiert wird
Nur-Server-EreignisseVerfolgen Sie Dinge, die nur serverseitig stattfinden — bestätigte Zahlungen, Cron-Jobs, Webhooks
DatenkontrolleSie entscheiden genau, was gesendet wird
Hybrides TrackingKombinieren Sie mit dem Client-Skript für vollständige Abdeckung

Wann verwenden

  • E-Commerce-Kaufbestätigung (nach Bestätigung durch den Zahlungsanbieter)
  • Backend-Ereignisse (Abonnement erstellt, Abonnement gekündigt)
  • Webhook-gesteuerte Ereignisse (Stripe, Zahlungsanbieter)
  • Hybrides Tracking (Client-Skript zum Browsing + Server für bestätigte Konversionen)

Tracking-Endpunkt

Serverseitige Anfragen verwenden denselben Ingest-Endpunkt wie das Client-Skript. Senden Sie einen POST zum Tracking-Endpunkt mit dem Tracking-Code Ihrer Website im Pfad:

POST https://api.zenovay.com/e/{trackingCode}

Dies ist ein öffentlicher, nicht authentifizierter Endpunkt — er erfordert keinen API-Schlüssel und ist auf jedem Plan offen (es ist derselbe Pfad, auf den das Tracking-Skript sendet). Der Tracking-Code ist derselbe Wert, den Sie im Attribut data-tracking-code Ihres Installationscodes verwenden.

Information

Der Ingest-Endpunkt wird mit dem Browser-Tracker gemeinsam genutzt, daher ist seine Payload wie die Daten strukturiert, die ein Browser senden würde. Das bedeutet, dass einige Felder, die der Browser automatisch ausfüllt — session_id, device_type, browser, os und user_agentvon Ihnen im JSON-Body angegeben werden müssen, wenn Sie vom Server aufrufen. Anfragen, denen diese fehlen, werden abgelehnt.

Erforderliche Felder

Jedes Ereignis, das Sie senden, muss diese Felder im JSON-Body enthalten:

FeldHinweise
session_idEine Zeichenkette mit mindestens 8 Zeichen. Verwenden Sie denselben Wert für Ereignisse, die zu demselben Besuch gehören.
urlEine vollständige, gültige URL (z. B. https://example.com/checkout/success).
device_typez. B. desktop, mobile, tablet oder server.
browserEin Browser-/Client-Name. Verwenden Sie etwas Aussagekräftiges für Server-Traffic (z. B. server).
osEin Betriebssystem-Name (z. B. Linux).
user_agentEine User-Agent-Zeichenkette. Vermeiden Sie generische Bot-ähnliche Agents (curl, python, wget, usw.) — diese werden als Bots gefiltert.

visitor_id ist optional, aber empfohlen (≥8 Zeichen), damit wiederholte Ereignisse an denselben Besucher gebunden sind.

Seitenaufruf vs. Benutzerdefiniertes Ereignis

Die Ereignisart wird mit dem Feld event_type gesetzt:

  • Seitenaufruf — lassen Sie event_type weg (Standard) oder setzen Sie es auf pageview.
  • Benutzerdefiniertes Ereignis — setzen Sie event_type auf custom, geben Sie den Ereignisnamen in event_name ein und alle Metadaten in properties.
# Benutzerdefiniertes Ereignis (z. B. ein bestätigter Kauf)
curl -X POST "https://api.zenovay.com/e/YOUR_TRACKING_CODE" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "custom",
    "event_name": "purchase",
    "url": "https://example.com/checkout/success",
    "referrer": "https://example.com/cart",
    "session_id": "srv-9f2a7c41bd",
    "device_type": "server",
    "browser": "server",
    "os": "Linux",
    "user_agent": "MyApp-Server/1.0",
    "properties": {
      "order_id": "ORD-12345",
      "value": 99.99,
      "currency": "USD"
    }
  }'
# Seitenaufruf
curl -X POST "https://api.zenovay.com/e/YOUR_TRACKING_CODE" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "pageview",
    "url": "https://example.com/products/widget",
    "referrer": "https://google.com/search",
    "session_id": "srv-9f2a7c41bd",
    "device_type": "server",
    "browser": "server",
    "os": "Linux",
    "user_agent": "MyApp-Server/1.0"
  }'

Ein Hinweis zur Geolokalisierung

Bei Browser-Traffic leitet Zenovay den Standort von der IP des verbindenden Besuchers ab. Wenn Sie den Endpunkt von Ihrem Server aufrufen, ist die verbindende IP die Ihres Servers — daher werden Ereignisse nach Ihrer Infrastruktur geortet.

Wenn Sie genaue Geolokalisierung pro Besucher benötigen, führen Sie dieses Tracking clientseitig durch (das Standard-Installationscode-Snippet) oder verwenden Sie den First-Party-Proxy, und reservieren Sie serverseitiges Tracking für Backend-Ereignisse (Käufe, Abonnements), wo der genaue Standort des Benutzers nicht der Punkt ist. Das Hinzufügen eines X-Forwarded-For-Headers bei einem einfachen Server-Aufruf überschreibt nicht die IP des Servers für den öffentlichen Endpunkt.

Implementierungsbeispiele

Node.js / Express

// lib/analytics.js
const TRACKING_CODE = process.env.ZENOVAY_TRACKING_CODE;
const ENDPOINT = `https://api.zenovay.com/e/${TRACKING_CODE}`;

// Basisfelder, die jedes serverseitige Ereignis braucht.
const SERVER_DEFAULTS = {
  device_type: 'server',
  browser: 'server',
  os: 'Linux',
  user_agent: 'MyApp-Server/1.0'
};

async function trackEvent(eventName, { url, sessionId, properties = {} }) {
  const payload = {
    event_type: 'custom',
    event_name: eventName,
    url,
    session_id: sessionId,
    properties,
    ...SERVER_DEFAULTS
  };

  try {
    const response = await fetch(ENDPOINT, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    });
    return response.ok;
  } catch (error) {
    console.error('Analytics error:', error);
    return false;
  }
}

async function trackPageview({ url, sessionId, referrer = '' }) {
  const payload = {
    event_type: 'pageview',
    url,
    referrer,
    session_id: sessionId,
    ...SERVER_DEFAULTS
  };

  try {
    const response = await fetch(ENDPOINT, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    });
    return response.ok;
  } catch (error) {
    console.error('Pageview tracking error:', error);
    return false;
  }
}

module.exports = { trackEvent, trackPageview };

Python (Flask)

# analytics.py
import os
import requests
from flask import request

TRACKING_CODE = os.getenv('ZENOVAY_TRACKING_CODE')
TRACKING_URL = f'https://api.zenovay.com/e/{TRACKING_CODE}'

SERVER_DEFAULTS = {
    'device_type': 'server',
    'browser': 'server',
    'os': 'Linux',
    'user_agent': 'MyApp-Server/1.0',
}

def track_event(event_name, session_id, url, properties=None):
    payload = {
        'event_type': 'custom',
        'event_name': event_name,
        'url': url,
        'session_id': session_id,
        'properties': properties or {},
        **SERVER_DEFAULTS,
    }
    try:
        response = requests.post(TRACKING_URL, json=payload, timeout=5)
        return response.ok
    except Exception as e:
        print(f'Analytics error: {e}')
        return False

def track_pageview(session_id, url, referrer=''):
    payload = {
        'event_type': 'pageview',
        'url': url,
        'referrer': referrer,
        'session_id': session_id,
        **SERVER_DEFAULTS,
    }
    try:
        response = requests.post(TRACKING_URL, json=payload, timeout=5)
        return response.ok
    except Exception as e:
        print(f'Pageview tracking error: {e}')
        return False

PHP

<?php
class ZenovayAnalytics {
    private $trackingUrl;
    private $defaults = [
        'device_type' => 'server',
        'browser'     => 'server',
        'os'          => 'Linux',
        'user_agent'  => 'MyApp-Server/1.0',
    ];

    public function __construct($trackingCode) {
        $this->trackingUrl = "https://api.zenovay.com/e/{$trackingCode}";
    }

    public function trackEvent($eventName, $sessionId, $url, $properties = []) {
        $payload = array_merge([
            'event_type' => 'custom',
            'event_name' => $eventName,
            'url'        => $url,
            'session_id' => $sessionId,
            'properties' => $properties,
        ], $this->defaults);
        return $this->sendRequest($payload);
    }

    public function trackPageview($sessionId, $url, $referrer = '') {
        $payload = array_merge([
            'event_type' => 'pageview',
            'url'        => $url,
            'referrer'   => $referrer,
            'session_id' => $sessionId,
        ], $this->defaults);
        return $this->sendRequest($payload);
    }

    private function sendRequest($payload) {
        $ch = curl_init($this->trackingUrl);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($payload),
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 5
        ]);
        curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return $httpCode >= 200 && $httpCode < 300;
    }
}

// Verwendung
$analytics = new ZenovayAnalytics(getenv('ZENOVAY_TRACKING_CODE'));
$analytics->trackEvent('purchase', 'srv-9f2a7c41bd', 'https://example.com/checkout/success', [
    'order_id' => 'ORD-12345',
    'value'    => 99.99
]);

Hybrides Tracking

Das häufigste Muster: Verfolgen Sie das Browsing mit dem Client-Skript und bestätigen Sie Konversionen vom Server, sobald der Zahlungsanbieter diese bestätigt hat.

// Client-seitig: Verfolgen Sie die Absicht mit dem Zenovay-Skript
window.zenovay('track', 'checkout_started');

// Server-seitig: Verfolgen Sie das bestätigte Ereignis von Ihrem Webhook-Handler
app.post('/webhooks/stripe', async (req, res) => {
  const event = req.body;

  if (event.type === 'checkout.session.completed') {
    await trackEvent('purchase', {
      url: 'https://example.com/checkout/success',
      sessionId: 'srv-' + event.data.object.id.slice(-12),
      properties: {
        order_id: event.data.object.id,
        value: event.data.object.amount_total / 100
      }
    });
  }

  res.sendStatus(200);
});

Bot-Filterung

Zenovay filtert offensichtlichen Bot-Traffic bereits auf der Ingest-Seite, daher werden Ereignisse, die mit generischen Agents wie curl, wget, python oder alles, das gängigen Crawler-Mustern entspricht, gesendet werden, abgelehnt. Daher verwenden die obigen Beispiele einen beschreibenden user_agent für Ihren Server.

Wenn Sie auch echte Client-Anfragen durch Ihr Backend leiten, filtern Sie Crawler vorher heraus, damit Sie die Rate-Limit nicht mit Traffic verbrennen, der ohnehin abgelehnt würde:

function isBot(userAgent) {
  const botPatterns = [
    /bot/i, /crawler/i, /spider/i, /scraper/i,
    /curl/i, /wget/i, /python/i, /java\//i,
    /googlebot/i, /bingbot/i, /yandex/i
  ];
  return botPatterns.some(pattern => pattern.test(userAgent || ''));
}

Ratenbegrenzungen

Der Tracking-Endpunkt hat Ratenbegrenzungen pro IP-Adresse:

  • Burst-Limit: 60 Anfragen pro 10 Sekunden
  • Dauerhaftes Limit: 5.000 Anfragen pro Stunde

Diese Limits gelten speziell für den Tracking-Ingest-Endpunkt, nicht für die REST API (die ein separates, kostenpflichtiges Feature mit eigenen Limits ist).

Fehlerbehebung

Ereignisse erscheinen nicht

Überprüfen Sie:

  • Der Tracking-Code im URL-Pfad ist korrekt.
  • Alle erforderlichen Felder vorhanden (session_id von 8+ Zeichen, gültige url, device_type, browser, os, user_agent). Fehlende Felder geben einen 400 mit einer Liste dessen zurück, was fehlt.
  • Ihr user_agent wird nicht als Bot gefiltert (vermeiden Sie curl, python, usw.).
  • Die IP ist nicht ratenbegrenzt.

Doppelte Ereignisse

Stellen Sie sicher:

  • Sie verfolgen nicht dasselbe Ereignis sowohl client- als auch serverseitig.
  • Webhook-Handler werden nicht mehr als einmal für dasselbe Ereignis ausgelöst.

Geolokalisierung spiegelt Ihren Server wider

Dies ist normal für serverseitige Aufrufe — die verbindende IP ist Ihr Server, nicht der Besucher. Verwenden Sie das Client-Skript (oder einen First-Party-Proxy) für besuchergenaue Geolokalisierung und nutzen Sie serverseitiges Tracking für Backend-Ereignisse, bei denen der Standort nicht das Ziel ist.

Nächste Schritte

War dieser Artikel hilfreich?