---
name: heyapply-ads
description: Heyapply Google Ads recurring audit and optimization. Account context, navigation paths, known UI gotchas, and standard workflow for the Heyapply | CH Search | Bewerbung campaign. Triggers on "Google Ads check", "Ads audit", "Ads optimieren", "Anzeige bearbeiten", "Kampagne prüfen", "Quality Score", "Search Terms Report".
---

# Heyapply Google Ads — Recurring Audit Skill

Compiled from session 2026-05-08 (CSP fix, audit, manual fixes).

## Account context

- **Account ID:** 899-468-8509 (Heyapply)
- **OCID:** 8217148970
- **Login:** pascal.a.beck@gmail.com
- **Campaign:** "Heyapply | CH Search | Bewerbung"
  - **campaignId:** 23824083298
  - **Budget:** CHF 10/day
  - **Target:** Schweiz, Deutsch
  - **Bidding:** Klicks maximieren (Lernphase bis 30 conv → switch zu tCPA)
- **Brand-Campaign:** geplant, noch nicht aufgesetzt (CHF 2/day)

## Conversion actions

| Action | ctId | gtag send_to | Role | Wert |
|---|---|---|---|---|
| Abo-Kauf | 7599833176 | AW-18140933563/sTySCNiA8accELvbospD | Primär (Bidding) | 1 CHF default |
| Registrierung | 7603047504 | AW-18140933563/JNyTCNCYtakcELvbospD | Sekundär (nur Tracking) | Keinen Wert |

GA4: `G-GD5JR7HEC3`. Google Ads: `AW-18140933563`.

## Tracking-Architektur (Code)

| Komponente | Pfad | Funktion |
|---|---|---|
| gtag.js + Consent v2 | `app/layout.tsx` | Default `denied`, wartet 500ms auf CMP |
| ConversionTracker | `components/tracking/conversion-tracker.tsx` | Feuert `Registrierung` + `Abo-Kauf` bei `?welcome=true&session_id=...`. Enhanced Conversions: SHA256-Email als `user_data` |
| GCLID-Capture | `lib/gclid.ts` + `components/tracking/gclid-capture.tsx` | Cookie `heyapply_gclid` (domain `.heyapply.ch`, 30 Tage) |
| Stripe Checkout | `app/api/stripe/checkout/route.ts` + `lib/stripe.ts` | GCLID landet in `session.metadata.gclid` |
| CSP | `middleware.ts` | Whitelist: googletagmanager, google-analytics, doubleclick, googleadservices |

## Standard-URLs

```
Anzeigen-Liste:    https://ads.google.com/aw/ads?campaignId=23824083298&ocid=8217148970&authuser=0
Conversions-Übersicht: https://ads.google.com/aw/conversions?ocid=8217148970&authuser=0
Conversion-Detail: https://ads.google.com/aw/conversions/detail?ocid=8217148970&ctId=<CTID>&authuser=0
Keywords:          https://ads.google.com/aw/keywords?campaignId=23824083298&ocid=8217148970&authuser=0
Asset-Bibliothek:  https://ads.google.com/aw/assetreport/associations?campaignId=23824083298&ocid=8217148970&assetType=all&authuser=0
Neues Asset:       https://ads.google.com/aw/assetlibrary/newasset?ocid=8217148970&authuser=0
Search Terms:      https://ads.google.com/aw/keywords/searchterms?campaignId=23824083298&ocid=8217148970&authuser=0
```

## Recurring audit workflow (alle 7 Tage)

### 1. Performance-Snapshot
- Dashboard: Klicks, Impressionen, CTR, Avg-CPC, Conv-Rate, Cost/Conv
- Vergleich gegen Vorwoche (% Δ)
- Ziel-Benchmarks: CTR ≥ 5%, Conv-Rate ≥ 3%, Cost/Conv ≤ CHF 30

### 2. Search Terms Report
- Suchen nach 0-Conv-Begriffen mit > CHF 5 Spend → Negative Keywords
- Suchen nach High-Conv-Begriffen → als Exact Match Keywords hinzufügen
- Aktuelle Negative Keywords: `vorlage, muster, template, kostenlos, gratis, word, pdf, download, beispiel, modell, model, tabelle, prompt`

### 3. Anzeigen-Health
- **Anzeigeneffektivität:** Ziel "Sehr gut" oder "Hervorragend"
- Wenn "Durchschnittlich" → Headlines/Descriptions ergänzen oder ersetzen
- Final URLs prüfen: alle auf `/bewerbung-erstellen-lassen` (kein 308-Redirect)
- Display-Path: `bewerbung` / `schreiben`

### 4. Asset-Coverage
- Sitelinks: ≥ 4 (haben aktuell)
- Callouts: ≥ 6 (haben 8)
- Structured Snippets: ≥ 1 mit Header "Dienstleistungen"
- Empfohlen: Bild-Erweiterungen + Anruf-Erweiterung

### 5. Smart Bidding-Phase prüfen
- Lernphase (< 30 Conv): Klicks maximieren
- Stable (≥ 30 Conv in 30 Tagen): tCPA mit Ziel-CPA = aktueller Cost/Conv
- Wachstum (≥ 50 Conv): Maximize Conversion Value mit tROAS

## Critical UI gotchas (aus Session 2026-05-08)

### Hover-Pencil zum Edit
Pencil-Icon für Anzeigen-Edit erscheint NUR bei Hover. Chrome MCP Workflow:
```
1. mcp__Claude_in_Chrome__computer action="hover" auf Anzeigen-Zeile (y=Mitte der Anzeige)
2. screenshot
3. Pencil-Icon ist rechts der Anzeigen-Zelle bei x≈810, y=Anzeigen-Zeile
4. left_click auf Pencil
```
NICHT mit `request_access` Browser direkt steuern — Browser-Tier ist "read-only".

### Identitäts-Bestätigung-Dialog
Erscheint bei JEDEM Save kritischer Änderung (Final URL, Anzeigen-Edit, neue RSA, neue Kampagne). Optionen je nach Status:
- "Überspringen" + "Bestätigen" → noch in Grace-Period
- Nur "Abbrechen" + "Bestätigen" → User MUSS bestätigen (öffnet Re-Auth-Flow mit 2FA)

**Workflow:** Wenn nur "Bestätigen" da ist, an User delegieren. Pascal muss selber klicken (kann Auth-Flow nicht automatisieren).

### Pfad-Limit
Display-Path 1 + 2: max 15 Zeichen pro Feld. "erstellen-lassen" ist 16 → Fehler. Verwende "schreiben" (9) oder "erstellen" (9).

### Headline / Description Limits (RSA)
- Headlines: max 30 Zeichen, 3-15 Stück (mind. 8)
- Descriptions: max 90 Zeichen, 2-4 Stück
- Pin-Position: Nur PIN wenn wirklich kritisch (Position 1 = First Headline)

### Callout-Limit
- Max 25 Zeichen pro Callout
- "Auf jede Stelle zugeschnitten" (29) → zu lang, kürze auf "Pro Stelle zugeschnitten" (24)

### Conversion Action: Primär ↔ Sekundär
- Standardzielvorhaben auf Kontoebene (z.B. Registrierung) lassen sich NICHT direkt im Conversion-Settings auf Sekundär switchen via Radio-Button — Wert wird nicht persistiert
- Lösung: Conversion-Übersicht → ⋮-Menü auf Action → "Zu einem anderen Conversion-Zielvorhaben wechseln"
- Faktischer Workaround: Conversion ohne Wert (`Registrierung` = "Keinen Wert verwenden") wird von Smart Bidding mit Wert-Optimierung ohnehin niedriger priorisiert

### Conversions-Übersicht-Page
- Direkt-URL `/aw/conversions/all` = 404
- Korrekt: `/aw/conversions` → scroll runter → "Alle Conversion-Aktionen anzeigen" Link

## Tool-Strategie

### Chrome MCP (preferred)
```
find → form_input         für Inputs (zuverlässig, kein Pixel-Click)
hover → screenshot → click  für Hover-Pencil
scroll_to ref             für Off-Screen Buttons
```

### Vermeiden
- Triple-click + retype auf Material-DOM Inputs (Layout-Shifts möglich)
- Blind clicks ohne vorherige Screenshot-Verifikation
- `mcp__computer-use__*` für Browser (Tier read-only auf Chrome)

## Aktueller Code-Status (Stand 2026-05-09)

Committed in `b8aa446`:
- ✅ CSP whitelist (gtag, doubleclick, posthog)
- ✅ Consent Mode v2 default denied
- ✅ Enhanced Conversions (SHA256 email)
- ✅ GCLID cookie capture (apex + subdomain via `.heyapply.ch`)
- ✅ GCLID → Stripe metadata

Pending (User-Action erforderlich):
- ⚠️ Cookie-Banner / CMP integration (gtag consent update bei accept/reject)
- ⚠️ Server-side Conversion API via Stripe webhook → Google Ads (Enhanced Conversions for Leads)

## Optimierungs-Pipeline (Roadmap)

| Phase | Trigger | Aktion |
|---|---|---|
| Phase 1 | < 30 Conv | Klicks maximieren, Negative Keywords nach SearchTerms-Report |
| Phase 2 | 30+ Conv | Switch zu tCPA, Quality Score Audit |
| Phase 3 | CHF 30+/day Budget | Brand-Kampagne aufsetzen, Vorlage-Intent-Kampagne mit eigener Landing Page |
| Phase 4 | 100+ Conv | Customer Match Audiences (PostHog → Google Ads), Server-side CAPI |

## Wiki-Referenzen

- `wiki/Produkt/Uebersicht.md` → Google Ads section (Status, Tracking-Architektur)
- `wiki/Produkt/Roadmap.md` → Budget-Skalierung, Vorlage-Kampagne Plan
- `wiki/raw/google-ads-audit-2026-05-08.md` → Initial-Audit (Score 28/100)
- `wiki/raw/google-ads-handoff-2026-05-08.md` → Manual Handoff Steps

## Brand-Profile für Copy

- **Tonalität:** Schweizer-präzise, kein Marketing-Sprech, no em-dashes
- **Rechtschreibung:** Schweizer (ss statt ß)
- **USP:** "schreibt CV NEU für jede Stelle" (nicht "anpasst" oder "umformatiert")
- **Trust-Signals:** DSG-konform, Server in der Schweiz, Made in Switzerland
- **Preis-Anker:** ab CHF 14/Monat
- **Zeit-Anker:** "in 3 Minuten statt 3 Stunden"
- **Differenzierung:** vs. Vorlagen (Word/PDF) — wir machen ATS-optimiert, individuell

## Häufige Tasks → Schnell-Anleitung

### Task: "Final URL einer Anzeige fixen"
1. Navigiere zu Anzeigen-Liste-URL
2. Scroll runter zur Anzeigen-Tabelle
3. `hover` auf Anzeigen-Zeile (Mitte der Anzeige)
4. Click Pencil bei x≈810
5. `find` "Finale URL input" → `form_input` neuer URL
6. `find` "Pfad 1 input" → `form_input` "bewerbung"
7. `find` "Pfad 2 input" → `form_input` "schreiben"
8. `find` "Anzeige speichern button" → click
9. Identitäts-Dialog: Pascal muss "Bestätigen" klicken

### Task: "Negative Keywords hinzufügen"
1. Navigiere zu `/aw/keywords/negativekeywords?campaignId=23824083298`
2. Click `+` FAB
3. Modus: "Auszuschließendes Keyword"
4. Textarea: ein Keyword pro Zeile
5. Match-Type: Phrase ("..." mit Anführungszeichen)
6. Save

### Task: "Search Terms Report exportieren"
1. Navigiere zu `/aw/keywords/searchterms`
2. Date-Range: letzte 7 Tage
3. Click "Herunterladen" Icon → CSV
4. Parse mit Bash: `cat *.csv | awk -F',' '$5==0 && $4>5 {print}'` für 0-Conv-Begriffe > CHF 5

### Task: "Neue RSA erstellen"
1. Anzeigen-Liste → `+` FAB → "Anzeige" → wähle Anzeigengruppe
2. 8-15 Headlines (max 30 Zeichen)
3. 2-4 Descriptions (max 90 Zeichen)
4. Final URL: `https://heyapply.ch/bewerbung-erstellen-lassen`
5. Pfad 1: `bewerbung`, Pfad 2: `schreiben`
6. Save → Identitäts-Dialog (Pascal)

## Letzter Audit-Stand

Datum: 2026-05-08
Score: 28/100 (vor Maßnahmen)
Top-Findings:
1. CSP blockierte gtag.js → 0 Conversions getrackt (FIXED)
2. "lebenslauf vorlage" 40% Budget → 13 Negative Keywords (FIXED)
3. Final URL = 308-Redirect → Quality Score-Schaden (PARTIAL FIX)
4. Nur 2 RSAs (Min 3 für Optimierung) → 3 RSA-Kopien fertig im Handoff-Doc
5. Keine Brand-Kampagne → Setup vorbereitet, noch nicht deployed
