{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "892c329c-dce3-424c-bceb-c85293ebf16f",
      "name": "Filter",
      "type": "n8n-nodes-base.filter",
      "position": [
        -2304,
        496
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c7c82a02-9958-4898-832f-6cc8b03a5103",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.Update }}",
              "rightValue": "=Updated"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "68482079-afcd-4379-bcca-c9fe2566189e",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1184,
        368
      ],
      "parameters": {
        "text": "={{ $json.Previous }}\nThis is the Product Name",
        "options": {
          "systemMessage": "You are a PrestaShop Catalog Content and SEO Expert specialized in parapharmacy products for the Spanish market (farmaenvia.com).\n\nYour task: Given a product name or title, research the product and generate complete, SEO-optimized product content in Spanish, ready for PrestaShop.\n\nYou MUST use your web search tool to find accurate product information from trusted sources such as:\n- farmaciasdirect.com\n- manufacturer official websites\n- authorized Spanish pharmacy websites\n\nNEVER fabricate or guess product details. If information cannot be verified, state it is unavailable.\n\n---\n\nOUTPUT RULES \u2014 CRITICAL:\nYou must return ONLY a valid JSON object. No markdown, no backticks, no preamble, no explanation. Just the raw JSON.\n\n---\n\nFIELD RULES:\n\ntitle:\n- Max 60 characters\n- Format: Brand + Product Name + Format/Use\n- Title Case (first letter of each word capitalized)\n- Example: \"ISDIN Fusion Water SPF 50+ 50ml - Protector Solar Facial\"\n\nshort_description:\n- 1\u20132 sentences, max 200 characters\n- What it does and who it is for, in Spanish\n- Example: \"Protector solar ligero para piel sensible del rostro, con SPF 50+. Ideal para uso diario.\"\n\nlong_description:\n- 200\u2013300 words MAXIMUM, never exceed 300 words\n- Must be a single HTML string on one line \u2014 no line breaks, no newlines inside the value\n- Use this exact HTML structure:\n  <p><strong>Qu\u00e9 es y para qu\u00e9 sirve:</strong> [description]<br><strong>Beneficios principales:</strong><br>- [benefit 1]<br>- [benefit 2]<br>- [benefit 3]<br><strong>Modo de uso:</strong> [instructions]<br><strong>Ingredientes:</strong> [main ingredients]<br><strong>Recomendaciones:</strong> [warnings/tips]</p>\n- Do NOT use asterisks, markdown bold, or newline characters inside this field\n\nmeta_title:\n- Max 60 characters\n- Format: Brand + Product Name + Format | Farmaenvia\n- Example: \"ISDIN Fusion Water SPF 50+ 50ml | Farmaenvia\"\n\nmeta_description:\n- 150\u2013160 characters\n- Concise summary with benefits and brand\n- Example: \"Protector solar facial ligero SPF 50+ de ISDIN. Hidrataci\u00f3n, protecci\u00f3n y acabado invisible. Compra r\u00e1pida en Farmaenvia\"\n\nuser_friendly_url:\n- Lowercase, hyphens only, no special characters, descriptive\n- Example: \"protector-solar-isdin-fusion-water-spf50-50ml\"\n\n---\n\nEXAMPLE FULL OUTPUT (return exactly this format, nothing else):\n\n{\n  \"title\": \"ISDIN Fusion Water SPF 50+ 50ml - Protector Solar Facial\",\n  \"short_description\": \"Protector solar ligero para piel sensible del rostro, con SPF 50+. Ideal para uso diario.\",\n  \"long_description\": \"<p><strong>Qu\u00e9 es y para qu\u00e9 sirve:</strong> ISDIN Fusion Water SPF 50+ es un protector solar facial ligero dise\u00f1ado para piel sensible.<br><strong>Beneficios principales:</strong><br>- Alta protecci\u00f3n frente a rayos UVA y UVB<br>- Textura no grasa y r\u00e1pida absorci\u00f3n<br>- Acabado invisible y c\u00f3modo para uso diario<br><strong>Modo de uso:</strong> Aplicar generosamente 30 minutos antes de la exposici\u00f3n solar y repetir cada 2 horas o tras nadar.<br><strong>Ingredientes:</strong> Aqua, Glycerin, Octocrylene.<br><strong>Recomendaciones:</strong> Testado dermatol\u00f3gicamente para piel sensible. Evitar contacto con ojos.</p>\",\n  \"meta_title\": \"ISDIN Fusion Water SPF 50+ 50ml | Farmaenvia\",\n  \"meta_description\": \"Protector solar facial ligero SPF 50+ de ISDIN. Hidrataci\u00f3n, protecci\u00f3n y acabado invisible. Compra r\u00e1pida en Farmaenvia\",\n  \"user_friendly_url\": \"protector-solar-isdin-fusion-water-spf50-50ml\"\n}"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "36009b6b-4cd5-40b4-9fbf-8e086422b1b7",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -1184,
        592
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7bc88fc2-0433-458e-99ee-290bb51b8bc3",
      "name": "Limit",
      "type": "n8n-nodes-base.limit",
      "position": [
        -2080,
        496
      ],
      "parameters": {
        "keep": "lastItems",
        "maxItems": 50
      },
      "typeVersion": 1
    },
    {
      "id": "c636b90f-7d57-4448-8ace-938e66c7179e",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -1024,
        592
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"title\": \"string\",\n  \"short_description\": \"string\",\n  \"long_description\": \"string\",\n  \"meta_title\": \"string\",\n  \"meta_description\": \"string\",\n  \"user_friendly_url\": \"string\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "502b1eeb-e225-4891-a557-a3da5e51deda",
      "name": "Arrange Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -832,
        368
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "02dece47-2dc7-49fb-a8e3-ff4d5eac893d",
              "name": "title",
              "type": "string",
              "value": "={{ $json.output.title }}"
            },
            {
              "id": "3a4e11d1-759f-4c3c-867a-576793e43d92",
              "name": "short_description",
              "type": "string",
              "value": "={{ $json.output.short_description }}"
            },
            {
              "id": "4f11256f-6e31-43e0-9140-7f98addb6782",
              "name": "long_description",
              "type": "string",
              "value": "={{ $json.output.long_description }}"
            },
            {
              "id": "096d60dd-790c-49f9-80b4-97642ee22be1",
              "name": "meta_title",
              "type": "string",
              "value": "={{ $json.output.meta_title }}"
            },
            {
              "id": "4a2f3aa4-0c1b-48cb-aa47-610b0c087159",
              "name": "meta_description",
              "type": "string",
              "value": "={{ $json.output.meta_description }}"
            },
            {
              "id": "9ba535f7-e878-4b62-b170-7ac87f6efbbc",
              "name": "user_friendly_url",
              "type": "string",
              "value": "={{ $json.output.user_friendly_url }}"
            },
            {
              "id": "89949603-3e34-4075-9c82-3940ce8e0df3",
              "name": "row_number",
              "type": "string",
              "value": "={{ $('Loop Over Items').item.json.row_number }}"
            },
            {
              "id": "70d2a30c-83e8-4ad0-9c56-887da9f8651a",
              "name": "productId",
              "type": "string",
              "value": "={{ $('Loop Over Items').item.json.productId }}"
            },
            {
              "id": "b53fcf55-bc09-47a8-a452-f99732db15b8",
              "name": "API_Key",
              "type": "string",
              "value": "Your Api Key Here"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "d0ad5aac-d859-4b86-a2a8-b8f4e99bbe61",
      "name": "Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -1632,
        496
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "6e25a383-bcc1-45cc-b54f-4ebf3309dd5e",
              "name": "row_number",
              "type": "number",
              "value": "={{ $('Limit').item.json.row_number }}"
            },
            {
              "id": "3a4c74ef-26af-44ad-ab14-fcc473a2a186",
              "name": "Previous",
              "type": "string",
              "value": "={{ $('Limit').item.json['Previous Title'] }}"
            },
            {
              "id": "4b2f7465-80c4-41cb-a4e0-d5939992ae09",
              "name": "productId",
              "type": "number",
              "value": "={{ $json.productId }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0b3a912d-e578-49c8-bd79-cf712ee87e74",
      "name": "Get Products",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -2528,
        496
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 712862669,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zms7srrDb0N5ELJbi4OWQswn7ksHwwCPsXJ5-HONRQk/edit#gid=712862669",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1zms7srrDb0N5ELJbi4OWQswn7ksHwwCPsXJ5-HONRQk",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zms7srrDb0N5ELJbi4OWQswn7ksHwwCPsXJ5-HONRQk/edit?usp=drivesdk",
          "cachedResultName": "farmaenvia.com"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "19313f08-596e-4670-948e-f321883f2973",
      "name": "Mannual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -2752,
        496
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "ceca0beb-344b-4f21-bdb9-d6f954c295ca",
      "name": "Get Product ID",
      "type": "n8n-nodes-base.code",
      "position": [
        -1856,
        496
      ],
      "parameters": {
        "jsCode": "// n8n Function Node\n// Input: each item must contain json.Address (URL)\n// Output: productId for EACH item\n\nconst items = $input.all();\n\nreturn items.map(item => {\n  const url = item.json.Address;\n\n  const match = url.match(/\\/(\\d+)-.*\\.html$/);\n\n  if (!match) {\n    throw new Error(`Product ID not found in URL: ${url}`);\n  }\n\n  return {\n    json: {\n      productId: parseInt(match[1], 10),\n      Address: url\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "6a1f92e1-a40a-4aa1-8177-1dc15608f030",
      "name": "Update Product",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -608,
        368
      ],
      "parameters": {
        "url": "=https://farmaenvia.com/admin-api/product/{{ $json.productId }}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={\n  \"type\": \"simple\",\n  \"active\": true,\n  \"names\": {\n    \"es-ES\": \"{{ $json.title }}\"\n  },\n  \"shortDescriptions\": {\n    \"es-ES\": \"{{ $json.short_description }}\"\n  },\n  \"descriptions\": {\n    \"es-ES\": \"{{ $json.long_description }}\"\n  },\n  \"metaTitles\": {\n    \"es-ES\": \"{{ $json.meta_title }}\"\n  },\n  \"metaDescriptions\": {\n    \"es-ES\": \"{{ $json.meta_description }}\"\n  },\n  \"linkRewrites\": {\n    \"es-ES\": \"{{ $json.user_friendly_url }}\"\n  }\n}\n",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $json.API_Key }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "1b2e2f8c-6685-4ded-b6eb-bd6950f4413c",
      "name": "Log In Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -384,
        368
      ],
      "parameters": {
        "columns": {
          "value": {
            "Slug": "={{ $('Arrange Data').item.json.user_friendly_url }}",
            "Title": "={{ $('Arrange Data').item.json.title }}",
            "Update": "Updated",
            "Meta Title": "={{ $('Arrange Data').item.json.meta_title }}",
            "row_number": "={{ $('Arrange Data').item.json.row_number }}",
            "Long Description": "={{ $('Arrange Data').item.json.long_description }}",
            "Meta Description": "={{ $('Arrange Data').item.json.meta_description }}",
            "Short Description": "={{ $('Arrange Data').item.json.short_description }}"
          },
          "schema": [
            {
              "id": "Address",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Previous Title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Previous Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Short Description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Short Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Long Description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Long Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Meta Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Meta Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Meta Description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Meta Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Slug",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Slug",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Update",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Update",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 712862669,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zms7srrDb0N5ELJbi4OWQswn7ksHwwCPsXJ5-HONRQk/edit#gid=712862669",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1zms7srrDb0N5ELJbi4OWQswn7ksHwwCPsXJ5-HONRQk",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zms7srrDb0N5ELJbi4OWQswn7ksHwwCPsXJ5-HONRQk/edit?usp=drivesdk",
          "cachedResultName": "farmaenvia.com"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "acca519a-6c00-4ba3-8372-f36ceb218af6",
      "name": "Wait 8 Sec",
      "type": "n8n-nodes-base.wait",
      "position": [
        -160,
        496
      ],
      "parameters": {
        "amount": 8
      },
      "typeVersion": 1.1
    },
    {
      "id": "96a0697a-6e50-4015-8a97-0a074c4e8eb1",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -1408,
        496
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "4a34025d-7ef6-422f-a908-6be852f62c41",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3296,
        224
      ],
      "parameters": {
        "color": 5,
        "width": 500,
        "height": 572,
        "content": "## \ud83d\udccbAI Agent Auto-Generates & Pushes SEO Metas, Product Content on PrestaShop\n\n### How it works\n1. Reads products from Google Sheets not marked Updated\n2. Limits to 50 products per run\n3. Extracts Product ID from PrestaShop URL\n4. Loops one product at a time\n5. AI Agent researches and generates SEO content in Spanish\n6. Structured Output Parser ensures clean JSON\n7. Updates product in PrestaShop via PATCH API\n8. Logs result back to Google Sheets\n9. Waits 8 seconds between each product\n\n### Setup\n- [ ] Google Sheets OAuth2 credential\n- [ ] PrestaShop Bearer token in Arrange Data node\n- [ ] Google Gemini API credential\n- [ ] Sheet columns: Address, Previous, Title, Short Description, Long Description, Meta Title, Meta Description, Slug, Update"
      },
      "typeVersion": 1
    },
    {
      "id": "f6779993-bd01-42b7-8835-732cd26d8bed",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2768,
        288
      ],
      "parameters": {
        "color": 7,
        "width": 576,
        "height": 364,
        "content": "## 1\ufe0f\u20e3 Trigger & Fetch Products\n\nStarts manually, reads all rows from Google Sheets and filters out products already marked as Updated."
      },
      "typeVersion": 1
    },
    {
      "id": "2aa95518-38d5-4d3d-a576-724d27b76264",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2160,
        288
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 364,
        "content": "## 2\ufe0f\u20e3 Limit & Extract Product ID\n\nTakes last 50 unprocessed rows. Extracts numeric Product ID from the PrestaShop URL using regex."
      },
      "typeVersion": 1
    },
    {
      "id": "34ccd199-fe03-42d4-88e3-905e748e5868",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        224
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 512,
        "content": "## 4\ufe0f\u20e3 Update PrestaShop & Log Result\n\nPATCH request updates the product in PrestaShop. Result is logged back to Google Sheets. Failed updates are marked ERROR so they retry next run. Waits 8 seconds before next product."
      },
      "typeVersion": 1
    },
    {
      "id": "c3651fa5-d58b-4c1c-9e09-ea5564c8b204",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1472,
        224
      ],
      "parameters": {
        "color": 7,
        "width": 1008,
        "height": 500,
        "content": "## 3\ufe0f\u20e3 Loop & AI Content Generation\n\nLoops one product at a time. AI Agent researches the product online and generates all SEO content in Spanish. Structured Output Parser guarantees clean JSON output every time.\n\n\u26a0\ufe0f **Add your PrestaShop Bearer API token in the Arrange Data node \u2192 API_Key field**"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Data": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit": {
      "main": [
        [
          {
            "node": "Get Product ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter": {
      "main": [
        [
          {
            "node": "Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Arrange Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 8 Sec": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Arrange Data": {
      "main": [
        [
          {
            "node": "Update Product",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Products": {
      "main": [
        [
          {
            "node": "Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log In Sheet": {
      "main": [
        [
          {
            "node": "Wait 8 Sec",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Product ID": {
      "main": [
        [
          {
            "node": "Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Product": {
      "main": [
        [
          {
            "node": "Log In Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mannual Trigger": {
      "main": [
        [
          {
            "node": "Get Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}