{
  "id": "1blKL30BZbXvbsoX",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Generative Engine Optimization (GEO) Content Booster",
  "tags": [],
  "nodes": [
    {
      "id": "9b6d6858-99ff-46f2-8d07-5c79465f1bfa",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -64
      ],
      "parameters": {
        "width": 960,
        "height": 944,
        "content": "## Generative Engine Optimization (GEO) Content Booster\n\nThis workflow automatically monitors blog posts or product pages for new/updated content, analyzes Google AI Overviews to identify optimization gaps, auto-generates optimized titles, summaries, and schema markup, and applies these improvements to enhance visibility in AI search results.\n\n### Who's it for\n\u2022 SEO managers optimizing for AI-driven search results\n\u2022 Content teams publishing 5+ articles per week\n\u2022 E-commerce teams managing product page visibility\n\u2022 Digital marketers tracking AI Overview presence\n\n### How it works / What it does\n1. Detects new or updated blog posts / product pages via webhook or schedule\n2. Fetches raw content and existing metadata\n3. Queries Google Search API to analyze AI Overview coverage gaps\n4. AI generates optimized title, meta summary, and JSON-LD schema markup\n5. Pushes improvements back to CMS or target endpoint\n6. Logs all changes and scores to Google Sheet tracker\n\n### How to set up\n1. Import this workflow\n2. Set up credentials (Google Search API, OpenAI/Anthropic, CMS/HTTP, Google Sheets)\n3. Update your site URL and content preferences\n4. Activate workflow\n\n### Requirements\n\u2022 Webhook endpoint or CMS trigger\n\u2022 Google Custom Search API key\n\u2022 OpenAI / Anthropic / Grok API\n\u2022 CMS REST API or target HTTP endpoint\n\u2022 Google Sheets for tracking\n\n### How to customize the workflow\n\u2022 Change AI tone and schema type in the AI node\n\u2022 Modify Python keyword/gap detection logic\n\u2022 Update Google Sheet columns and Sheet ID\n\u2022 Adjust polling interval or wait times"
      },
      "typeVersion": 1
    },
    {
      "id": "7f4d83fb-9773-48ab-92fb-0ecfff25c728",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1072,
        272
      ],
      "parameters": {
        "color": 4,
        "width": 760,
        "height": 500,
        "content": "## 1. Trigger & Content Intake"
      },
      "typeVersion": 1
    },
    {
      "id": "5510df8f-8e5c-42b0-91bf-344bd70cc5e4",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1872,
        256
      ],
      "parameters": {
        "color": 3,
        "width": 1104,
        "height": 640,
        "content": "## 2. AI Overview Gap Analysis"
      },
      "typeVersion": 1
    },
    {
      "id": "c3fb0111-5dfa-4150-9a65-da7587692e48",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3008,
        224
      ],
      "parameters": {
        "color": 6,
        "width": 980,
        "height": 600,
        "content": "## 3. GEO Optimization & Publish"
      },
      "typeVersion": 1
    },
    {
      "id": "ce3f6556-dd5d-4018-8114-796ef1bac83c",
      "name": "Webhook - New or Updated Content",
      "type": "n8n-nodes-base.webhook",
      "position": [
        1232,
        384
      ],
      "parameters": {
        "path": "geo-content-inbound",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 1.1
    },
    {
      "id": "dfce174f-6af6-44dc-9fb5-e0deb48a67d5",
      "name": "Poll CMS for Updated Pages",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1232,
        592
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 */6 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "066195c8-c234-41a9-9355-92737c4c1006",
      "name": "Prepare Content Context",
      "type": "n8n-nodes-base.set",
      "position": [
        1472,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "name": "pageUrl",
              "type": "string",
              "value": "={{ $json.url || $json.body?.url || '' }}"
            },
            {
              "name": "pageTitle",
              "type": "string",
              "value": "={{ $json.title || $json.body?.title || '' }}"
            },
            {
              "name": "pageContent",
              "type": "string",
              "value": "={{ $json.content || $json.body?.content || $json.body || '' }}"
            },
            {
              "name": "pageType",
              "type": "string",
              "value": "={{ $json.type || $json.body?.type || 'blog' }}"
            },
            {
              "name": "existingMeta",
              "type": "string",
              "value": "={{ $json.meta || $json.body?.meta || '' }}"
            },
            {
              "name": "contentId",
              "type": "string",
              "value": "={{ $json.id || $json.body?.id || Date.now().toString() }}"
            },
            {
              "name": "targetKeyword",
              "type": "string",
              "value": "={{ $json.keyword || $json.body?.keyword || '' }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "fe007108-65ab-481c-86cf-6d7c0cb30ea9",
      "name": "Fetch Google AI Overview Data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1888,
        480
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/customsearch/v1?key=YOUR_GOOGLE_API_KEY&cx=YOUR_SEARCH_ENGINE_ID&q={{ encodeURIComponent($json.targetKeyword || $json.pageTitle) }}&num=5",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "bbf69c13-d111-4bd7-a398-bd76adea87bc",
      "name": "Python - Detect GEO Gaps",
      "type": "n8n-nodes-base.code",
      "position": [
        2128,
        480
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "python"
      },
      "typeVersion": 2
    },
    {
      "id": "82e2a78c-bd29-4678-a02c-a5da0f046ec2",
      "name": "Filter Pages Needing Optimization",
      "type": "n8n-nodes-base.filter",
      "position": [
        2352,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "conditions": [
            {
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "leftValue": "={{ $json.hasGeoGap }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "bbe3dc5e-8c38-4dde-af13-5b51209d55aa",
      "name": "Wait 1 - Rate Limit",
      "type": "n8n-nodes-base.wait",
      "position": [
        2528,
        480
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "1d808144-1aa2-4a4b-96dd-41bec42d9795",
      "name": "AI - Generate GEO Optimizations",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2704,
        480
      ],
      "parameters": {
        "text": "=Act as an expert SEO strategist specializing in Generative Engine Optimization (GEO) for Google AI Overviews and AI-driven search results.\n\nPage Details:\nURL: {{ $json.pageUrl }}\nType: {{ $json.pageType }}\nCurrent Title: {{ $json.pageTitle }}\nTarget Keyword: {{ $json.targetKeyword }}\nExisting Meta: {{ $json.existingMeta }}\n\nContent Snippet:\n{{ ($json.pageContent || '').substring(0, 800) }}\n\nIdentified GEO Gaps:\n{{ $json.geoGapSummary || 'Missing structured answers, low entity coverage, weak schema.' }}\n\nTop Competing Snippets from Google:\n{{ $json.competitorSnippets || 'No data available.' }}\n\nYour task:\n1. Write an optimized SEO title (60 chars max) that improves AI Overview inclusion chances.\n2. Write a concise meta description / AI summary (155 chars max) with direct answer format.\n3. Generate a valid JSON-LD schema markup (Article or Product depending on page type) with all recommended fields for AI crawlers.\n4. Provide a GEO score (0-100) estimating the page's current AI Overview readiness.\n\nRespond ONLY in this exact JSON format:\n{\n  \"optimizedTitle\": \"...\",\n  \"optimizedSummary\": \"...\",\n  \"schemaMarkup\": { ... },\n  \"geoScore\": 0,\n  \"recommendations\": \"...\"\n}",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 1.6
    },
    {
      "id": "d9225991-0699-4924-a46a-58094158dff1",
      "name": "JS - Format GEO Output",
      "type": "n8n-nodes-base.code",
      "position": [
        3088,
        480
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const item = $input.item.json;\nlet aiOutput = {};\ntry {\n  const raw = item.output || item.response || item.text || '{}';\n  const clean = raw.replace(/```json|```/g, '').trim();\n  aiOutput = JSON.parse(clean);\n} catch (e) {\n  aiOutput = {\n    optimizedTitle: item.pageTitle || 'Optimized Page Title',\n    optimizedSummary: 'AI-optimized summary pending manual review.',\n    schemaMarkup: {},\n    geoScore: 0,\n    recommendations: 'Manual review required.'\n  };\n}\nreturn {\n  json: {\n    ...item,\n    optimizedTitle: aiOutput.optimizedTitle || '',\n    optimizedSummary: aiOutput.optimizedSummary || '',\n    schemaMarkup: JSON.stringify(aiOutput.schemaMarkup || {}),\n    geoScore: aiOutput.geoScore || 0,\n    recommendations: aiOutput.recommendations || '',\n    status: 'Optimized',\n    processedDate: new Date().toISOString().split('T')[0],\n    processedAt: new Date().toISOString()\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "055ae27e-7cde-412c-b81e-e5ae4b573bae",
      "name": "Wait 2 - Review Buffer",
      "type": "n8n-nodes-base.wait",
      "position": [
        3248,
        480
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "d70f0144-b884-4d7f-802a-1b3279fba463",
      "name": "Push Optimizations to CMS",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3472,
        384
      ],
      "parameters": {
        "url": "=https://your-cms-api.com/api/pages/{{ $json.contentId }}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={\n  \"title\": \"{{ $json.optimizedTitle }}\",\n  \"meta_description\": \"{{ $json.optimizedSummary }}\",\n  \"schema_markup\": {{ $json.schemaMarkup }},\n  \"geo_optimized\": true,\n  \"geo_score\": {{ $json.geoScore }}\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "3b95bb94-2ac7-473a-96b9-0a541c99d955",
      "name": "Update GEO Tracker Sheet",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3472,
        608
      ],
      "parameters": {
        "url": "https://sheets.googleapis.com/v4/spreadsheets/YOUR_SHEET_ID/values/GEO_Tracker!A1:append?valueInputOption=USER_ENTERED",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"values\": [[\"{{ $json.processedDate }}\", \"{{ $json.pageUrl }}\", \"{{ $json.pageType }}\", \"{{ $json.targetKeyword }}\", \"{{ $json.optimizedTitle }}\", \"{{ $json.geoScore }}\", \"Optimized\", \"{{ $json.recommendations }}\", \"{{ $json.processedAt }}\"]]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "1fe3c865-71d3-4843-80df-c8f6a7d9c84a",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2672,
        704
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "c4f09534-4545-4b2a-ac75-9464e7f9de35",
      "name": "Wait For Data",
      "type": "n8n-nodes-base.wait",
      "position": [
        1680,
        480
      ],
      "parameters": {},
      "typeVersion": 1.1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d72c2ef2-6106-4dd3-93a0-9abb4d64f043",
  "connections": {
    "Wait For Data": {
      "main": [
        [
          {
            "node": "Fetch Google AI Overview Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI - Generate GEO Optimizations",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Wait 1 - Rate Limit": {
      "main": [
        [
          {
            "node": "AI - Generate GEO Optimizations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JS - Format GEO Output": {
      "main": [
        [
          {
            "node": "Wait 2 - Review Buffer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 2 - Review Buffer": {
      "main": [
        [
          {
            "node": "Push Optimizations to CMS",
            "type": "main",
            "index": 0
          },
          {
            "node": "Update GEO Tracker Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Content Context": {
      "main": [
        [
          {
            "node": "Wait For Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Python - Detect GEO Gaps": {
      "main": [
        [
          {
            "node": "Filter Pages Needing Optimization",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll CMS for Updated Pages": {
      "main": [
        [
          {
            "node": "Prepare Content Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Google AI Overview Data": {
      "main": [
        [
          {
            "node": "Python - Detect GEO Gaps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI - Generate GEO Optimizations": {
      "main": [
        [
          {
            "node": "JS - Format GEO Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook - New or Updated Content": {
      "main": [
        [
          {
            "node": "Prepare Content Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Pages Needing Optimization": {
      "main": [
        [
          {
            "node": "Wait 1 - Rate Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}