{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "2c6c13f5-e9a8-494c-988e-11d565a5aca7",
      "name": "Search records",
      "type": "n8n-nodes-base.airtable",
      "position": [
        320,
        144
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appUZW7ajDzzAXOQn",
          "cachedResultUrl": "https://airtable.com/appUZW7ajDzzAXOQn",
          "cachedResultName": "Untitled Base"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tbl4VejzJZ2olbGtr",
          "cachedResultUrl": "https://airtable.com/appUZW7ajDzzAXOQn/tbl4VejzJZ2olbGtr",
          "cachedResultName": "Table 1"
        },
        "options": {},
        "operation": "search",
        "returnAll": "={{ true }}",
        "authentication": "airtableOAuth2Api",
        "filterByFormula": "NOT({Links} = '')"
      },
      "credentials": {
        "airtableOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "12de505f-eb35-45a5-9df2-86b587682036",
      "name": "Decodo",
      "type": "@decodo/n8n-nodes-decodo.decodo",
      "position": [
        528,
        144
      ],
      "parameters": {},
      "credentials": {},
      "retryOnFail": false,
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "940f4cd0-6d58-4536-bcbc-03f7250b5303",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1184,
        368
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.0-flash-lite"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "46e82f12-0c99-4c67-95ae-5cf5cae6005f",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        736,
        144
      ],
      "parameters": {
        "options": {},
        "batchSize": 3
      },
      "typeVersion": 3
    },
    {
      "id": "787e3704-9c6d-409b-a28a-5a762754110d",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1536,
        128
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "json.date",
            "Rating": "json.rating",
            "Reviews": "json.review"
          },
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Reviews",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Reviews",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Rating",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Rating",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JCkvUpgFVG4zo6JYijLAzLH0IyHz2qMP7thdAKrKidk/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1JCkvUpgFVG4zo6JYijLAzLH0IyHz2qMP7thdAKrKidk",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JCkvUpgFVG4zo6JYijLAzLH0IyHz2qMP7thdAKrKidk/edit?usp=drivesdk",
          "cachedResultName": "Reviews"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "dbff0000-6579-4b4a-843f-5063e319dd1b",
      "name": "Schedule Trigger1",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -160,
        768
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "months"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "70c9e137-3a5f-481c-b2c4-259478b7144e",
      "name": "AI Agent1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        480,
        768
      ],
      "parameters": {
        "text": "=You are analyzing customer feedback.\n\nREVIEWS DATA:\n{{ JSON.stringify($json.reviews, null, 2) }}\n\nProvide:\n1. Overall sentiment\n2. Common positive points\n3. Common complaints\n4. Suggested improvements\n",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "44d806ed-b4af-44db-833d-c9f9e00db9c4",
      "name": "Google Gemini Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        368,
        944
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ecd8f3e8-5860-4504-99f5-ed6bb67e9938",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        48,
        768
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JCkvUpgFVG4zo6JYijLAzLH0IyHz2qMP7thdAKrKidk/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1JCkvUpgFVG4zo6JYijLAzLH0IyHz2qMP7thdAKrKidk",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JCkvUpgFVG4zo6JYijLAzLH0IyHz2qMP7thdAKrKidk/edit?usp=drivesdk",
          "cachedResultName": "Reviews"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "d02c5a10-e350-4bc7-b6be-806a120983a3",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        256,
        768
      ],
      "parameters": {
        "jsCode": "const reviews = items.map(item => ({\n  date: item.json.Date,\n  review: item.json.Reviews,\n  rating: item.json.Rating\n}));\n\nconst avgRating =\n  reviews.reduce((sum, r) => sum + r.rating, 0) / reviews.length;\n\nreturn [\n  {\n    json: {\n      reviews: items.map(item => ({\n        date: item.json.Date,\n        review: item.json.Reviews,\n        rating: item.json.Rating\n      }))\n    }\n  }\n];\n\n"
      },
      "typeVersion": 2
    },
    {
      "id": "02beb4ff-98a1-491e-a305-061a06b34ad2",
      "name": "Send a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        800,
        768
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "={{ $json.output }}",
        "options": {},
        "subject": "Reviews Summary"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "d2c14388-00fb-469a-9c9c-c1c8709acf2a",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 528,
        "content": "## Purpose: Controls when the workflow runs\nIncludes:\n\n* Run Daily (review scraping trigger)\n* Scheduled Review Analysis trigger\n* Manages automated execution without manual intervention."
      },
      "typeVersion": 1
    },
    {
      "id": "ebfbf2a9-1cb3-4ac6-9d2d-c72b714b42d2",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        512
      ],
      "parameters": {
        "color": 5,
        "width": 1280,
        "height": 576,
        "content": "## Purpose: Saves data and generates insights\nIncludes:\n\n* Append row in Google Sheets\n* Get row(s) from Google Sheets\n* Code (data structuring)\n* AI Agent (review analysis)\n* Gmail (send summary email)\n* Stores reviews and delivers AI-generated insights."
      },
      "typeVersion": 1
    },
    {
      "id": "209db795-a8ee-4b63-a571-581718438e27",
      "name": "Run Daily",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        112,
        144
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7ed27daa-aa52-4a99-92d8-9db2d682fcaf",
      "name": "Analyzer",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "maxTries": 5,
      "position": [
        1184,
        128
      ],
      "parameters": {
        "text": "=Extract only reviews ratings with dates from {{ $json.results[0].content }}",
        "options": {},
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 2.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "63147c15-893e-432a-bd34-b116ec798590",
      "name": "Delay until next cycle",
      "type": "n8n-nodes-base.wait",
      "position": [
        960,
        272
      ],
      "parameters": {
        "amount": 50
      },
      "typeVersion": 1.1
    },
    {
      "id": "f0338925-b234-43bd-aff0-8a7b7a54bc90",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1296,
        -80
      ],
      "parameters": {
        "width": 1024,
        "height": 608,
        "content": "## How It Works\nThe workflow is divided into two main automated cycles:\n\n### Cycle 1: Collection & Storage\n* Trigger: The Run Daily schedule starts the process.\n* Fetch: It searches Airtable for any records containing new review links.\n* Extract: Decodo visits the links to pull raw content.\n* Structure: The AI Analyzer (Gemini) identifies the specific date, star rating, and text from the raw data.\n* Log: Each review is appended as a new row in Google Sheets, creating a historical database.\n\n### Cycle 2: Insight Generation\n* Analyze: On a separate schedule, the workflow retrieves all stored rows from Google Sheets.\n* Summarize: An AI Agent processes the collective data to identify:\n* Overall sentiment trends.\n* Recurring positive feedback.\n* Top customer complaints and suggested improvements.\n* Report: A formatted summary is sent directly to your inbox via Gmail.\n\n## Setup Steps\n* Prepare your Database: Connect your Airtable account and ensure you have a field (e.g., \"Links\") populated with the URLs you want to monitor.\n* Configure Storage: Connect Google Sheets and select the spreadsheet where you want the reviews to be archived.\n* Activate AI: Add your Google Gemini API Key to the Chat Model nodes.\n* Set Delivery: Connect your Gmail account and update the \"Send to\" field with your preferred email address.\n* Timing: Adjust both Schedule Triggers (one for daily scraping, one for periodic summary reports) to match your team\u2019s reporting cadence."
      },
      "typeVersion": 1
    },
    {
      "id": "23322f87-da08-4cde-90fe-9f6936ede1a8",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        288,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 848,
        "height": 528,
        "content": "## Purpose: Fetches and extracts raw review data\nIncludes:\n* Airtable Search Records\n* Decodo\n* Loop Over Items\n* Delay until next cycle\n\nResponsible for pulling review links and safely processing them in batches."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Decodo": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyzer": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent1": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Daily": {
      "main": [
        [
          {
            "node": "Search records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search records": {
      "main": [
        [
          {
            "node": "Decodo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Analyzer",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Delay until next cycle",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger1": {
      "main": [
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "AI Agent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delay until next cycle": {
      "main": [
        [
          {
            "node": "Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Analyzer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  }
}