{"id":9303,"date":"2026-08-09T15:37:08","date_gmt":"2026-08-09T13:37:08","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/werkzeuge\/ga4-bot-detector\/"},"modified":"2026-08-28T16:15:09","modified_gmt":"2026-08-28T14:15:09","slug":"ga4-bot-detector","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/","title":{"rendered":"GA4 Bot-Erkennung"},"content":{"rendered":"<p><script src=\"https:\/\/accounts.google.com\/gsi\/client\" async defer><\/script><\/p>\n<div class=\"ga4-bot-detector-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<div class=\"lw-aussenhinweis\" style=\"background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-left: 3px solid #fbbf24; border-radius: 6px; padding: 14px 16px; margin-bottom: 20px;\">\n<div style=\"color: #fbbf24; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 6px;\">Ben\u00f6tigt eine Google-Anmeldung<\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); margin: 0 0 8px; font-size: 0.9rem; line-height: 1.55;\">Anders als die \u00fcbrigen Werkzeuge hier arbeitet dieses nicht f\u00fcr sich allein. Es liest aus der Google Analytics Data API v1 und verlangt daf\u00fcr eine Anmeldung bei Google. Das angeforderte Recht lautet analytics.readonly und ist ausschlie\u00dflich lesend \u2014 \u00e4ndern l\u00e4sst sich dar\u00fcber nichts.<\/p>\n<p style=\"color: var(--text-secondary, #a0a0b0); margin: 0; font-size: 0.9rem; line-height: 1.55;\">Was geholt wird, bleibt in dieser Registerkarte: Die Auswertung l\u00e4uft im Browser, an lukaswojcik.com geht nichts. Die unten vorbelegte OAuth-Client-ID l\u00e4sst sich durch eine eigene ersetzen.<\/p>\n<\/div>\n<p style=\"color: var(--text-secondary); margin-bottom: 20px; line-height: 1.6;\">\n        Verbindet sich per OAuth 2.0 direkt mit der <strong>Google Analytics Data API v1<\/strong> und durchsucht die Verkehrsdimensionen (Betriebssystem, Browser, Land, Quelle\/Medium) nach Crawler-Mustern, Geister-Spam und Bot-Segmenten ohne jede Interaktion.<br \/>\n        Alle heuristischen Auswertungen laufen lokal im Browser &mdash; es werden keinerlei Daten gespeichert oder an unsere Server \u00fcbertragen.\n    <\/p>\n<p>    <!-- SCHRITT 1: OAUTH UND ANMELDUNG --><\/p>\n<div style=\"background: var(--bg-body, #101416); padding: 20px; border-radius: 8px; border: 1px solid var(--border); margin-bottom: 20px;\">\n<h3 style=\"color: var(--accent); font-size: 1rem; margin-top: 0; margin-bottom: 12px;\">1. Anmeldung an der Google Analytics API<\/h3>\n<div style=\"display: flex; gap: 15px; flex-wrap: wrap; align-items: flex-end;\">\n<div style=\"flex: 1; min-width: 280px;\">\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">Google Cloud OAuth-Client-ID:<\/label><br \/>\n                <input type=\"text\" id=\"ga4-client-id\" value=\"423029313598-2ko0jilc28eevp253rqncvodg2181e1l.apps.googleusercontent.com\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); border: 1px solid var(--border); color: var(--text-primary); border-radius: 6px; font-family: monospace;\">\n            <\/div>\n<div>\n                <button id=\"ga4-auth-btn\" class=\"button\" style=\"background: var(--accent); color: var(--on-accent); border: none; padding: 11px 22px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Mit Google autorisieren<\/button>\n            <\/div>\n<\/p><\/div>\n<div data-mp-mask id=\"ga4-auth-status\" style=\"margin-top: 10px; font-size: 0.85rem; color: var(--text-secondary);\">Status: <strong style=\"color: #ff6b6b;\">Nicht verbunden<\/strong><\/div>\n<\/p><\/div>\n<p>    <!-- SCHRITT 2: PROPERTY UND SCAN-EINSTELLUNGEN --><\/p>\n<div id=\"ga4-config-panel\" style=\"background: var(--bg-body); padding: 20px; border-radius: 8px; border: 1px solid var(--border); margin-bottom: 20px; display: none;\">\n<h3 style=\"color: var(--accent); font-size: 1rem; margin-top: 0; margin-bottom: 12px;\">2. Property und Bot-Scan einrichten<\/h3>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 15px;\">\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">GCP-Projektkennung:<\/label><br \/>\n                <input type=\"text\" id=\"gcp-project-id\" value=\"lukaswojcik\" placeholder=\"lukaswojcik\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; font-family: monospace;\">\n            <\/div>\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">GA4-Property-ID (numerisch):<\/label><br \/>\n                <input type=\"text\" id=\"ga4-property-id\" placeholder=\"z. B. 345678901\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; font-family: monospace;\">\n            <\/div>\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">Zeitraum:<\/label><br \/>\n                <select id=\"ga4-timeframe\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px;\"><option value=\"14daysAgo\">Letzte 14 Tage<\/option><option value=\"30daysAgo\" selected>Letzte 30 Tage (empfohlen)<\/option><option value=\"60daysAgo\">Letzte 60 Tage<\/option><\/select>\n            <\/div>\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">Mindestanzahl Sitzungen:<\/label><br \/>\n                <select id=\"ga4-min-sessions\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px;\"><option value=\"5\">ab 5 Sitzungen<\/option><option value=\"10\" selected>ab 10 Sitzungen (Standard)<\/option><option value=\"25\">ab 25 Sitzungen (nur gro\u00dfe Kohorten)<\/option><\/select>\n            <\/div>\n<\/p><\/div>\n<div style=\"display: flex; justify-content: flex-end;\">\n            <button id=\"run-bot-scan-btn\" class=\"button\" style=\"background: var(--accent); color: var(--on-accent); border: none; padding: 11px 26px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Verkehr auf Bot-Kohorten pr\u00fcfen<\/button>\n        <\/div>\n<\/p><\/div>\n<p>    <!-- STATUS- UND ZUSAMMENFASSUNGSLEISTE --><\/p>\n<div data-mp-mask id=\"bot-summary-bar\" style=\"margin-bottom: 20px;\"><\/div>\n<p>    <!-- ERGEBNISBEREICH --><\/p>\n<div data-mp-mask id=\"bot-results-container\"><\/div>\n<\/div>\n<p><script>\n(() => {\n    let accessToken = null;\n    let tokenClient = null;<\/p>\n<p>    const authBtn = document.getElementById(\"ga4-auth-btn\");\n    const authStatus = document.getElementById(\"ga4-auth-status\");\n    const configPanel = document.getElementById(\"ga4-config-panel\");\n    const runScanBtn = document.getElementById(\"run-bot-scan-btn\");\n    const summaryBar = document.getElementById(\"bot-summary-bar\");\n    const resultsContainer = document.getElementById(\"bot-results-container\");<\/p>\n<p>    \/\/ Beschriftung der Schaltfl\u00e4che an einer Stelle halten\n    const SCAN_LABEL = \"Verkehr auf Bot-Kohorten pr\u00fcfen\";<\/p>\n<p>    \/\/ Sichere Unicode-Ersetzung, damit WordPress keine Entities zerlegt\n    const esc = (str) => String(str).replace(\/u0026\/g, \"&amp;\").replace(\/u003c\/g, \"&lt;\").replace(\/u003e\/g, \"&gt;\");<\/p>\n<p>    \/\/ 1. OAUTH-2.0-INITIALISIERUNG\n    authBtn.addEventListener(\"click\", () => {\n        const clientId = document.getElementById(\"ga4-client-id\").value.trim();\n        if (!clientId) {\n            alert(\"Bitte eine g\u00fcltige Google Cloud Client-ID eingeben.\");\n            return;\n        }<\/p>\n<p>        let gsiReady = false;\n        if (window.google) {\n            if (google.accounts) {\n                if (google.accounts.oauth2) {\n                    gsiReady = true;\n                }\n            }\n        }<\/p>\n<p>        if (!gsiReady) {\n            alert(\"Das Skript von Google Identity Services wird noch geladen. Bitte gleich erneut versuchen.\");\n            return;\n        }<\/p>\n<p>        tokenClient = google.accounts.oauth2.initTokenClient({\n            client_id: clientId,\n            scope: \"https:\/\/www.googleapis.com\/auth\/analytics.readonly\",\n            callback: (resp) => {\n                if (resp.error) {\n                    authStatus.innerHTML = \"Status: <strong style='color:#ff6b6b;'>Anmeldefehler: \" + esc(resp.error) + \"<\/strong>\";\n                    return;\n                }\n                accessToken = resp.access_token;\n                authStatus.innerHTML = \"Status: <strong style='color:#51cf66;'>Verbunden (Analytics, nur lesend)<\/strong>\";\n                configPanel.style.display = \"block\";\n            }\n        });\n        tokenClient.requestAccessToken();\n    });<\/p>\n<p>    \/\/ 2. HEURISTIK-MODUL (WP-filtersichere Logik)\n    const evaluateBotBehavior = (row) => {\n        const browser = row.dimensionValues[0].value;\n        const os = row.dimensionValues[1].value;\n        const country = row.dimensionValues[2].value;\n        const sourceMedium = row.dimensionValues[3].value;<\/p>\n<p>        const sessions = Number(row.metricValues[0].value ? row.metricValues[0].value : 0);\n        const pageviews = Number(row.metricValues[1].value ? row.metricValues[1].value : 0);\n        const engagementRate = parseFloat(row.metricValues[2].value ? row.metricValues[2].value : 0);\n        const bounceRate = parseFloat(row.metricValues[3].value ? row.metricValues[3].value : 0);\n        const avgSessionDuration = parseFloat(row.metricValues[4].value ? row.metricValues[4].value : 0);<\/p>\n<p>        const viewsPerSession = sessions > 0 ? pageviews \/ sessions : 0;<\/p>\n<p>        let botScore = 0;\n        const flags = [];<\/p>\n<p>        \/\/ Regel 1: Verkehr ganz ohne Interaktion (0 % bis 2 %)\n        if (engagementRate <= 0.02) {\n            botScore += 40;\n            flags.push(\"Keine Interaktion (\" + (engagementRate * 100).toFixed(1) + \" % aktive Sitzungen)\");\n        }\n\n        \/\/ Regel 2: Einzelseiten-Crawler (genau 1 Seitenaufruf je Sitzung und mindestens 95 % Absprungrate)\n        if (viewsPerSession <= 1.05) {\n            if (bounceRate >= 0.95) {\n                botScore += 35;\n                flags.push(\"Einzelseiten-Crawler (\" + viewsPerSession.toFixed(2) + \" Aufrufe\/Sitzung)\");\n            }\n        }<\/p>\n<p>        \/\/ Regel 3: Sitzungsdauer nahe null\n        if (avgSessionDuration <= 1.0) {\n            botScore += 25;\n            flags.push(\"Sitzungsdauer nahe null (\" + avgSessionDuration.toFixed(1) + \" s)\");\n        }\n\n        \/\/ Regel 4: Verd\u00e4chtige Kombinationen aus Betriebssystem und Browser\n        \/\/ Achtung: Die Vergleichswerte stammen aus der GA4-API und bleiben englisch.\n        const lowBrowser = browser.toLowerCase();\n        const lowOs = os.toLowerCase();\n        const suspiciousTerms = [\"bot\", \"crawler\", \"spider\", \"headless\"];\n        let isSuspicious = suspiciousTerms.some(term => lowBrowser.includes(term));\n        if (lowOs.includes(\"linux\")) {\n            isSuspicious = true;\n        }\n        if (isSuspicious) {\n            botScore += 20;\n            flags.push(\"Verd\u00e4chtige Signatur (\" + browser + \" \/ \" + os + \")\");\n        }<\/p>\n<p>        \/\/ Regel 5: Viel direkter Verkehr aus Rechenzentren ohne jede Interaktion\n        \/\/ Achtung: \"(direct)\" ist ein GA4-API-Wert und bleibt unver\u00e4ndert.\n        if (sourceMedium.toLowerCase().includes(\"(direct)\")) {\n            if (engagementRate === 0) {\n                botScore += 15;\n                flags.push(\"Direkter Verkehr ohne Interaktion\");\n            }\n        }<\/p>\n<p>        return {\n            browser: browser,\n            os: os,\n            country: country,\n            sourceMedium: sourceMedium,\n            sessions: sessions,\n            pageviews: pageviews,\n            engagementRate: engagementRate,\n            bounceRate: bounceRate,\n            avgSessionDuration: avgSessionDuration,\n            viewsPerSession: viewsPerSession,\n            score: Math.min(botScore, 100),\n            flags: flags\n        };\n    };<\/p>\n<p>    const getSeverityBadge = (score) => {\n        if (score >= 80) {\n            return \"<span style='background:#471a1a; color:#ff6b6b; padding:4px 10px; border-radius:4px; font-size:0.75rem; font-weight:700; text-transform:uppercase;'>Bot kritisch (\" + score + \" %)<\/span>\";\n        }\n        if (score >= 60) {\n            return \"<span style='background:#4b3a1a; color:#ff922b; padding:4px 10px; border-radius:4px; font-size:0.75rem; font-weight:700; text-transform:uppercase;'>Hohe Wahrscheinlichkeit (\" + score + \" %)<\/span>\";\n        }\n        return \"<span style='background:#242b30; color:#a0a6b0; padding:4px 10px; border-radius:4px; font-size:0.75rem; font-weight:700; text-transform:uppercase;'>Mittel (\" + score + \" %)<\/span>\";\n    };<\/p>\n<p>    \/\/ 3. BERICHT \u00dcBER DIE GA4 DATA API ABRUFEN\n    runScanBtn.addEventListener(\"click\", async () => {\n        const propertyId = document.getElementById(\"ga4-property-id\").value.trim().replace(\/^properties\\\/\/i, \"\");\n        const timeframe = document.getElementById(\"ga4-timeframe\").value;\n        const minSessions = parseInt(document.getElementById(\"ga4-min-sessions\").value, 10) || 10;<\/p>\n<p>        if (!propertyId || isNaN(propertyId)) {\n            alert(\"Bitte eine g\u00fcltige numerische GA4-Property-ID eingeben (z. B. 345678901).\");\n            return;\n        }<\/p>\n<p>        runScanBtn.disabled = true;\n        runScanBtn.textContent = \"GA4-Verkehrskohorten werden gepr\u00fcft \u2026\";\n        summaryBar.innerHTML = \"\";\n        resultsContainer.innerHTML = \"\";<\/p>\n<p>        try {\n            const response = await fetch(\"https:\/\/analyticsdata.googleapis.com\/v1beta\/properties\/\" + propertyId + \":runReport\", {\n                method: \"POST\",\n                headers: {\n                    \"Authorization\": \"Bearer \" + accessToken,\n                    \"Content-Type\": \"application\/json\"\n                },\n                body: JSON.stringify({\n                    dateRanges: [{ startDate: timeframe, endDate: \"yesterday\" }],\n                    dimensions: [\n                        { name: \"browser\" },\n                        { name: \"operatingSystem\" },\n                        { name: \"country\" },\n                        { name: \"sessionSourceMedium\" }\n                    ],\n                    metrics: [\n                        { name: \"sessions\" },\n                        { name: \"screenPageViews\" },\n                        { name: \"engagementRate\" },\n                        { name: \"bounceRate\" },\n                        { name: \"averageSessionDuration\" }\n                    ],\n                    limit: 2500\n                })\n            });<\/p>\n<p>            if (!response.ok) {\n                const errJson = await response.json().catch(() => ({}));\n                const errMsg = errJson.error ? errJson.error.message : response.statusText;\n                throw new Error(errMsg);\n            }<\/p>\n<p>            const data = await response.json();\n            const rows = data.rows ? data.rows : [];\n            const totalCohortsScanned = rows.length;<\/p>\n<p>            let totalSessionsScanned = 0;\n            let totalBotSessions = 0;\n            const botCohorts = [];<\/p>\n<p>            rows.forEach(row => {\n                const result = evaluateBotBehavior(row);\n                totalSessionsScanned += result.sessions;<\/p>\n<p>                if (result.sessions >= minSessions) {\n                    if (result.score >= 60) {\n                        botCohorts.push(result);\n                        totalBotSessions += result.sessions;\n                    }\n                }\n            });<\/p>\n<p>            \/\/ Nach Sitzungsvolumen absteigend sortieren\n            botCohorts.sort((a, b) => b.sessions - a.sessions);<\/p>\n<p>            \/\/ 4. ZUSAMMENFASSUNG UND ERGEBNISSE AUSGEBEN\n            summaryBar.innerHTML = [\n                \"<\/p>\n<div style='background:var(--bg-body); padding:16px 20px; border-radius:8px; border:1px solid var(--border); display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:15px;'>\",\n                \"  <\/p>\n<div>\",\n                \"    <span style='color:var(--text-secondary); font-size:0.85rem; display:block;'>Gepr\u00fcfte Verkehrskohorten<\/span>\",\n                \"    <strong style='color:var(--accent); font-size:1.4rem;'>\" + totalCohortsScanned.toLocaleString() + \" Segmente<\/strong>\",\n                \"  <\/div>\n<p>\",\n                \"  <\/p>\n<div>\",\n                \"    <span style='color:var(--text-secondary); font-size:0.85rem; display:block;'>Ausgewertete Sitzungen<\/span>\",\n                \"    <strong style='color:var(--text-primary); font-size:1.4rem;'>\" + totalSessionsScanned.toLocaleString() + \" Sitzungen<\/strong>\",\n                \"  <\/div>\n<p>\",\n                \"  <\/p>\n<div>\",\n                \"    <span style='color:var(--text-secondary); font-size:0.85rem; display:block;'>Markierter Bot-Verkehr<\/span>\",\n                \"    <strong style='color:\" + (botCohorts.length > 0 ? \"#ff6b6b\" : \"#51cf66\") + \"; font-size:1.4rem;'>\" + totalBotSessions.toLocaleString() + \" Sitzungen (\" + botCohorts.length + \" Kohorten)<\/strong>\",\n                \"  <\/div>\n<p>\",\n                \"<\/p><\/div>\n<p>\"\n            ].join(\"\");<\/p>\n<p>            if (botCohorts.length === 0) {\n                resultsContainer.innerHTML = \"<\/p>\n<div style='background:var(--bg-body); padding:30px; border-radius:8px; border:1px solid var(--border); text-align:center; color:#51cf66; font-weight:bold; font-size:1.1rem;'>\u2714 Saubere Property: In \" + totalCohortsScanned + \" Verkehrssegmenten wurden keine automatisierten Crawler- oder Geister-Bot-Kohorten gefunden.<\/div>\n<p>\";\n                return;\n            }<\/p>\n<p>            const cardsHtml = botCohorts.map(b => {\n                const flagsHtml = b.flags.map(f => [\n                    \"<span style='background:rgba(255,107,107,0.12); border:1px solid rgba(255,107,107,0.3); color:#ff6b6b; padding:4px 10px; border-radius:20px; font-size:0.8rem; font-weight:600;'>\" + esc(f) + \"<\/span>\"\n                ].join(\"\")).join(\" \");<\/p>\n<p>                return [\n                    \"<\/p>\n<div style='background:var(--bg-body); border:1px solid var(--border); border-radius:8px; padding:18px; margin-bottom:15px;'>\",\n                    \"  <\/p>\n<div style='display:flex; justify-content:space-between; align-items:flex-start; flex-wrap:wrap; gap:10px; border-bottom:1px solid var(--border); padding-bottom:12px; margin-bottom:12px;'>\",\n                    \"    <\/p>\n<div style='flex:1; min-width:260px;'>\",\n                    \"      <\/p>\n<div style='color:var(--text-secondary); font-size:0.8rem; text-transform:uppercase; font-weight:700; margin-bottom:4px;'>\" + esc(b.country) + \" &bull; \" + esc(b.sourceMedium) + \"<\/div>\n<p>\",\n                    \"      <strong style='color:var(--text-primary); font-size:1.15rem; display:block;'>\" + esc(b.browser) + \" auf \" + esc(b.os) + \"<\/strong>\",\n                    \"    <\/div>\n<p>\",\n                    \"    <\/p>\n<div style='text-align:right;'>\",\n                    \"      <\/p>\n<div style='color:var(--accent); font-weight:700; font-size:1.1rem; margin-bottom:4px;'>\" + b.sessions.toLocaleString() + \" Sitzungen <span style='color:var(--text-secondary); font-size:0.85rem; font-weight:normal;'>(\" + b.pageviews.toLocaleString() + \" Aufrufe)<\/span><\/div>\n<p>\",\n                    \"      \" + getSeverityBadge(b.score),\n                    \"    <\/p><\/div>\n<p>\",\n                    \"  <\/p><\/div>\n<p>\",\n                    \"  <\/p>\n<div style='display:flex; gap:20px; flex-wrap:wrap; margin-bottom:12px; font-family:monospace; font-size:0.85rem; color:var(--text-secondary);'>\",\n                    \"    <\/p>\n<div>Interaktionsrate: <strong style='color:\" + (b.engagementRate === 0 ? \"#ff6b6b\" : \"var(--text-primary)\") + \";'>\" + (b.engagementRate * 100).toFixed(1) + \" %<\/strong><\/div>\n<p>\",\n                    \"    <\/p>\n<div>Absprungrate: <strong style='color:var(--text-primary);'>\" + (b.bounceRate * 100).toFixed(1) + \" %<\/strong><\/div>\n<p>\",\n                    \"    <\/p>\n<div>\u00d8 Dauer: <strong style='color:var(--text-primary);'>\" + b.avgSessionDuration.toFixed(1) + \" s<\/strong><\/div>\n<p>\",\n                    \"    <\/p>\n<div>Aufrufe\/Sitzung: <strong style='color:var(--text-primary);'>\" + b.viewsPerSession.toFixed(2) + \"<\/strong><\/div>\n<p>\",\n                    \"  <\/p><\/div>\n<p>\",\n                    \"  <\/p>\n<div style='display:flex; gap:8px; flex-wrap:wrap; align-items:center;'>\",\n                    \"    <span style='color:var(--text-secondary); font-size:0.8rem; font-weight:600;'>Erkannte Merkmale:<\/span>\",\n                    \"    \" + flagsHtml,\n                    \"  <\/div>\n<p>\",\n                    \"<\/p><\/div>\n<p>\"\n                ].join(\"\");\n            }).join(\"\");<\/p>\n<p>            resultsContainer.innerHTML = [\n                \"<\/p>\n<h3 style='color:var(--text-primary); margin-bottom:15px; font-size:1.15rem;'>Erkannte Bot- und Crawler-Kohorten (\" + botCohorts.length + \")<\/h3>\n<p>\",\n                cardsHtml\n            ].join(\"\");<\/p>\n<p>        } catch (e) {\n            resultsContainer.innerHTML = \"<\/p>\n<div style='background:var(--bg-body); padding:25px; border-radius:8px; border:1px solid #ff6b6b; color:#ff6b6b; font-weight:bold;'>GA4-API-Fehler: \" + esc(e.message) + \"<\/div>\n<p>\";\n        } finally {\n            runScanBtn.disabled = false;\n            runScanBtn.textContent = SCAN_LABEL;\n        }\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Verbindet sich per OAuth mit der GA4 Data API und durchsucht die Verkehrssegmente nach Bot- und Crawler-Kohorten.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":9283,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[92088,92091],"class_list":["post-9303","page","type-page","status-publish","hentry","tag-data-quality-de","tag-google-analytics-4-de"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>GA4 Bot-Erkennung - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GA4 Bot-Erkennung - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Verbindet sich per OAuth mit der GA4 Data API und durchsucht die Verkehrssegmente nach Bot- und Crawler-Kohorten.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-28T14:15:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-bot-detector\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-bot-detector\\\/\",\"name\":\"GA4 Bot-Erkennung - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-08-09T13:37:08+00:00\",\"dateModified\":\"2026-08-28T14:15:09+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-bot-detector\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-bot-detector\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-bot-detector\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/toolbox-2\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"GA4 Bot-Erkennung\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"GA4 Bot-Erkennung - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/","og_locale":"en_US","og_type":"article","og_title":"GA4 Bot-Erkennung - Lukas Wojcik - Blog","og_description":"Verbindet sich per OAuth mit der GA4 Data API und durchsucht die Verkehrssegmente nach Bot- und Crawler-Kohorten.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/","og_site_name":"Lukas Wojcik - Blog","article_modified_time":"2026-08-28T14:15:09+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/","url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/","name":"GA4 Bot-Erkennung - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-08-09T13:37:08+00:00","dateModified":"2026-08-28T14:15:09+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-bot-detector\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/toolbox-2\/"},{"@type":"ListItem","position":3,"name":"GA4 Bot-Erkennung"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9303","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=9303"}],"version-history":[{"count":6,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9303\/revisions"}],"predecessor-version":[{"id":13092,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9303\/revisions\/13092"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9283"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=9303"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=9303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}