{
  "name": "Extract and score Naver Place Reviews Scraper data to Google Sheets, CSV, and Slack with Apify",
  "nodes": [
    {
      "parameters": {
        "content": "## Naver Place Reviews Scraper — Automated Sheets, CSV & Slack Pipeline\n\nBuilt for market research, e-commerce, and growth teams. This workflow runs on a schedule to extract fresh data with the **[naver-place-reviews-scraper Apify Actor](https://apify.com/unitbytes/naver-place-reviews-scraper?fpr=939u3w&fp_sid=n8n_io)** ($0.0008 / item), skips previously seen records, scores each item, logs results to **Google Sheets** and **CSV**, and posts **Slack** alerts for top matches.\n\n### How it works\n1. **Every 6 Hours** triggers the run and loads search settings from **1. Configure Search & Rules**.\n2. **2. Run UnitBytes (naver-place-reviews-scraper)** executes the actor via Apify's synchronous endpoint.\n3. **3. Skip Seen Records** deduplicates items by `placeId` across runs.\n4. **4. Clean & Score Items** and **5. Map Export Fields** normalize fields (`reviewId, reviewType, placeId, placeName, placeCategory`) and compute a 0–100 `priorityScore`.\n5. **6a. Log to Google Sheets** and **6b. Export Backup CSV** store all rows, while **6c. Filter High-Priority Items** sends top matches to **7. Send Slack Alert**.\n\n### Setup\n1. Copy your API token from [naver-place-reviews-scraper on Apify Store](https://apify.com/unitbytes/naver-place-reviews-scraper?fpr=939u3w&fp_sid=n8n_io) into the **HTTP Header Auth** credential (`Authorization: Bearer <TOKEN>`) on node 2.\n2. Edit `actorInput`, `sheetTab`, and `maxTargetPrice` in **1. Configure Search & Rules**.\n3. Connect **Google Sheets** and **Slack** credentials (or test immediately via CSV export).\n\n### Customization\n- Tune `maxTargetPrice` or `priorityKeyword` in node 1 to adjust Slack alert sensitivity.\n- Full schema reference: [https://unitbytes.com/actors/naver-place-reviews-scraper/](https://unitbytes.com/actors/naver-place-reviews-scraper/)",
        "height": 760,
        "width": 560,
        "color": 1
      },
      "id": "8a514d5a-eb18-5487-b2bb-9211caff2f91",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -640,
        -80
      ]
    },
    {
      "parameters": {
        "content": "## 1. Schedule & Search Settings\nTriggers on schedule and sets target search parameters, Google Sheets tab, and alert thresholds.",
        "height": 380,
        "width": 440,
        "color": 7
      },
      "id": "01da6706-82ff-5148-9e63-272c385bf402",
      "name": "Section 1 — Schedule & Settings",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        60
      ]
    },
    {
      "parameters": {
        "content": "## 2. Extract & Deduplicate\nRuns the UnitBytes Apify Actor and skips records already processed in previous runs.",
        "height": 380,
        "width": 440,
        "color": 7
      },
      "id": "2085e058-8bdb-5b7e-b72e-18994424c346",
      "name": "Section 2 — Extract & Deduplicate",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        460,
        60
      ]
    },
    {
      "parameters": {
        "content": "## 3. Clean, Score & Flatten\nNormalizes fields, parses numeric metrics, and calculates a 0–100 priority score.",
        "height": 380,
        "width": 440,
        "color": 7
      },
      "id": "c6ff2aed-40d1-5651-a5cb-81ff1f0be903",
      "name": "Section 3 — Clean, Score & Flatten",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        920,
        60
      ]
    },
    {
      "parameters": {
        "content": "## 4. Sync to Sheets, CSV & Slack\nLogs all new records to Google Sheets and CSV, and routes high-priority matches to Slack.",
        "height": 660,
        "width": 540,
        "color": 7
      },
      "id": "f4a0d747-1077-562b-9121-46e87ee02177",
      "name": "Section 4 — Sheets, CSV & Slack",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1380,
        -80
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "id": "a68d13f9-ecf5-59b5-9a44-f80d56ef2929",
      "name": "Every 6 Hours",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        40,
        220
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "2874cd74-27c0-5630-a5df-8faef733c876",
              "name": "actorInput",
              "value": "{\"placeUrls\": [\"https://map.naver.com/p/entry/place/2025884279\"], \"maxItems\": 20, \"maxReviewsPerPlace\": 20, \"onlyPhotoReviews\": false, \"includeBlogReviews\": true, \"maxBlogReviewsPerPlace\": 10}",
              "type": "object"
            },
            {
              "id": "04708fe7-3ca0-5add-8150-1bf8b9e270a6",
              "name": "sheetTab",
              "value": "MarketplaceDeals",
              "type": "string"
            },
            {
              "id": "fd5f7e3c-dfbc-5024-aff3-9540e931121f",
              "name": "maxTargetPrice",
              "value": 500,
              "type": "number"
            },
            {
              "id": "76c3de33-e888-5fb0-9440-6d85e080343e",
              "name": "priorityKeyword",
              "value": "",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "cf56d5c8-8c2d-5f5d-957d-8b803cf1a9cd",
      "name": "1. Configure Search & Rules",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        260,
        220
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.apify.com/v2/acts/unitbytes~naver-place-reviews-scraper/run-sync-get-dataset-items?format=json&clean=true",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.actorInput) }}",
        "options": {
          "timeout": 300000
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "58e4a8b3-3798-5837-9e9c-c5513711f4d1",
          "name": "Apify API Token (Header Auth)"
        }
      },
      "id": "0e462606-c0c8-53e3-9f2e-b20d16621c1e",
      "name": "2. Run UnitBytes (naver-place-reviews-scraper)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        500,
        220
      ]
    },
    {
      "parameters": {
        "operation": "removeItemsSeenInPreviousExecutions",
        "dedupeValue": "={{ $json.placeId || $json.id || $json.url }}",
        "options": {}
      },
      "id": "e46c11ec-2533-5a58-af55-423a41eef072",
      "name": "3. Skip Seen Records",
      "type": "n8n-nodes-base.removeDuplicates",
      "typeVersion": 2,
      "position": [
        720,
        220
      ]
    },
    {
      "parameters": {
        "jsCode": "// Normalize fields, parse numeric metrics, and score items for Slack alerts\nconst config = $('1. Configure Search & Rules').first().json;\nconst threshold = Number(config.maxTargetPrice ?? 500);\nconst keywordFilter = String(config.priorityKeyword || '').trim().toLowerCase();\nconst primaryKeys = [\"reviewId\", \"reviewType\", \"placeId\", \"placeName\", \"placeCategory\", \"businessCategory\"];\n\nreturn $input.all().map((item) => {\n  const raw = item.json || {};\n  const cleaned = { ...raw };\n\n  for (const k of primaryKeys) {\n    if (typeof cleaned[k] === 'string') {\n      cleaned[k] = cleaned[k].replace(/\\s+/g, ' ').trim();\n    }\n  }\n\n  const recordId = String(cleaned.placeId || cleaned.id || cleaned.url || '');\n  const titleText = String(cleaned.title || cleaned.query || cleaned.business_name || cleaned.place_name || cleaned.placeName || cleaned.shopName || cleaned.reviewer_name || cleaned.contributor_name || cleaned.content || cleaned.body || cleaned.keyword || cleaned.original_keyword || cleaned.name || cleaned.sellerNick || recordId).slice(0, 180);\n  const itemUrl = String(cleaned.url || cleaned.review_url || cleaned.review_permalink || cleaned.photoUrl || cleaned.noteUrl || cleaned.shopUrl || cleaned.place_url || cleaned.google_maps_url || cleaned.website || cleaned.productUrl || cleaned.taobaoUrl || cleaned.resolved_url || cleaned.input_url || cleaned.contributor_url || '');\n  const rawMetric = cleaned.price ?? cleaned.promotionPrice ?? cleaned.priceMin ?? cleaned.score ?? cleaned.likedCount ?? cleaned.likeCount ?? cleaned.value ?? cleaned.volume ?? cleaned.rating ?? cleaned.review_stars ?? cleaned.dsrDescription ?? cleaned.lead_score ?? 0;\n  const numericValue = Number(String(rawMetric).replace(/[^0-9.-]/g, '')) || 0;\n\n  let priorityScore = 50;\n  let isHighPriority = false;\n  const mode = 'price_deal';\n\n  if (mode === 'price_deal') {\n    if (numericValue > 0 && numericValue <= threshold) {\n      priorityScore = Math.min(100, Math.round(70 + ((threshold - numericValue) / Math.max(threshold, 1)) * 30));\n      isHighPriority = true;\n    }\n  } else if (mode === 'review_sentiment') {\n    const stars = Number(cleaned.review_stars ?? cleaned.stars ?? cleaned.rating ?? numericValue);\n    if (cleaned.is_removed === true || cleaned.is_edited === true || cleaned.status === 'REMOVED' || (stars > 0 && stars <= threshold)) {\n      priorityScore = 95;\n      isHighPriority = true;\n    }\n  } else if (mode === 'lead_score') {\n    const hasDirectContact = Boolean(cleaned.primary_email || cleaned.phone);\n    if (numericValue >= threshold || hasDirectContact) {\n      priorityScore = Math.min(100, Math.max(numericValue, hasDirectContact ? 85 : 70));\n      isHighPriority = true;\n    }\n  } else if (mode === 'status_audit') {\n    if (cleaned.is_sold === true || cleaned.is_removed === true || cleaned.status === 'SOLD' || (numericValue > 0 && numericValue <= threshold)) {\n      priorityScore = 90;\n      isHighPriority = true;\n    }\n  } else {\n    if (numericValue >= threshold) {\n      priorityScore = Math.min(100, Math.round(70 + Math.min(numericValue / Math.max(threshold, 1), 3) * 10));\n      isHighPriority = true;\n    }\n  }\n\n  if (keywordFilter && titleText.toLowerCase().includes(keywordFilter)) {\n    priorityScore = Math.min(100, priorityScore + 20);\n    isHighPriority = true;\n  }\n\n  return {\n    json: {\n      ...cleaned,\n      recordId,\n      titleText,\n      itemUrl,\n      numericValue,\n      priorityScore,\n      isHighPriority,\n      alertSummary: `${titleText} (Metric: ${numericValue} | Score: ${priorityScore}/100)`,\n      scrapedAt: new Date().toISOString(),\n    },\n  };\n});"
      },
      "id": "fb45f93b-af59-58d5-93af-8c7604e2ebc9",
      "name": "4. Clean & Score Items",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        960,
        220
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "578cedf3-06c8-5e2b-b2b5-a1fbf5ff464b",
              "name": "reviewId",
              "value": "={{ $json.reviewId }}",
              "type": "string"
            },
            {
              "id": "4e126d0c-46c0-58b1-b891-a56d80e6ac0a",
              "name": "reviewType",
              "value": "={{ $json.reviewType }}",
              "type": "string"
            },
            {
              "id": "0bd3f7db-23a0-5b5f-ba8a-ca0de1c83dec",
              "name": "placeId",
              "value": "={{ $json.placeId }}",
              "type": "string"
            },
            {
              "id": "f6c5d36e-7416-5a95-b3ff-bf23dfbad58a",
              "name": "placeName",
              "value": "={{ $json.placeName }}",
              "type": "string"
            },
            {
              "id": "dca9b209-08c6-5f0a-8b25-67480f610318",
              "name": "placeCategory",
              "value": "={{ $json.placeCategory }}",
              "type": "string"
            },
            {
              "id": "e118c12f-c4b8-548e-ab29-b47250a6355b",
              "name": "businessCategory",
              "value": "={{ $json.businessCategory }}",
              "type": "string"
            },
            {
              "id": "22d3cd0d-3f36-569f-9a0b-d850208739b4",
              "name": "numericValue",
              "value": "={{ $json.numericValue }}",
              "type": "number"
            },
            {
              "id": "5855912b-954b-5eeb-ba08-e4d55ef5147a",
              "name": "priorityScore",
              "value": "={{ $json.priorityScore }}",
              "type": "number"
            },
            {
              "id": "ec416f2f-ef62-5278-b876-e084aa3ae553",
              "name": "isHighPriority",
              "value": "={{ $json.isHighPriority }}",
              "type": "boolean"
            },
            {
              "id": "f23ab2fb-2f40-5b3e-8d2f-c0329f41077b",
              "name": "alertSummary",
              "value": "={{ $json.alertSummary }}",
              "type": "string"
            },
            {
              "id": "81e6e5e6-e601-55cb-9542-ede2b650a4ae",
              "name": "scrapedAt",
              "value": "={{ $json.scrapedAt }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "id": "c20dff98-1d84-5616-a9eb-0ab95bffc8da",
      "name": "5. Map Export Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1180,
        220
      ]
    },
    {
      "parameters": {
        "resource": "sheet",
        "operation": "append",
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('1. Configure Search & Rules').first().json.sheetTab }}"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "reviewId": "={{ $json.reviewId }}",
            "reviewType": "={{ $json.reviewType }}",
            "placeId": "={{ $json.placeId }}",
            "placeName": "={{ $json.placeName }}",
            "placeCategory": "={{ $json.placeCategory }}",
            "businessCategory": "={{ $json.businessCategory }}",
            "numericValue": "={{ $json.numericValue }}",
            "priorityScore": "={{ $json.priorityScore }}",
            "isHighPriority": "={{ $json.isHighPriority }}",
            "alertSummary": "={{ $json.alertSummary }}",
            "scrapedAt": "={{ $json.scrapedAt }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "reviewId",
              "displayName": "reviewId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "reviewType",
              "displayName": "reviewType",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "placeId",
              "displayName": "placeId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "placeName",
              "displayName": "placeName",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "placeCategory",
              "displayName": "placeCategory",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "businessCategory",
              "displayName": "businessCategory",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "numericValue",
              "displayName": "numericValue",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "priorityScore",
              "displayName": "priorityScore",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "isHighPriority",
              "displayName": "isHighPriority",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "alertSummary",
              "displayName": "alertSummary",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "scrapedAt",
              "displayName": "scrapedAt",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {
          "cellFormat": "RAW"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "392f8733-93e7-5818-aa0c-b1fd35cc5d9c",
          "name": "Google Sheets account"
        }
      },
      "id": "25ec6a9d-ca76-5c49-a59c-c55f59e5ebc0",
      "name": "6a. Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1440,
        -20
      ]
    },
    {
      "parameters": {
        "operation": "csv",
        "options": {
          "fileName": "naver-place-reviews-scraper-dataset-export.csv"
        }
      },
      "id": "fa6277a5-a3a5-541f-8628-dd16bafbef38",
      "name": "6b. Export Backup CSV",
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1.1,
      "position": [
        1440,
        160
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "be31d4fe-4a55-5df9-b7ca-39bf53623634",
              "leftValue": "={{ $json.isHighPriority }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "e76d931e-bfdd-5859-9024-9246c21db720",
      "name": "6c. Filter High-Priority Items",
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.2,
      "position": [
        1440,
        360
      ]
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "messageType": "text",
        "text": "=:bell: *New High-Priority Match (Naver Place Reviews Scraper)*\n*<{{ $json.itemUrl }}|{{ $json.titleText }}>*\n• *Priority Score:* {{ $json.priorityScore }}/100 ({{ $json.numericValue }})\n• *Record ID:* `{{ $json.recordId }}`\n• *Scraped At:* {{ $json.scrapedAt }}",
        "otherOptions": {
          "includeLinkToWorkflow": false,
          "unfurl_links": false
        }
      },
      "credentials": {
        "slackApi": {
          "id": "6c67b0db-bde1-5e74-9d67-b43b6bfdb500",
          "name": "Slack account"
        }
      },
      "id": "56703a07-84e7-5263-954b-d404136cb587",
      "name": "7. Send Slack Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        1680,
        360
      ]
    }
  ],
  "connections": {
    "Every 6 Hours": {
      "main": [
        [
          {
            "node": "1. Configure Search & Rules",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1. Configure Search & Rules": {
      "main": [
        [
          {
            "node": "2. Run UnitBytes (naver-place-reviews-scraper)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. Run UnitBytes (naver-place-reviews-scraper)": {
      "main": [
        [
          {
            "node": "3. Skip Seen Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3. Skip Seen Records": {
      "main": [
        [
          {
            "node": "4. Clean & Score Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4. Clean & Score Items": {
      "main": [
        [
          {
            "node": "5. Map Export Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5. Map Export Fields": {
      "main": [
        [
          {
            "node": "6a. Log to Google Sheets",
            "type": "main",
            "index": 0
          },
          {
            "node": "6b. Export Backup CSV",
            "type": "main",
            "index": 0
          },
          {
            "node": "6c. Filter High-Priority Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6c. Filter High-Priority Items": {
      "main": [
        [
          {
            "node": "7. Send Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false,
    "instanceId": "030f9420-0ca8-5240-8fe8-208e287a8b19"
  },
  "tags": [
    {
      "name": "Web Scraping"
    },
    {
      "name": "Apify"
    },
    {
      "name": "UnitBytes"
    },
    {
      "name": "Reputation Intelligence"
    }
  ]
}