Campaign Management · Backend · Bidding

Vom Buchungsklick zur Echtzeit-Ausspielung

Werbetreibende buchen im UZE Ad Manager. Eine Microservice-Plattform auf NestJS prüft und verwaltet die Kampagnen und rechnet sie ab. Bei jeder einzelnen Display-Anfrage wählt sie das passende Werbemittel aus.

NestJS 11TypeScriptMongoDBOpenRTB 2.xUber H3StripeGoogle Cloud
Campaign Management

Kampagnen buchen in neun Schritten

Der Buchungsassistent im Ad Manager führt durch alle Parameter einer Kampagne. Jede Kampagne besteht aus einem oder mehreren Line Items mit genau einem Werbemittel. Das Budget wird gleichmäßig auf die Line Items verteilt.

1
Basis
2
Orte
3
Wetter
4
Display­typen
5
Medien
6
Zeitraum
7
Budget
8
Zusammen­fassung
€
Buchen & bezahlen

Targeting

  • Buchungsgebiete als H3-Waben (Auflösung 8), frei kombinierbar
  • No-Ad-Zonen mit feiner Auflösung 12, z. B. um Schulen oder Kirchen
  • Zeitfenster je Wochentag, minutengenau
  • Wetterbedingungen: Regen, Schnee, Klar, Wolken …
  • Displaytypen nach Format und unterstützten Medien

Preis & Zahlung

  • Abrechnung per CPM, Standard 3,50 € je 1.000 Kontakte
  • 1 Ausspielung = 10 Kontakte, also 3,5 Cent beim Standard-CPM
  • Kartenzahlung über Stripe PaymentIntents oder auf Rechnung
  • Gutscheine als fester Betrag oder Prozent, mit Gültigkeit pro Kunde
  • Private Deals mit eigenem CPM für einzelne Geräte oder Partner

Werbemittel

  • Upload von PNG, APNG, JPEG, MP4 und WebM
  • Automatische Konvertierung mit ffmpeg und ImageMagick, z. B. JPEG → PNG + MP4
  • Thumbnails, EXIF-Rotation, Deduplizierung per SHA-256
  • Template-Motive über Bannerbear mit News, Wetter oder RSS, automatisch aktualisiert

Lebenszyklus mit Freigabe

Jede gebuchte Kampagne durchläuft eine redaktionelle Prüfung: Line-Item-Review und Medien-Audit. Erst nach der Freigabe durch einen Administrator im Configurator wird sie aktiv. Bei einer Ablehnung wird ein Grund vermerkt, etwa politisch, religiös oder ein Verstoß gegen die Richtlinien, und eine Stripe-Zahlung automatisch erstattet. Für einen Motivtausch wird die Kampagne mit dem Restbudget geklont.

Kunden werden per E-Mail benachrichtigt, wenn eine Kampagne freigegeben, abgelehnt, pausiert oder gelöscht wird. Der Versand läuft über SendGrid.

Entwurf→ In Prüfung→ Aktiv
GeplantLäuftAbgelaufen
AbgelehntDeaktiviertGelöschtGeklont
Der Status einer Kampagne ergibt sich aus dem Status ihrer Line Items.

Live-Karte

Positionen, aktuelle Motive und Zähler aller Geräte kommen per WebSocket aus MongoDB Change Streams. Für jede Kampagne gibt es zusätzlich eine Heatmap.

Reporting

Geplante und tatsächliche Kontakte, Ausspielungen, Budget und Laufzeit je Kampagne. Dazu Reichweite als Brutto- und Netto-Kontakte aus der WLAN-Probe-Messung.

Filler & Eigenwerbung

Füllkampagnen springen ein, wenn keine bezahlte Kampagne passt. Social- und Self-Promotion laufen als unbezahlte Line Items.

Bidding-Algorithmus

Welche Werbung läuft jetzt, genau hier?

Bei jeder Display-Anfrage fächert die UZE Ad-Exchange einen OpenRTB-BidRequest an mehrere Bidder auf. Der eigene Bidder rtb-api filtert dabei alle aktiven Line Items in sechs Stufen. Die Simulation unten spielt einen Request durch.

Aktive Line ItemsStatus aktiv, Laufzeit, Budget > 0
–
GeoH3-Zelle im Zielgebiet
–
FormatSeitenverhältnis & MIME-Typ
–
Wetteraktuelle Lage oder Stundenprognose
–
ZeitfensterWochentag & Uhrzeit
–
PacingRückstand zum Soll > 0
–
Gewinner: LI-4711 Bucket: Paid CPM: 3,50 € VAST 2.0 · 10 s · Tracking-URLs

Vier Buckets, klare Reihenfolge

Die verbleibenden Line Items werden in Buckets aufgeteilt. Innerhalb eines Buckets entscheidet zuerst der höhere CPM und danach der größere Rückstand gegenüber dem Ausspielungs-Soll.

Private Dealexklusiv, wenn vorhanden
Paidbezahlte Kampagnen
UnpaidEigen- & Social-Promotion
Fillernur wenn sonst nichts passt

Die Exchange fragt die UZE-Bidder für EU und US sowie angebundene externe Bidder parallel an, mit einem Timeout von 1.250 ms je Bidder. Welches Gebot übernommen wird, regelt eine festgelegte Bidder-Priorität. Wiederholt sich ein Motiv auf demselben Display, wird ein anderes gewählt.

Geo-Targeting mit H3-Waben

Die Plattform rechnet jede gemeldete GPS-Position in Uber-H3-Zellen auf allen 16 Auflösungsstufen um. Liegt das Fahrzeug in einer No-Ad-Zone mit Auflösung 12, wird nicht ausgespielt. Außerhalb aller Buchungsgebiete mit Auflösung 8 ebenfalls nicht. Das Wetter wird pro Zelle mit Auflösung 6 abgefragt und zwischengespeichert.

  • Auflösung 8 ≈ 0,7 km² je Wabe: Stadtteile und Quartiere
  • Auflösung 12 ≈ 300 m² je Wabe: einzelne Grundstücke
  • Kampagnen-Gebiete sind einfache Listen von Zellen, die sich schnell vergleichen lassen
Im Buchungsgebiet (H3 Res 8) → Bid-Request an die Exchange
BuchungsgebietNo-Ad-Zoneaktuelle Position
jetzt Rückstand → höhere Priorität Soll Start Ende Imp.
Soll-VerlaufIst-Verlauf mit Aufholen

Pacing: gleichmäßig über die Laufzeit

Das Budget soll nicht in den ersten Stunden verbraucht sein. Der Algorithmus vergleicht deshalb laufend, wie viele Kontakte ein Line Item zu diesem Zeitpunkt haben sollte, und zählt dabei nur die gebuchten Zeitfenster. Wer im Rückstand ist, wird vorgezogen. Wer im Soll liegt, setzt aus.

soll = geplante Impressions ÷ spielbare Minuten gesamt
ist = verbrauchte Impressions ÷ vergangene spielbare Minuten
fehlend = (soll − ist) × Restminuten der laufenden Stunde
→ fehlend ≤ 0: aussetzen · sonst sortieren nach CPM, dann fehlend

Verbucht wird erst nach der Bestätigung durch das Gerät, über die Billing-Notice. Das Tagesbudget wird jede Nacht um 0 Uhr zurückgesetzt.

Backend-Architektur

13 Services, ein Datenmodell

Das Backend ist ein NestJS-Monorepo. Die Services teilen sich Bibliotheken für Datenmodell, Datenbankzugriff, Auth und Playout-Logik und werden einzeln als Container ausgerollt. Jobs laufen über Agenda auf MongoDB. Live-Daten fließen über MongoDB Change Streams.

CLIENTS Ad ManagerKunden-Frontend (Vue 3) ConfiguratorAdmin-Frontend (Vue 3) Roofbox / SmartboxUZE Player Partner-DisplaysPlayout-API (API-Key) APIs auth-api marketplace-api config-api live-apisocket.io iot-apiPlayout · Sensorik AD-TECH uze-ad-exchangeOpenRTB Fan-out rtb-apiUZE-Bidder EU / US externe BidderOpenRTB / SSP WORKER (AGENDA JOBS) uze-mailer media-processor banner-bear mender-sync vd-manager big-query-sync MongoDB Replica SetDatenmodell · Agenda-Jobs · Change Streams Cloud StorageWerbemittel (CDN) Externe Dienste: Mender · Stripe · SendGrid · Twilio · OpenWeatherMap · Geoapify · Bannerbear

auth-api

Login, Registrierung, Passwort-Flows. JWT über Passport, Passwörter mit bcrypt gehasht. Fünf Rollen von Campaign Manager bis Technical Admin.

marketplace-api

Buchungs-Backend des Ad Managers: Kampagnen, Line Items, Medien-Upload, Stripe-Zahlung, Gutscheine, Reports.

config-api

Admin-Backend: Geräte, Partner, Fahrzeuge, Buchungsgebiete, No-Ad-Zonen, Freigaben, Private Deals, Runtime-Konfiguration.

iot-api

Geräteschnittstelle: Playout-Anfrage, Bestätigung und Ablehnung sowie Sensordaten. Authentisierung per Mender-Fingerprint, Geräte-Token oder Partner-API-Key.

uze-ad-exchange

Baut den OpenRTB-BidRequest, fragt alle aktiven Bidder parallel an und leitet Impressions-Tracking weiter.

rtb-api

Der UZE-Bidder: Filter, Buckets, Pacing, VAST-2.0-Antwort, Win-, Billing- und Loss-Notices sowie Budget-Verbuchung.

live-api

socket.io-Gateway für die Live-Karte: Gerätepositionen, laufende Motive, Kampagnen-Zähler und Heatmaps.

uze-mender-sync

Gleicht jede Minute den Mender-Bestand mit der Geräteverwaltung ab. Mehr dazu unter Device Management.

uze-media-processor

Konvertiert Bild und Video mit ffmpeg und ImageMagick und erzeugt Thumbnails.

uze-banner-bear

Template-Motive über die Bannerbear-API mit Tagesschau-News, Wetter oder RSS. Die News werden werktags alle 15 Minuten aktualisiert.

uze-mailer

E-Mails über SendGrid mit Handlebars-Templates, SMS und WhatsApp über Twilio.

uze-vd-manager

Virtuelle Fahrzeuge fahren hinterlegte Routen mit 10 bis 50 km/h ab und fragen echte Playouts an. Damit lässt sich die Plattform ohne Hardware testen.

Geräteverwaltung im Backend

Jedes Display als Datensatz mit Kontext

Im Configurator verwalten Administratoren den gesamten Bestand. Die meisten Geräte legt die Mender-Synchronisation automatisch an, Partner-Displays registrieren sich beim ersten Aufruf der Playout-API selbst.

IdentitätGeräte-ID, Kit-Seriennummer, MAC, Partner, Fahrzeug mit Kennzeichen, Konzession und Seriennummer-Historie
Typmobile (Roofbox) oder stationary (Smartbox, fester Standort)
DisplaysIndex, Breite × Höhe, unterstützte MIME-Typen, Tags wie Fahrer- oder Beifahrerseite, Default- und Demo-Motive
StandortLetzte Position, H3-Zelle, Heimatgebiet, Stadt, Zeitzone (automatisch über geo-tz)
SensorikKlappenstatus mit Zeitpunkt der letzten Änderung, WLAN-Probe-Zählung
MenderStatus, Fingerprint, letzte Verbindung, Softwarestand, angeschlossene USB-Geräte, Inventar-Snapshot

Bulk-Import & Audit-Log

Geräte lassen sich gesammelt anlegen und ändern. Jede Änderung landet im Audit-Log, auch die automatischen Änderungen durch das System, z. B. „System [Mender]“.

Klappen-Alarm

Ist das Dachdisplay länger als 30 Minuten heruntergeklappt, gehen SMS oder WhatsApp an die hinterlegten Nummern. Klappt es wieder hoch, wird der Alarm automatisch zurückgenommen.

Demo-Modus je Display

Hinterlegte Demo-Motive laufen im 10-Sekunden-Takt, ohne Geo- und Kampagnenprüfung. Damit lässt sich die Verbindung eines neuen Geräts schnell testen.

Technologie-Stack

Die NestJS-Applikation

Laufzeit
Node.js 20 · TypeScript 5.7 · Yarn 3 Workspaces · Monorepo mit 13 Apps und gemeinsamen Libraries
Framework
NestJS 11 auf Express 5 · Nestia (TypedRoute / TypedBody) · typia für Laufzeitvalidierung zur Compile-Zeit · Swagger / OpenAPI generiert
Daten
MongoDB Replica Set über den nativen Treiber, zstd-Kompression, Change Streams, TTL-Indizes · PostgreSQL für WLAN-Analytics · In-Process-TTL-Cache
Jobs
Agenda 6 auf MongoDB, steuerbar, welche Instanzen Jobs abarbeiten · Cron für Tagesbudget, Bannerbear-Updates und Exporte
Echtzeit
socket.io über WebSockets · OpenRTB 2.x · VAST 2.0 mit Quartil-Tracking · Avro-Schemas für Geräte-Payloads
Geo
Uber H3 (h3-js) · geo-tz für Zeitzonen · Geoapify für die Adresssuche · OpenWeatherMap One Call 3.0
Sicherheit
Passport (JWT, Local) · bcrypt · Rollen- und Admin-Guards · Geräte-Auth per SHA-512-Fingerprint des Mender-Schlüssels
Cloud
Google Cloud Storage für Medien · BigQuery · strukturiertes JSON-Logging für Cloud Logging · Docker-Multi-Stage-Images
Delivery
GitLab CI (Lint, Test, Build, Image) · GitOps-Deployment auf GKE in den Regionen EU und US · Jest 29 mit In-Memory-MongoDB

Weiter zur Hardware

Wie Roofbox und Smartbox Werbemittel anfragen, anzeigen und bestätigen.