This workflow corresponds to n8n.io template #15163 — we link there as the canonical source.
This workflow follows the Agent → Google Sheets recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"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
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googlePalmApigoogleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow is built for PrestaShop store owners, eCommerce managers, and digital agencies who need to bulk-generate professional, SEO-optimized product content in Spanish or any other language — without writing a single word manually.
Source: https://n8n.io/workflows/15163/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This automation is designed to help you generate AI-powered music tracks, cover art, and fully rendered music videos — all triggered from a simple Telegram chat and managed via Google Sheets.
This Shopify AI automation is an advanced n8n-powered workflow that transforms Shopify product collections into SEO-optimized blog articles with images, while maintaining full visibility and control t
LinkedIn URL → Scrape → Match → Screen → Decide, all automated
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
This workflow is a fully automated YouTube Shorts production pipeline. It takes the structured output from a video digestion workflow (transcript, key moments, metadata) and produces finished, rendere