{ "name": "Parapharmacy Manual Scraper (Webhook)", "nodes": [ { "parameters": { "httpMethod": "POST", "path": "scrape-parapharmacy", "options": {} }, "id": "webhook-trigger", "name": "Webhook Trigger", "type": "n8n-nodes-base.webhook", "typeVersion": 2, "position": [220, 300], "webhookId": "scrape-parapharmacy" }, { "parameters": { "values": { "string": [ { "name": "queries", "value": "={{ $json.body?.queries || 'crema hidratante cara,protector solar,leche corporal' }}" } ] }, "options": {} }, "id": "set-queries", "name": "Set Queries", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [440, 300] }, { "parameters": { "fieldToSplitOut": "queries", "options": {} }, "id": "split-queries", "name": "Split Queries", "type": "n8n-nodes-base.splitOut", "typeVersion": 1, "position": [660, 300] }, { "parameters": { "method": "GET", "url": "https://www.promofarma.com/es/search?q={{ encodeURIComponent($json.queries) }}", "options": { "timeout": 30000 } }, "id": "scrape-promofarma", "name": "Scrape Promofarma", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [880, 300] }, { "parameters": { "jsCode": "// Extract products from Promofarma HTML\nconst html = $input.first().json.data;\nconst products = [];\n\nconst productRegex = /
]*>([\\s\\S]*?)<\\/div>/gi;\nconst nameRegex = /]*>([^<]+)<\\/h3>/i;\nconst priceRegex = /class=\"price[^\"]*\"[^>]*>([^<]+)<\\/span>/i;\nconst linkRegex = /]*href=\"([^\"]+)\"[^>]*>/i;\n\nlet match;\nwhile ((match = productRegex.exec(html)) !== null) {\n const card = match[1];\n const name = nameRegex.exec(card)?.[1]?.trim();\n const price = priceRegex.exec(card)?.[1]?.trim();\n const link = linkRegex.exec(card)?.[1];\n \n if (name) {\n products.push({\n name,\n price: parseFloat(price?.replace(/[^\\d.,]/g, '').replace(',', '.')) || 0,\n source_url: link?.startsWith('http') ? link : `https://www.promofarma.com${link}`,\n source: 'promofarma',\n source_product_id: link?.match(/\\/p\\/([^/]+)/)?.[1] || Date.now().toString()\n });\n }\n}\n\nreturn products.map(p => ({ json: p }));" }, "id": "extract-promofarma", "name": "Extract Products", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [1100, 300] }, { "parameters": { "method": "POST", "url": "http://parapharmacy-api:3002/api/products/bulk", "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ products: $input.all().map(item => item.json) }) }}", "options": {} }, "id": "send-to-api", "name": "Send to Parapharmacy API", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [1320, 300] }, { "parameters": { "respondWith": "json", "responseBody": "={{ { success: true, products: $input.all().length } }}" }, "id": "respond", "name": "Respond", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.1, "position": [1540, 300] } ], "connections": { "Webhook Trigger": { "main": [ [ { "node": "Set Queries", "type": "main", "index": 0 } ] ] }, "Set Queries": { "main": [ [ { "node": "Split Queries", "type": "main", "index": 0 } ] ] }, "Split Queries": { "main": [ [ { "node": "Scrape Promofarma", "type": "main", "index": 0 } ] ] }, "Scrape Promofarma": { "main": [ [ { "node": "Extract Products", "type": "main", "index": 0 } ] ] }, "Extract Products": { "main": [ [ { "node": "Send to Parapharmacy API", "type": "main", "index": 0 } ] ] }, "Send to Parapharmacy API": { "main": [ [ { "node": "Respond", "type": "main", "index": 0 } ] ] } }, "active": true, "settings": { "executionOrder": "v1" }, "versionId": "1", "tags": [ { "name": "parapharmacy" }, { "name": "scraper" }, { "name": "webhook" } ] }