{
  "id": "nMN0reA9rvuZwAjK",
  "meta": {
    "instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
    "templateCredsSetupCompleted": true
  },
  "name": "Generate SEO Content Briefs from Chat Input Using AI, DataForSEO, SERP Analysis & Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "cc7d2183-d9b9-4a7c-8806-fdcb0b7600e9",
      "name": "Overview Sticky",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1632,
        -720
      ],
      "parameters": {
        "width": 420,
        "height": 464,
        "content": "## 📝 AI-Powered SEO Content Brief Generator\n\n### How it works\nThis workflow generates comprehensive, data-driven SEO content briefs using real-time keyword research, competitor analysis, and SERP intelligence. An AI agent analyzes search volume, keyword difficulty, content gaps, and competitor strategies to create briefs with quality scoring, versioning, and HTML previews. All briefs are automatically stored in Google Sheets with version control.\n\n### Setup steps\n1. **Connect credentials**: OpenAI API, DataForSEO, SerpAPI, Google Sheets OAuth2\n2. **Configure Google Sheet**: Create sheets named `content_versions` with columns: content_id, version_no, version_id, topic, meta_title, meta_desc, outline, keywords, tone, word_count, cta_ideas, context_used, timestamp\n3. **Set Slack webhook** (optional): Replace webhook URL in \"Send Quality Alert\" node for low-quality brief notifications\n4. **Test the workflow**: Send a topic via chat trigger and review the generated brief\n\n*Note: This workflow uses GPT-4o-mini for cost-effective brief generation with consistent quality.*"
      },
      "typeVersion": 1
    },
    {
      "id": "911f0520-7d91-4799-ba5c-ee1982c1b70f",
      "name": "Input Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1632,
        -240
      ],
      "parameters": {
        "color": 2,
        "width": 512,
        "height": 412,
        "content": "## 🎯 Input Normalization\n\nStandardizes incoming chat messages into a consistent format (intent, topic, content, parameters) for downstream processing."
      },
      "typeVersion": 1
    },
    {
      "id": "795c77cc-e0fc-4f17-b337-3b257372bfea",
      "name": "Keyword Research Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1104,
        -240
      ],
      "parameters": {
        "color": 2,
        "height": 412,
        "content": "## 🔍 Keyword Research\n\nFetches real-time search volume, keyword difficulty, and CPC data from DataForSEO to inform brief recommendations."
      },
      "typeVersion": 1
    },
    {
      "id": "b19ec937-6190-49e7-bc89-0da3f764030e",
      "name": "AI Agent Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        -224
      ],
      "parameters": {
        "color": 2,
        "width": 720,
        "height": 676,
        "content": "## 🤖 AI Brief Generation\n\nThe AI agent combines keyword data, SERP analysis, competitor intelligence, and historical content from Google Sheets to generate comprehensive briefs with structured JSON output."
      },
      "typeVersion": 1
    },
    {
      "id": "fede1c25-bc4f-4df5-9062-5c3c3858181d",
      "name": "Quality & Storage Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        -256
      ],
      "parameters": {
        "color": 2,
        "width": 908,
        "height": 708,
        "content": "## ✅ Quality Control & Storage\n\nCalculates quality scores across SEO, differentiation, and completeness dimensions. Validates briefs against minimum thresholds, generates HTML previews, and stores approved briefs in Google Sheets with version control."
      },
      "typeVersion": 1
    },
    {
      "id": "f148b18c-1712-4c4b-8c6e-1e5d08e770b6",
      "name": "Credentials Info",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        816,
        128
      ],
      "parameters": {
        "color": 3,
        "width": 320,
        "height": 312,
        "content": "## 🔐 Required Credentials\n\n- **OpenAI API**: For GPT-4o-mini brief generation\n- **DataForSEO**: Basic auth for keyword metrics\n- **SerpAPI**: For real-time SERP analysis\n- **Google Sheets OAuth2**: For context retrieval and brief storage\n- **Slack Webhook** (optional): For quality alerts\n\nReplace all placeholder credentials before activating."
      },
      "typeVersion": 1
    },
    {
      "id": "0cfadf9c-3630-4494-8ba7-90812810f532",
      "name": "Short-Term Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -624,
        256
      ],
      "parameters": {
        "sessionKey": "brief-writer-session",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "26e1bb40-3465-46c4-9cbf-3f97477f2d40",
      "name": "AI Agent (Brief Writer)",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -560,
        16
      ],
      "parameters": {
        "text": "=Topic: {{ $('Normalize Input').item.json.intent }}\nIntent: {{ $('Normalize Input').item.json.intent }}\nUser request: {{ $('Normalize Input').item.json.content }}\n\nKeyword Data: {{ $('Get Keyword Metrics').item.json || 'No keyword data' }}\n\nContext (from Sheets): {{ $json.context || 'No context found' }}",
        "options": {
          "systemMessage": "=You are \"Brief Writer Agent\", a senior SEO content strategist AI.\n\nYou have access to:\n1. Keyword metrics (volume, difficulty, CPC)\n2. Deep competitor analysis (headings, word counts)\n3. Content gap opportunities\n4. Internal linking suggestions\n5. Entity and semantic analysis\n6. SERP Intelligence\n7. Historical content from Sheets\n\n🎯 ENHANCED BRIEF GENERATION\n\n**Use Keyword Data:**\n- Prioritize high volume + low difficulty\n- Include CPC for commercial intent\n- Add LSI keywords from entities\n\n**Use Competitor Analysis:**\n- Match or exceed word count by 15-20%\n- Improve on common H2 patterns\n- Exploit competitor weaknesses\n\n**Use Content Gaps:**\n- Create H2s for missed topics\n- Address unanswered PAA questions\n- Include unique angles\n\n**Use Internal Links:**\n- Suggest 3-5 related articles\n- Include anchor text recommendations\n\n📄 VERSIONING\n1. Check Sheets for existing topic\n2. If exists: reuse content_id, increment version_no\n3. If new: create CNT-<timestamp>, version_no = 1\n\n📤 OUTPUT FORMAT\n\n{\n  \"brief\": {\n    \"title\": \"string\",\n    \"meta_description\": \"string\",\n    \"target_keywords\": [\n      {\n        \"keyword\": \"string\",\n        \"volume\": number,\n        \"difficulty\": number,\n        \"priority\": \"primary|secondary\"\n      }\n    ],\n    \"outline\": [\n      {\n        \"h2\": \"string\",\n        \"h3_suggestions\": [\"string\"],\n        \"purpose\": \"competitor_match|content_gap|paa_answer\"\n      }\n    ],\n    \"word_count\": number,\n    \"tone\": \"string\",\n    \"cta_ideas\": [\"string\"],\n    \"internal_links\": [\n      {\n        \"anchor_text\": \"string\",\n        \"target_content_id\": \"string\",\n        \"relevance_score\": number\n      }\n    ],\n    \"semantic_entities\": [\"string\"],\n    \"content_gaps_addressed\": [\"string\"]\n  },\n  \"competitive_intel\": {\n    \"avg_competitor_word_count\": number,\n    \"top_3_competitors\": [\"string\"],\n    \"our_advantage\": [\"string\"],\n    \"difficulty_assessment\": \"easy|medium|hard\"\n  },\n  \"metadata\": {\n    \"content_id\": \"string\",\n    \"version_no\": number,\n    \"version_id\": \"string\",\n    \"is_new_topic\": boolean\n  },\n  \"quality_scores\": {\n    \"seo_score\": number,\n    \"differentiation_score\": number,\n    \"completeness_score\": number,\n    \"overall_score\": number\n  },\n  \"context_used\": [\"string\"]\n}\n\n📌 RULES\n- Use ALL data sources\n- Data-driven decisions\n- If competitor avg is 2000 words, recommend 2300-2400\n- Address 3+ content gaps\n- Include entities in keywords\n- Calculate quality scores\n- Return JSON ONLY"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "6a888524-27de-400a-ac65-795ac9c39d59",
      "name": "Structured JSON Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -240,
        256
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"brief\": {\n    \"title\": \"string\",\n    \"meta_description\": \"string\",\n    \"target_keywords\": [{\"keyword\": \"string\", \"volume\": 1000, \"difficulty\": 45, \"priority\": \"primary\"}],\n    \"outline\": [{\"h2\": \"string\", \"h3_suggestions\": [\"string\"], \"purpose\": \"content_gap\"}],\n    \"word_count\": 2500,\n    \"tone\": \"string\",\n    \"cta_ideas\": [\"string\"],\n    \"internal_links\": [{\"anchor_text\": \"string\", \"target_content_id\": \"string\", \"relevance_score\": 8}],\n    \"semantic_entities\": [\"string\"],\n    \"content_gaps_addressed\": [\"string\"]\n  },\n  \"competitive_intel\": {\n    \"avg_competitor_word_count\": 2000,\n    \"top_3_competitors\": [\"string\"],\n    \"our_advantage\": [\"string\"],\n    \"difficulty_assessment\": \"medium\"\n  },\n  \"metadata\": {\n    \"content_id\": \"CNT-001\",\n    \"version_no\": 1,\n    \"version_id\": \"VER-001\",\n    \"is_new_topic\": true\n  },\n  \"quality_scores\": {\n    \"seo_score\": 8.5,\n    \"differentiation_score\": 7.0,\n    \"completeness_score\": 9.0,\n    \"overall_score\": 8.2\n  },\n  \"context_used\": [\"serp\", \"keywords\", \"competitors\", \"sheets\"]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "2f106b07-7da8-4c1b-bdb5-7a9149102fbf",
      "name": "Retrieve Historical Content Context",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        -496,
        256
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 2120745354,
          "cachedResultName": "content_versions"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1fsnnXsU1n-iX-MEpLuw3XC6wHD-ek6OlkQe31ousk84",
          "cachedResultName": "SEO Content Automation"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "485c1a47-f406-49cd-84dd-2a2cb08401b8",
      "name": "Validate Brief Quality",
      "type": "n8n-nodes-base.if",
      "position": [
        208,
        32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "quality-check-1",
              "operator": {
                "type": "number",
                "operation": "largerEqual"
              },
              "leftValue": "={{ $json.output.brief.outline.length }}",
              "rightValue": 5
            },
            {
              "id": "quality-check-2",
              "operator": {
                "type": "number",
                "operation": "largerEqual"
              },
              "leftValue": "={{ $json.output.brief.target_keywords.length }}",
              "rightValue": 3
            },
            {
              "id": "quality-check-3",
              "operator": {
                "type": "number",
                "operation": "largerEqual"
              },
              "leftValue": "={{ $json.output.brief.word_count }}",
              "rightValue": 800
            },
            {
              "id": "quality-check-4",
              "operator": {
                "type": "number",
                "operation": "largerEqual"
              },
              "leftValue": "={{ $json.output.quality_scores.overall_score }}",
              "rightValue": 6
            },
            {
              "id": "7d55c376-2f47-4a12-8379-ab3477c83236",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.output.quality_scores.overall_score }}",
              "rightValue": 8
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "9aa6edbb-ab73-4d74-b74b-76d4394f08b6",
      "name": "Store Brief with Version Control",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        656,
        -80
      ],
      "parameters": {
        "columns": {
          "value": {
            "tone": "={{ $json.output.brief.tone }}",
            "topic": "={{ $('Normalize Input').item.json.topic }}",
            "outline": "={{ JSON.stringify($json.output.brief.outline) }}",
            "keywords": "={{ JSON.stringify($json.output.brief.target_keywords) }}",
            "cta_ideas": "={{ JSON.stringify($json.output.brief.cta_ideas) }}",
            "meta_desc": "={{ $json.output.brief.meta_description }}",
            "timestamp": "={{ $now }}",
            "content_id": "={{ $json.output.metadata.content_id }}",
            "meta_title": "={{ $json.output.brief.title }}",
            "version_id": "={{ $json.output.metadata.version_id }}",
            "version_no": "={{ $json.output.metadata.version_no }}",
            "word_count": "={{ $json.output.brief.word_count }}",
            "context_used": "={{ JSON.stringify($json.output.context_used) }}"
          },
          "schema": [
            {
              "id": "content_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "content_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "version_no",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "version_no",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "version_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "version_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "topic",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "topic",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "meta_title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "meta_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "meta_desc",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "meta_desc",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "outline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "outline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "keywords",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "keywords",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "tone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "tone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "word_count",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "word_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "cta_ideas",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "cta_ideas",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "context_used",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "context_used",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "section",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "html",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "html",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "timestamp"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 2120745354,
          "cachedResultName": "content_versions"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1fsnnXsU1n-iX-MEpLuw3XC6wHD-ek6OlkQe31ousk84",
          "cachedResultName": "SEO Content Automation"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "4ad12b1b-6d88-4e44-9ecf-46c40c0931fb",
      "name": "OpenAI GPT-4o-mini Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -752,
        256
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "credential-id",
          "name": "openAiApi Credential"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8d102000-1d1f-4adc-9d6c-1b4f95894852",
      "name": "Normalize Input",
      "type": "n8n-nodes-base.set",
      "position": [
        -1264,
        16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8ea18d06-f3cb-4988-9015-d1baec5f74c1",
              "name": "intent",
              "type": "string",
              "value": "={{ $json.intent || 'brief' }}"
            },
            {
              "id": "f091b1a0-2d42-4ade-b25d-9d562cad239f",
              "name": "topic",
              "type": "string",
              "value": "={{ $json.topic || $json.chatInput }}"
            },
            {
              "id": "4ce9bf82-c89e-44e8-aca6-4720fdf6dcf7",
              "name": "content",
              "type": "string",
              "value": "={{ $json.content || '' }}"
            },
            {
              "id": "cef206d3-24f5-46c4-bab4-bbe246ef655e",
              "name": "parameter",
              "type": "object",
              "value": "={{ $json.parameter || {} }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6bd7c780-daf0-4044-b79d-83b2aac46eaa",
      "name": "SERP Analysis Tool",
      "type": "@n8n/n8n-nodes-langchain.toolSerpApi",
      "position": [
        -368,
        256
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "serpApi": {
          "id": "credential-id",
          "name": "serpApi Credential"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d729bf90-d5d8-4639-bf1d-95588d7aaf1d",
      "name": "Chat Trigger",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -1552,
        16
      ],
      "webhookId": "7603f4c1-b953-4813-a2de-1152da409e91",
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "cbd4a16a-2bee-429e-b2a6-330147f27264",
      "name": "Fetch Keyword Metrics from DataForSEO",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Fetches search volume, keyword difficulty, and CPC data",
      "position": [
        -1040,
        16
      ],
      "parameters": {
        "url": "https://api.dataforseo.com/v3/keywords_data/google/search_volume/live",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "keywords",
              "value": "=[\"{{ $('Normalize Input').item.json.topic }}\"]"
            },
            {
              "name": "language_code",
              "value": "=en"
            },
            {
              "name": "location_code",
              "value": "=2840"
            }
          ]
        },
        "genericAuthType": "httpBasicAuth"
      },
      "credentials": {
        "httpBasicAuth": {
          "id": "credential-id",
          "name": "httpBasicAuth Credential"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "a45a5bb2-12e3-4667-8700-5fdc6596f07f",
      "name": "Calculate Quality Scores",
      "type": "n8n-nodes-base.code",
      "position": [
        -32,
        32
      ],
      "parameters": {
        "jsCode": "const brief = $input.first().json.output.brief;\nconst competitive = $input.first().json.output.competitive_intel;\n\nlet seoScore = 0;\nif (brief.target_keywords && brief.target_keywords.length >= 5) seoScore += 3;\nif (brief.meta_description && brief.meta_description.length <= 160) seoScore += 2;\nif (brief.title && brief.title.length <= 60) seoScore += 2;\nif (brief.outline && brief.outline.length >= 7) seoScore += 2;\nif (brief.semantic_entities && brief.semantic_entities.length >= 5) seoScore += 1;\n\nlet diffScore = 0;\nif (brief.content_gaps_addressed && brief.content_gaps_addressed.length >= 3) diffScore += 4;\nif (competitive.our_advantage && competitive.our_advantage.length >= 2) diffScore += 3;\nif (brief.word_count > competitive.avg_competitor_word_count) diffScore += 3;\n\nlet completeScore = 0;\nif (brief.outline && brief.outline.length >= 5) completeScore += 2;\nif (brief.cta_ideas && brief.cta_ideas.length >= 2) completeScore += 2;\nif (brief.internal_links && brief.internal_links.length >= 3) completeScore += 2;\nif (brief.target_keywords && brief.target_keywords.length >= 3) completeScore += 2;\nif (brief.semantic_entities && brief.semantic_entities.length >= 5) completeScore += 2;\n\nconst overallScore = ((seoScore + diffScore + completeScore) / 3).toFixed(1);\n\nreturn {\n  json: {\n    ...$input.first().json,\n    output: {\n      ...$input.first().json.output,\n      quality_scores: {\n        seo_score: seoScore,\n        differentiation_score: diffScore,\n        completeness_score: completeScore,\n        overall_score: parseFloat(overallScore)\n      }\n    }\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "cb585b9f-8a79-4fd1-bedd-abb7843d3c08",
      "name": "Send Slack Quality Alert",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        432,
        128
      ],
      "parameters": {
        "url": "https://hooks.slack.com/services/[YOUR_WEBHOOK_URL]",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"text\": \"⚠️ Brief Quality Check Failed\",\n  \"blocks\": [\n    {\n      \"type\": \"section\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*Brief Generation Alert*\\nTopic: {{ $('Normalize Input').item.json.topic }}\\nQuality Score: {{ $('Calculate Quality Scores').item.json.output.quality_scores.overall_score }}\"\n      }\n    }\n  ]\n}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "2927e7c9-a9f5-4899-961f-895d48eee343",
      "name": "Generate HTML Preview",
      "type": "n8n-nodes-base.code",
      "position": [
        432,
        -80
      ],
      "parameters": {
        "jsCode": "const output = $input.first().json.output;\nconst brief = output.brief;\nconst competitive = output.competitive_intel;\nconst quality = output.quality_scores;\nconst metadata = output.metadata;\n\nconst keywordsHtml = brief.target_keywords.map(kw => \n  typeof kw === 'object' \n    ? `<span class=\"keyword ${kw.priority === 'primary' ? 'primary' : ''}\">${kw.keyword} ${kw.volume ? `(${kw.volume})` : ''}</span>`\n    : `<span class=\"keyword\">${kw}</span>`\n).join('');\n\nconst outlineHtml = brief.outline.map(section => \n  typeof section === 'object'\n    ? `<li><strong>${section.h2}</strong> <span class=\"purpose\">${section.purpose || ''}</span>\n       ${section.h3_suggestions && section.h3_suggestions.length > 0 ? `<ul style=\"margin-top: 8px;\">${section.h3_suggestions.map(h3 => `<li style=\"border:none; background:transparent; padding:5px 0;\">${h3}</li>`).join('')}</ul>` : ''}\n       </li>`\n    : `<li>${section}</li>`\n).join('');\n\nconst html = `<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Brief Preview - ${brief.title}</title>\n  <style>\n    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif; max-width: 900px; margin: 40px auto; padding: 20px; background: #f5f7fa; }\n    .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 12px; margin-bottom: 30px; }\n    .header h1 { margin: 0 0 10px 0; font-size: 32px; }\n    .header .meta { opacity: 0.9; font-size: 14px; }\n    .card { background: white; padding: 25px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }\n    .card h2 { margin: 0 0 15px 0; font-size: 20px; color: #2d3748; border-bottom: 2px solid #667eea; padding-bottom: 10px; }\n    .keywords { display: flex; flex-wrap: wrap; gap: 8px; margin: 15px 0; }\n    .keyword { background: #edf2f7; padding: 6px 12px; border-radius: 20px; font-size: 13px; border: 1px solid #cbd5e0; }\n    .keyword.primary { background: #667eea; color: white; border-color: #667eea; }\n    .outline { list-style: none; padding: 0; }\n    .outline li { padding: 12px; margin: 8px 0; background: #f7fafc; border-left: 4px solid #667eea; border-radius: 4px; }\n    .outline li .purpose { font-size: 11px; color: #718096; margin-left: 10px; background: #edf2f7; padding: 2px 8px; border-radius: 10px; }\n    .scores { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; }\n    .score-box { text-align: center; padding: 20px; background: #f7fafc; border-radius: 8px; border: 2px solid #e2e8f0; }\n    .score-box .number { font-size: 36px; font-weight: bold; color: #667eea; }\n    .score-box .label { font-size: 12px; color: #718096; margin-top: 5px; text-transform: uppercase; }\n  </style>\n</head>\n<body>\n  <div class=\"header\">\n    <h1>${brief.title}</h1>\n    <div class=\"meta\">Content ID: ${metadata.content_id} | Version: ${metadata.version_no} | ${metadata.is_new_topic ? '🆕 New Topic' : '🔄 Updated'}</div>\n  </div>\n  <div class=\"card\">\n    <h2>📊 Quality Scores</h2>\n    <div class=\"scores\">\n      <div class=\"score-box\"><div class=\"number\">${quality.overall_score}</div><div class=\"label\">Overall</div></div>\n      <div class=\"score-box\"><div class=\"number\">${quality.seo_score}</div><div class=\"label\">SEO</div></div>\n      <div class=\"score-box\"><div class=\"number\">${quality.differentiation_score}</div><div class=\"label\">Differentiation</div></div>\n      <div class=\"score-box\"><div class=\"number\">${quality.completeness_score}</div><div class=\"label\">Completeness</div></div>\n    </div>\n  </div>\n  <div class=\"card\">\n    <h2>🎯 Meta Information</h2>\n    <p><strong>Meta Description:</strong></p>\n    <p style=\"background: #f7fafc; padding: 15px; border-radius: 6px;\">${brief.meta_description}</p>\n    <p><strong>Word Count:</strong> ${brief.word_count} | <strong>Tone:</strong> ${brief.tone}</p>\n  </div>\n  <div class=\"card\">\n    <h2>🔑 Target Keywords</h2>\n    <div class=\"keywords\">${keywordsHtml}</div>\n  </div>\n  <div class=\"card\">\n    <h2>📝 Content Outline</h2>\n    <ol class=\"outline\">${outlineHtml}</ol>\n  </div>\n  <div class=\"card\">\n    <h2>🏆 Competitive Intelligence</h2>\n    <p><strong>Avg Competitor Words:</strong> ${competitive.avg_competitor_word_count || 'N/A'}</p>\n    <p><strong>Difficulty:</strong> ${competitive.difficulty_assessment || 'N/A'}</p>\n  </div>\n</body>\n</html>`;\n\nreturn {\n  json: {\n    html_preview: html,\n    ...output\n  },\n  binary: {\n    preview: {\n      data: Buffer.from(html).toString('base64'),\n      mimeType: 'text/html',\n      fileName: `brief_${metadata.content_id}_${metadata.version_id}.html`\n    }\n  }\n};"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "80898bbe-36e4-470f-87cd-2d6d34d89f44",
  "connections": {
    "Chat Trigger": {
      "main": [
        [
          {
            "node": "Normalize Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Input": {
      "main": [
        [
          {
            "node": "Fetch Keyword Metrics from DataForSEO",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Short-Term Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent (Brief Writer)",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "SERP Analysis Tool": {
      "ai_tool": [
        [
          {
            "node": "AI Agent (Brief Writer)",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Generate HTML Preview": {
      "main": [
        [
          {
            "node": "Store Brief with Version Control",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Brief Quality": {
      "main": [
        [
          {
            "node": "Generate HTML Preview",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Slack Quality Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent (Brief Writer)": {
      "main": [
        [
          {
            "node": "Calculate Quality Scores",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Quality Scores": {
      "main": [
        [
          {
            "node": "Validate Brief Quality",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI GPT-4o-mini Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent (Brief Writer)",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured JSON Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent (Brief Writer)",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve Historical Content Context": {
      "ai_tool": [
        [
          {
            "node": "AI Agent (Brief Writer)",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Keyword Metrics from DataForSEO": {
      "main": [
        [
          {
            "node": "AI Agent (Brief Writer)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}