{
  "id": "ipqRyhJ4zC8H6xUq",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Decodo & Gemini SEO Watchlist (Template)",
  "tags": [],
  "nodes": [
    {
      "id": "3c03c45a-a30b-44dc-a4c5-ef8d414cf58f",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1648,
        80
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "0ab8b4ec-68fa-4687-98d0-d1006a8f7afd",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        -1440,
        80
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"keywords\": [\n      \"keyword_1\",\n      \"keyword_2\",\n      \"keyword_3\"\n  ]\n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "eddf61a3-9199-47d3-b464-e6bbf8590a71",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        -1232,
        80
      ],
      "parameters": {
        "jsCode": "const { keywords } = $json;\n\nreturn keywords.map(k => ({\n  json: { keyword: k }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "e743f378-23b8-4de5-9120-789072b26d32",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -720,
        -80
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "4d60b699-0f27-45a5-ad5a-ed9d85f45a7c",
      "name": "Decodo",
      "type": "@decodo/n8n-nodes-decodo.decodo",
      "position": [
        -464,
        64
      ],
      "parameters": {
        "query": "={{$json.keyword}}",
        "operation": "google_search"
      },
      "typeVersion": 1
    },
    {
      "id": "64582532-ddfe-4d3a-9442-22d53a07e59d",
      "name": "Code in JavaScript1",
      "type": "n8n-nodes-base.code",
      "position": [
        -752,
        96
      ],
      "parameters": {
        "jsCode": "// ---------------------------\n// SAFE DECODO ORGANIC EXTRACTOR\n// Works no matter how Decodo nests the JSON\n// ---------------------------\n\n// 1) Print input to browser console (not n8n UI)\nconsole.log(\"INPUT:\", JSON.stringify($json, null, 2));\n\n// 2) Recursive search function to find ALL \"organic\" arrays\nfunction findOrganic(node, results = []) {\n  if (!node || typeof node !== \"object\") return results;\n\n  if (Array.isArray(node)) {\n    for (const item of node) findOrganic(item, results);\n  } else {\n    for (const key of Object.keys(node)) {\n      if (key === \"organic\" && Array.isArray(node[key])) {\n        results.push(...node[key]);\n      } else {\n        findOrganic(node[key], results);\n      }\n    }\n  }\n  return results;\n}\n\n// 3) Run the extractor\nconst organicItems = findOrganic($json);\n\n// 4) Normalize output\nconst cleaned = organicItems.map(r => ({\n  keyword: $json.keyword || \"\",\n  title: r.title || \"\",\n  url: r.url || \"\",\n  snippet: r.desc || r.snippet || \"\",\n  position: r.pos || null\n}));\n\n// 5) Return as multiple items (this is correct)\nreturn cleaned.map(item => ({ json: item }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "19d1407a-b836-4919-8a91-3495653d9c7e",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        256,
        0
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "df35fb96-6298-49f4-9bd6-8c544b8369fb",
      "name": "Code in JavaScript2",
      "type": "n8n-nodes-base.code",
      "position": [
        -64,
        -160
      ],
      "parameters": {
        "jsCode": "// Combine all incoming items into one object\nconst combined = $input.all().map(item => item.json);\n\nreturn [\n  {\n    json: {\n      chatInput: combined\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "220647e8-2edd-4a79-9dc1-d3afd9499c67",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        272,
        -160
      ],
      "parameters": {
        "options": {
          "systemMessage": "You are an SEO analyst.  \nYou will receive JSON \u201cdata\u201d containing several Google SERP results.\n\nYour job is to produce a **very short, compact SEO analysis**, max 6 lines per result:\n\n1. Intent (short)\n2. Content Type (short)\n3. Strengths (bullet)\n4. Weaknesses (bullet)\n5. Opportunities (bullet)\n\nNo long paragraphs. No storytelling. Only compressed SEO insights.\n"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "67ae3188-cfed-4131-9c8f-ab6b7f349d76",
      "name": "Send a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        624,
        -160
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "={{ $json.output }}",
        "options": {},
        "subject": "Weekly SEO Watchlist \u2014 Automated Report",
        "emailType": "text"
      },
      "typeVersion": 2.1
    },
    {
      "id": "7e087f8b-7fdf-44ca-a6d3-512d6c569532",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1712,
        0
      ],
      "parameters": {
        "color": 4,
        "width": 704,
        "height": 272,
        "content": "Group A: \nThis section initializes the workflow and prepares the keyword list for the search loop."
      },
      "typeVersion": 1
    },
    {
      "id": "743b0539-caec-4f3a-962a-28850d42dd68",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -816,
        -144
      ],
      "parameters": {
        "color": 5,
        "width": 496,
        "height": 464,
        "content": "Group B :\nUsing Decodo API it search Google based on data from previous group to extract and normalize the organic search results."
      },
      "typeVersion": 1
    },
    {
      "id": "3da970f1-3687-4201-8583-c264408d17f2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        -256
      ],
      "parameters": {
        "color": 3,
        "width": 880,
        "height": 256,
        "content": "Group C: \nAggregate the collected search data and pass it to the Google Gemini AI Agent for analysis. and the AI prepares a report to be emailed."
      },
      "typeVersion": 1
    },
    {
      "id": "68808cc2-3f77-430a-bba9-29931ecaa9ef",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2544,
        -192
      ],
      "parameters": {
        "width": 800,
        "height": 528,
        "content": "## How to Set Up **Decodo** Credentials in n8n\n\n### Part 1: Get Your Decodo Authentication Token\n\n* **Activate Your Plan: The Decodo node requires a Web Scraping API Advanced plan. You can begin with a free trial, which is available on the Decodo dashboard.**\n* **Locate Your Token: Once your plan is active, navigate to the Web Scraping API page within your Decodo account.**\n* **Copy Your Token: Find and copy the authentication token generated for you on that page.**\n\n### Part 2: Add the Token to n8n\n\n* **Open n8n Credentials: Inside n8n, open the credentials window.**\n\n* **Create a New Credential: Select the option to create a new credential.**\n\n* **Find the Decodo Type: Search for and select the \"Decodo Credentials API\".**\n\n* **Paste and Save: Enter your authentication token (that you copied from the Decodo dashboard) into the field and save it.**\n\n\n### For detailed instructions : github.com/Decodo/n8n-nodes-decodo/tree/main"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "57b7cf53-4390-4f11-8bee-a5c5c0d5766c",
  "connections": {
    "Decodo": {
      "main": [
        [
          {
            "node": "Code in JavaScript1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Code in JavaScript2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Decodo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript1": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript2": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}