{
  "nodes": [
    {
      "id": "e005dd32-8f95-4a64-945d-f620a7a3f057",
      "name": "Fetch Idealista Rentals",
      "type": "n8n-nodes-idealista-scraper.idealistaScraper",
      "position": [
        3472,
        816
      ],
      "parameters": {
        "sizeFilters": {},
        "priceFilters": {
          "maxPrice": 1500
        },
        "rentalFilters": {},
        "featureFilters": {
          "elevator": true
        },
        "advancedFilters": {},
        "conditionFilters": {},
        "floorTimeFilters": {
          "sinceDate": "W"
        },
        "propertyTypeFilters": {},
        "bedroomBathroomFilters": {
          "bedrooms1": true,
          "bedrooms2": true
        }
      },
      "typeVersion": 1
    },
    {
      "id": "390c332b-d77d-4daa-85ba-829a77b1cc37",
      "name": "Filter New Listings",
      "type": "n8n-nodes-base.code",
      "position": [
        3696,
        816
      ],
      "parameters": {
        "jsCode": "// Deduplication: compare scraped listings against workflow static data\n// Only genuinely NEW listings pass through to alerts\n\nconst items = $input.all();\nconst staticData = $getWorkflowStaticData('global');\n\nif (!staticData.seenIds) {\n  staticData.seenIds = {};\n}\n\nconst newListings = [];\nfor (const item of items) {\n  const id = item.json.propertyCode\n    || item.json.url\n    || `${item.json.price}_${item.json.address}`;\n\n  if (!staticData.seenIds[id]) {\n    staticData.seenIds[id] = new Date().toISOString();\n    newListings.push(item);\n  }\n}\n\n// Prune entries older than 30 days\nconst thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();\nfor (const [id, dateStr] of Object.entries(staticData.seenIds)) {\n  if (dateStr < thirtyDaysAgo) {\n    delete staticData.seenIds[id];\n  }\n}\n\nreturn newListings;"
      },
      "typeVersion": 2
    },
    {
      "id": "08fef4f7-de1e-4081-a226-b616b6a317bf",
      "name": "Prepare Slack Message",
      "type": "n8n-nodes-base.set",
      "position": [
        3920,
        720
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b1b2c3d4-set1-4+123456789001",
              "name": "slackMessage",
              "type": "string",
              "value": "=:house: *New Rental on Idealista!*\n\n*Property listing*\n:moneybag:  EUR/month  |  :straight_ruler:  m\u00b2  |  :bed:  rooms\n:round_pushpin: \n\n:link: <|View on Idealista>"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "1ea13709-59d6-41ed-8721-72cbcb5ba35f",
      "name": "Post Slack Notification",
      "type": "n8n-nodes-base.slack",
      "position": [
        4144,
        720
      ],
      "parameters": {
        "text": "=",
        "otherOptions": {}
      },
      "typeVersion": 2.4
    },
    {
      "id": "e1a6cfdf-eda6-461f-b125-317cc07baa4b",
      "name": "Append Listings in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3920,
        912
      ],
      "parameters": {
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "2c1fda89-ff2a-494b-b33d-d71d02882a5e",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2640,
        560
      ],
      "parameters": {
        "width": 480,
        "height": 832,
        "content": "## Untitled workflow\n\n### How it works\n\n1. It runs every six hours to check for new Idealista rental listings.\n2. It compares scraped results against stored history to detect only fresh listings.\n3. It formats any new listing details into a Slack-ready message.\n4. It sends the alert to Slack and saves the listing data to Google Sheets for deduplication on future runs.\n\n### Setup steps\n\n- [ ] Configure the schedule trigger interval if you want a different polling frequency.\n- [ ] Connect and authorize the Idealista scraper node with the target search criteria.\n- [ ] Ensure the workflow can access static data or state used by the deduplication code node.\n- [ ] Set up the Slack credential and choose the destination channel for alerts.\n- [ ] Connect Google Sheets credentials and select the spreadsheet/sheet used for history tracking.\n\n### Customization\n\nYou can adjust the deduplication logic, Slack message formatting, search filters, and the sheet structure to change what counts as a new listing and how alerts are presented."
      },
      "typeVersion": 1
    },
    {
      "id": "a104e796-4634-4813-b13b-eeaebad8c5c8",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3200,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 304,
        "content": "## Scheduled scrape and filter\n\nThis left-to-middle cluster starts the recurring run, scrapes latest rentals, and filters out listings already seen in history."
      },
      "typeVersion": 1
    },
    {
      "id": "f6b0dbd6-88b8-454e-ab7f-b04639ae18c7",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3872,
        560
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 512,
        "content": "## Notify and store results\n\nThis right-side cluster formats the alert for Slack, sends the message, and stores new listings in Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "a3d39de2-6ea8-48b7-b1d4-f37cfce21ff4",
      "name": "Every 6 Hours1",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        3248,
        816
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "typeVersion": 1.2
    }
  ],
  "connections": {
    "Every 6 Hours1": {
      "main": [
        [
          {
            "node": "Fetch Idealista Rentals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter New Listings": {
      "main": [
        [
          {
            "node": "Prepare Slack Message",
            "type": "main",
            "index": 0
          },
          {
            "node": "Append Listings in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Slack Message": {
      "main": [
        [
          {
            "node": "Post Slack Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Idealista Rentals": {
      "main": [
        [
          {
            "node": "Filter New Listings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}