{
  "id": "pIU4FdK9iQpgw6lx",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Extract, Summarize, Sentiment Analysis of Price Drops for Amazon Products via Decodo",
  "tags": [
    {
      "id": "Kujft2FOjmOVQAmJ",
      "name": "Engineering",
      "createdAt": "2025-04-09T01:31:00.558Z",
      "updatedAt": "2025-04-09T01:31:00.558Z"
    },
    {
      "id": "ZOwtAMLepQaGW76t",
      "name": "Building Blocks",
      "createdAt": "2025-04-13T15:23:40.462Z",
      "updatedAt": "2025-04-13T15:23:40.462Z"
    },
    {
      "id": "ddPkw7Hg5dZhQu2w",
      "name": "AI",
      "createdAt": "2025-04-13T05:38:08.053Z",
      "updatedAt": "2025-04-13T05:38:08.053Z"
    }
  ],
  "nodes": [
    {
      "id": "2b808791-791d-4c97-969d-d1671564230e",
      "name": "When clicking \u2018Test workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -304,
        -688
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "4876fb18-7db4-4062-9f66-2dc17a251851",
      "name": "Set input fields",
      "type": "n8n-nodes-base.set",
      "position": [
        -112,
        -688
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0ac91db2-9848-40d4-b942-cd7288597ded",
              "name": "price_drop_url",
              "type": "string",
              "value": "https://camelcamelcamel.com/top_drops?t=daily"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "67595908-efad-4799-ab32-c5030ca8cdb8",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        736,
        -688
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "output"
      },
      "typeVersion": 1
    },
    {
      "id": "9a4c555a-45ae-4126-8aa0-dec77c515e9d",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        960,
        -688
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "a47aedbc-e23a-483d-a0ad-cbe84a5f0f08",
      "name": "Sentiment Analysis",
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "position": [
        1536,
        -512
      ],
      "parameters": {
        "text": "=Perform a detailed sentiment analysis on the following content:  {{ $json.results[0].content }}\n\nYour task is to:\n\n1. Determine overall sentiment\n\nClassify the sentiment strictly as:\npositive, neutral, or negative\n\nBase the classification on the dominant emotional tone of the text.\n\n2. Compute a sentiment polarity score\n\nProvide a numeric score between -1 and 1, where:\n\n-1 = very negative\n\n0 = neutral\n\n1 = very positive\n\nScore must reflect intensity and confidence of sentiment.\n\n3. Extract key topics\n\nIdentify important aspects, themes, or points discussed in the content.\nExamples: battery life, build quality, delivery, support, price, performance, etc.\n\nTopics must be:\n\nconcise\n\nrelevant\n\nnon-duplicated\n\nlowercase unless they are proper nouns\n\nOutput Rules\n\nOutput valid JSON only, following the schema below exactly.\n\nDo not include commentary, markdown, or explanation outside the JSON object.",
        "options": {},
        "schemaType": "manual",
        "inputSchema": "{\n  \"$schema\": \"http://json-schema.org/schema#\",\n  \"title\": \"EcommerceSentimentSubset\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"sentiment\": {\n      \"type\": \"string\",\n      \"enum\": [\"positive\", \"neutral\", \"negative\"],\n      \"description\": \"Categorized sentiment from NLP analysis\"\n    },\n    \"sentimentScore\": {\n      \"type\": \"number\",\n      \"minimum\": -1,\n      \"maximum\": 1,\n      \"description\": \"Numeric sentiment polarity score (-1 = very negative, 1 = very positive)\"\n    },\n    \"topics\": {\n      \"type\": \"array\",\n      \"description\": \"Key aspects mentioned in the review (e.g., battery, build quality, delivery)\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    }\n  }\n}\n"
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "c10604a6-868a-49b7-a4f2-eafe32686eaa",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        1904,
        -608
      ],
      "parameters": {},
      "typeVersion": 3.1
    },
    {
      "id": "4ee0392f-7f59-4d1f-8c64-b8a090e57c91",
      "name": "Update Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2384,
        -448
      ],
      "parameters": {
        "columns": {
          "value": {
            "output": "={{ $json.data.toJsonString() }}"
          },
          "schema": [
            {
              "id": "output",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "output",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "output"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10gAihQMT8-h8Mpehe9j-xxN4oTTpg8qwToI-I-Eauew/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1a1yb4XSMQ0Vs0Rg2RCwrcIVXwDN3ImXW_4OUebURKZI",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1a1yb4XSMQ0Vs0Rg2RCwrcIVXwDN3ImXW_4OUebURKZI/edit?usp=drivesdk",
          "cachedResultName": "Pricedrop Info"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "4e71b068-a290-4334-8e73-cc62668d366c",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        528,
        -464
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"array\",\n  \"items\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"id\": {\n        \"type\": \"string\"\n      },\n      \"title\": {\n        \"type\": \"string\"\n      },\n      \"price\": {\n        \"type\": \"string\"\n      },\n      \"savings\": {\n        \"type\": [\"string\", \"null\"]\n      },\n      \"link\": {\n        \"type\": \"string\"\n      }\n    },\n    \"required\": [\"id\", \"title\", \"price\", \"link\"]\n  }\n}\n"
      },
      "typeVersion": 1.2
    },
    {
      "id": "f2d73087-0763-4c18-9d38-576d40b31449",
      "name": "Structure Data Extract Using LLM",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        336,
        -688
      ],
      "parameters": {
        "text": "=Extract clean, structured JSON data from the following text:\n\n{{ $json.results[0].content }}\n\nYour goal is to identify all product entries and convert them into a normalized JSON array.",
        "batching": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "retryOnFail": true,
      "typeVersion": 1.7
    },
    {
      "id": "54baaa48-901d-4b26-934c-c5accbd2718b",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        2096,
        -608
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "c3feeb14-e1cc-49ff-a5bc-a39ea37fdefe",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1872,
        -1040
      ],
      "parameters": {
        "color": 7,
        "width": 736,
        "height": 848,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "b6835025-d8a3-4e73-9475-4f267bdf1022",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        -1040
      ],
      "parameters": {
        "color": 7,
        "width": 1128,
        "height": 852,
        "content": "\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a8ed3842-b93a-4129-855b-2d87c5c9e24b",
      "name": "Decodo",
      "type": "@decodo/n8n-nodes-decodo.decodo",
      "position": [
        80,
        -688
      ],
      "parameters": {
        "geo": "=",
        "url": "={{ $json.price_drop_url }}",
        "headless": false,
        "markdown": true
      },
      "credentials": {
        "decodoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ba4495df-dfe5-4ccb-9b06-08dcfa7f5fc4",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        288,
        -448
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d07b1d82-1793-49c5-b4f4-c87f45452200",
      "name": "Decodo Loop Web Scraper",
      "type": "@decodo/n8n-nodes-decodo.decodo",
      "position": [
        1328,
        -672
      ],
      "parameters": {
        "geo": "=",
        "url": "={{ $json.link }}",
        "headless": false,
        "markdown": true
      },
      "credentials": {
        "decodoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "92b5cea7-6a8a-43c4-a19d-a1aaf75cea33",
      "name": "OpenAI Chat Model for Sentiment Analysis",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1552,
        -336
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "50b80423-6a9f-4030-9a67-e3ce7b150ec7",
      "name": "Summarize Content",
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "position": [
        1536,
        -880
      ],
      "parameters": {
        "text": "=Generate a clear, accurate, and comprehensive summary of the following content: - {{ $json.results[0].content }}\n\nYour summary must:\n\nCapture all key points, major themes, and important details.\n\nPreserve the original meaning without introducing assumptions.\n\nBe concise, well-structured, and written in professional language.\n\nEliminate redundancy, filler text, and irrelevant information.\n\nPresent information in a logically organized flow.\n\nEnsure the summary is a single coherent paragraph unless the content requires multiple sections.\n\nDo not include explanations, markdown, or any text outside the JSON object.",
        "options": {},
        "schemaType": "manual",
        "inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"comprehensive_summary\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}"
      },
      "retryOnFail": true,
      "typeVersion": 1.2
    },
    {
      "id": "305690dc-1997-4281-8821-3a61ddc8c95f",
      "name": "OpenAI Chat Model for Summarize Content",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1600,
        -704
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "2a6a5cb8-44b1-450b-9f05-79c088f86b1b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        -1040
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 848,
        "content": "\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "56251a77-b7ba-404c-833f-c4f888a84734",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        -1248
      ],
      "parameters": {
        "color": 3,
        "width": 640,
        "height": 288,
        "content": "## Disclaimer\n\n![Logo](https://cdn.brandfetch.io/idIeG9_eXK/w/100/h/100/theme/dark/icon.jpeg?c=1bxid64Mup7aczewSAYMX&t=1756483136894)\n\nThis workflow is only available on n8n self-hosted as it's making use of the community node for the Decodo Web Scraping"
      },
      "typeVersion": 1
    },
    {
      "id": "103c8fe6-8438-4a63-b3b0-55beaec93ce6",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        -944
      ],
      "parameters": {
        "width": 640,
        "height": 752,
        "content": "## **How It Works**\n\nThis workflow pulls daily Amazon price-drop data from a Decodo-scraped source, extracts structured product information, and then loops through each product to scrape its corresponding page for deeper context. \n\nFor every item, the workflow generates two outputs: a concise summary and a sentiment analysis. All aggregated results are merged and pushed into a Google Sheet, making it easy to monitor trends, compare products, or trigger further automations.\n\n## **Setup**\n\n- Add your Decodo and OpenAI credentials.\n\n- Update the **price_drop_url** in the Set Input Fields node if needed.\n\n- Connect your Google Sheets OAuth credential and map the correct sheet.\n\n- Adjust the summary/sentiment schemas based on the level of detail you need.\n\n\n## **Customize**\n\n* Change the **price_drop_url** URL within the **Set input fields** node\n* Modify extraction schema within the **Structure Data Extract Using LLM** node\n* Adjust summary/sentiment prompts\n* Update Google Sheets mapping\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "6bb72b4f-2d2b-44cb-8ae8-1401067e0e8a",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        -1280
      ],
      "parameters": {
        "color": 6,
        "width": 656,
        "height": 224,
        "content": "## 1. Structured Data Extraction\n\nPerform a structured data extraction using the OpenAI gpt-4.1-mini. \n\n- Analyze and extract the structured data as per the Decodo Web Scraped Content. \n\n- Decodo\u2019s raw scrape is converted into a clean, consistent product structure using OpenAI. This ensures every item has normalized fields (title, price, link, savings, etc.) before entering the loop."
      },
      "typeVersion": 1
    },
    {
      "id": "b5361706-de8a-42d9-a96e-e8ac32c65b91",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        -1280
      ],
      "parameters": {
        "color": 6,
        "width": 1136,
        "height": 224,
        "content": "\n## 2.  Loop and Extract Data\n\nPerform Summarization & Sentiment Analysis with Decodo and OpenAI LLM. \n\n- Each product is processed individually using SplitOut + Batches. \n\n- For every item, the workflow performs a deep Decodo scrape of the product page, then uses OpenAI to generate a structured summary and sentiment analysis. \n\n- This step produces item-level insights used in the final output."
      },
      "typeVersion": 1
    },
    {
      "id": "472decee-f819-4d84-9b0a-3caa01525c1a",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1872,
        -1280
      ],
      "parameters": {
        "color": 6,
        "width": 736,
        "height": 224,
        "content": "## 3. Output Data Handling \n\nMerge, Aggregate and output content to Google Speadsheet. \n\n- Results from summarization and sentiment analysis are merged and aggregated into a single dataset.\n- The workflow then writes each processed item to Google Sheets, providing a structured, continuously updated record of all extracted product insights."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "61b4baa7-e0a8-40a4-bc1b-0f9de57ebbdd",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Decodo": {
      "main": [
        [
          {
            "node": "Structure Data Extract Using LLM",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Update Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Decodo Loop Web Scraper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set input fields": {
      "main": [
        [
          {
            "node": "Decodo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Structure Data Extract Using LLM",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Summarize Content": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sentiment Analysis": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Update Google Sheets": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Decodo Loop Web Scraper": {
      "main": [
        [
          {
            "node": "Sentiment Analysis",
            "type": "main",
            "index": 0
          },
          {
            "node": "Summarize Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Structure Data Extract Using LLM",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Structure Data Extract Using LLM": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Test workflow\u2019": {
      "main": [
        [
          {
            "node": "Set input fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model for Summarize Content": {
      "ai_languageModel": [
        [
          {
            "node": "Summarize Content",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model for Sentiment Analysis": {
      "ai_languageModel": [
        [
          {
            "node": "Sentiment Analysis",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  }
}