{
  "name": "Get hourly Wallapop deal alerts in Telegram and Google Sheets with Apify",
  "nodes": [
    {
      "parameters": {
        "content": "## Get instant Wallapop deal alerts in Telegram and Google Sheets\n\nWallapop's best bargains are gone within the hour. This workflow checks Wallapop every hour for new listings matching your search, saves each one to Google Sheets, and sends the ones under your price to Telegram while they are still available.\n\n### Who it's for\nBargain hunters and resellers in Spain, Italy, France, Portugal, Germany and the UK who want to be first to answer a listing.\n\n### How it works\n1. **Schedule** runs the workflow every hour.\n2. **Set your search** holds your keywords, price range, country and alert price.\n3. **Apify** runs the [Wallapop Scraper](https://apify.com/fayoussef/wallapop-scraper?fpr=youssef) on a search built from those values, newest first, limited to today's listings.\n4. **Remove Duplicates** drops items you have already been sent.\n5. Every new item is saved to your Google Sheet with price, condition, city and seller.\n6. Items at or under `alertMaxPrice` go to Telegram in one message.\n\n### How to set up\n1. Create a free [Apify account](https://apify.com/?fpr=youssef) and connect it in the **Apify** node (OAuth or API token).\n2. Create an empty Google Sheet and paste its URL in **Set your search**.\n3. Create a Telegram bot with @BotFather, connect it, and paste your chat id in **Set your search**.\n4. Put your keywords and prices in **Set your search**, run once, then activate.\n\n### Requirements\n- Apify account (the free plan returns 5 items per run)\n- Google Sheets and a Telegram bot\n\n### How to customize\n- Paste a ready-made Wallapop search URL into `searchUrl` to use every filter the site offers (category, distance, seller type).\n- Change `countryCode` to `it`, `fr`, `pt`, `de` or `en` and `country` to match.\n- Set `alertMaxPrice` to 0 to be alerted about every new listing.",
        "height": 1100,
        "width": 520,
        "color": 1
      },
      "id": "wa11a901-0000-4000-8000-000000000001",
      "name": "Sticky Note - About",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -760,
        -240
      ]
    },
    {
      "parameters": {
        "content": "### 1. Set your search\n`searchKeywords` and the price range build the Wallapop search for you.\n\n`countryCode`: the Wallapop site to search (`es`, `it`, `fr`, `pt`, `de`, `en`).\n`country`: sets the map centre of the search.\n`alertMaxPrice`: only items at or under this reach Telegram. 0 alerts on everything.\n`searchUrl`: optional. Paste a Wallapop search URL and every field above is ignored.",
        "height": 640,
        "width": 520,
        "color": 7
      },
      "id": "wa11a901-0000-4000-8000-000000000002",
      "name": "Sticky Note - Step 1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -200,
        -240
      ]
    },
    {
      "parameters": {
        "content": "### 2. Find new listings\nRuns the [Wallapop Scraper](https://apify.com/fayoussef/wallapop-scraper?fpr=youssef) on your Apify account, newest first and limited to listings posted today.\n\n**Skip items already sent** remembers every listing URL across runs, so an hourly schedule never repeats an item.\n\nUsage is billed per item on your Apify account, and the free plan returns 5 items per run.",
        "height": 640,
        "width": 520,
        "color": 7
      },
      "id": "wa11a901-0000-4000-8000-000000000003",
      "name": "Sticky Note - Step 2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        360,
        -240
      ]
    },
    {
      "parameters": {
        "content": "### 3. Save and alert\nEvery new item becomes one row in your Google Sheet (headers are created on the first run), with price, condition, city, seller and a photo link.\n\nOnly items under your alert price reach Telegram, combined into one message with up to 20 items.",
        "height": 640,
        "width": 920,
        "color": 7
      },
      "id": "wa11a901-0000-4000-8000-000000000004",
      "name": "Sticky Note - Step 3",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        920,
        -240
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 1
            }
          ]
        }
      },
      "id": "wa11a901-0000-4000-8000-000000000010",
      "name": "Every hour",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -120,
        120
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wa11a901f-0000-4000-8000-000000000001",
              "name": "searchKeywords",
              "value": "iphone 13",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000002",
              "name": "minPrice",
              "value": 0,
              "type": "number"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000003",
              "name": "maxPrice",
              "value": 300,
              "type": "number"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000004",
              "name": "countryCode",
              "value": "es",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000005",
              "name": "country",
              "value": "Spain",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000006",
              "name": "maxItems",
              "value": 40,
              "type": "number"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000007",
              "name": "alertMaxPrice",
              "value": 250,
              "type": "number"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000008",
              "name": "searchUrl",
              "value": "",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000009",
              "name": "googleSheetUrl",
              "value": "PASTE_YOUR_GOOGLE_SHEET_URL_HERE",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000010",
              "name": "telegramChatId",
              "value": "PASTE_YOUR_TELEGRAM_CHAT_ID_HERE",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "wa11a901-0000-4000-8000-000000000011",
      "name": "Set your search",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        120,
        120
      ]
    },
    {
      "parameters": {
        "operation": "Run actor and get dataset",
        "actorSource": "store",
        "actorId": {
          "__rl": true,
          "value": "zxeaZX6wkeQ2UPiYp",
          "mode": "id"
        },
        "customBody": "={{ (() => {\n  const s = $json;\n  const parts = [['keywords', s.searchKeywords], ['order_by', 'newest'], ['time_filter', 'today']];\n  if (s.minPrice) parts.push(['min_sale_price', s.minPrice]);\n  if (s.maxPrice) parts.push(['max_sale_price', s.maxPrice]);\n  const query = parts.map(p => p[0] + '=' + encodeURIComponent(String(p[1]))).join('&');\n  const built = 'https://' + String(s.countryCode || 'es').trim() + '.wallapop.com/search?' + query;\n  return JSON.stringify({\n    start_urls: [{ url: String(s.searchUrl || '').trim() || built }],\n    max_items: s.maxItems,\n    country: s.country\n  });\n})() }}"
      },
      "id": "wa11a901-0000-4000-8000-000000000012",
      "name": "Find new Wallapop listings",
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        460,
        120
      ]
    },
    {
      "parameters": {
        "operation": "removeItemsSeenInPreviousExecutions",
        "dedupeValue": "={{ $json.listing_url }}",
        "options": {}
      },
      "id": "wa11a901-0000-4000-8000-000000000013",
      "name": "Skip items already sent",
      "type": "n8n-nodes-base.removeDuplicates",
      "typeVersion": 2,
      "position": [
        720,
        120
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wa11a901f-0000-4000-8000-000000000001",
              "name": "Title",
              "value": "={{ $json.title }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000002",
              "name": "Price",
              "value": "={{ $json.price }}",
              "type": "number"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000003",
              "name": "Currency",
              "value": "={{ $json.currency || 'EUR' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000004",
              "name": "Brand",
              "value": "={{ $json.brand || '' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000005",
              "name": "Model",
              "value": "={{ $json.model || '' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000006",
              "name": "Condition",
              "value": "={{ (c => c ? ({ un_opened: 'new, sealed', as_good_as_new: 'as good as new', good: 'good', fair: 'fair', has_given_it_all: 'well used' }[c] || String(c).replaceAll('_', ' ')) : '')(($json.extra_attributes || {}).condition) }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000007",
              "name": "Category",
              "value": "={{ $json.category || '' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000008",
              "name": "City",
              "value": "={{ $json.city || '' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000009",
              "name": "Postal code",
              "value": "={{ $json.postal_code || '' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000010",
              "name": "Shipping",
              "value": "={{ $json.shipping_available ? 'Yes' : 'No' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000011",
              "name": "Views",
              "value": "={{ $json.views ?? '' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000012",
              "name": "Favorites",
              "value": "={{ $json.favorites ?? '' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000013",
              "name": "Listed",
              "value": "={{ $json.modified_date ? new Date($json.modified_date * 1000).toISOString().slice(0, 16).replace('T', ' ') : '' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000014",
              "name": "Photo",
              "value": "={{ Array.isArray($json.images) ? ($json.images[0] || '') : '' }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000015",
              "name": "Found on",
              "value": "={{ $now.toISODate() }}",
              "type": "string"
            },
            {
              "id": "wa11a901f-0000-4000-8000-000000000016",
              "name": "Link",
              "value": "={{ $json.listing_url }}",
              "type": "string"
            }
          ]
        },
        "options": {
          "ignoreConversionErrors": true
        }
      },
      "id": "wa11a901-0000-4000-8000-000000000014",
      "name": "Format item row",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        980,
        120
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "={{ $('Set your search').first().json.googleSheetUrl }}",
          "mode": "url"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "id"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {},
          "matchingColumns": [],
          "schema": []
        },
        "options": {}
      },
      "id": "wa11a901-0000-4000-8000-000000000015",
      "name": "Save every item to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1240,
        20
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "wa11a901c-0000-4000-8000-000000000001",
              "leftValue": "={{ (() => { const cap = Number($('Set your search').first().json.alertMaxPrice) || 0; return !cap || Number($json.Price) <= cap; })() }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "id": "wa11a901-0000-4000-8000-000000000016",
      "name": "Keep items under your price",
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.2,
      "position": [
        1240,
        240
      ]
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "items",
        "options": {}
      },
      "id": "wa11a901-0000-4000-8000-000000000017",
      "name": "Combine into one message",
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        1460,
        240
      ]
    },
    {
      "parameters": {
        "chatId": "={{ $('Set your search').first().json.telegramChatId }}",
        "text": "={{ (() => { const esc = s => String(s ?? '').replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');\nconst items = $json.items;\nconst lines = items.slice(0, 20).map(i => {\n  const price = Number(i.Price).toLocaleString('en-US') + ' ' + (i.Currency || 'EUR');\n  return '🛍 <b><a href=\"' + i.Link + '\">' + esc(String(i.Title).slice(0, 60)) + '</a></b>\\n'\n    + price + (i.Condition ? ' · ' + esc(i.Condition) : '') + (i.Shipping === 'Yes' ? ' · ships' : '') + '\\n'\n    + esc([i.City, i.Listed].filter(Boolean).join(' · '));\n});\nreturn '<b>' + items.length + ' new Wallapop find' + (items.length === 1 ? '' : 's') + '</b>\\n\\n' + lines.join('\\n\\n')\n  + (items.length > 20 ? '\\n\\n+ ' + (items.length - 20) + ' more in your Google Sheet' : '');\n})() }}",
        "additionalFields": {
          "appendAttribution": false,
          "parse_mode": "HTML",
          "disable_web_page_preview": true
        }
      },
      "id": "wa11a901-0000-4000-8000-000000000018",
      "name": "Send finds to Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1660,
        240
      ],
      "webhookId": "wa11a901w-0000-4000-8000-000000000001"
    }
  ],
  "connections": {
    "Every hour": {
      "main": [
        [
          {
            "node": "Set your search",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set your search": {
      "main": [
        [
          {
            "node": "Find new Wallapop listings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find new Wallapop listings": {
      "main": [
        [
          {
            "node": "Skip items already sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skip items already sent": {
      "main": [
        [
          {
            "node": "Format item row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format item row": {
      "main": [
        [
          {
            "node": "Save every item to Google Sheets",
            "type": "main",
            "index": 0
          },
          {
            "node": "Keep items under your price",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Keep items under your price": {
      "main": [
        [
          {
            "node": "Combine into one message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine into one message": {
      "main": [
        [
          {
            "node": "Send finds to Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": false
  }
}