{
  "name": "Get a Slack alert for new negative Tripadvisor reviews of your hotels or restaurants",
  "nodes": [
    {
      "parameters": {
        "content": "## Get a Slack alert for new negative Tripadvisor reviews of your hotels or restaurants\n\n### Who's it for\nHotel and restaurant owners, revenue and guest-relations managers, and hospitality agencies who want to answer unhappy guests on Tripadvisor fast, without checking each page by hand.\n\n### How it works\n1. Every morning the Schedule Trigger starts the workflow.\n2. The **Settings** node holds your Tripadvisor links (hotels, restaurants or attractions) and the highest star rating to alert on.\n3. The **Tripadvisor Reviews Scraper** Actor on Apify (`plainrows/tripadvisor-reviews`) runs with **Only new reviews** on: it remembers the reviews it already delivered, so each run returns only reviews posted since the last one.\n4. A Code node keeps the new reviews at or under your rating, groups them by place and builds one message with stars, title, text, date, whether management already answered, and a link to each review.\n5. The message is posted to Slack. No new low rating, no message.\n\n### Requirements\n- An Apify account (free plan available) and its API token.\n- A Slack workspace and the Slack credential in n8n.\n- The Apify node is the verified community node `@apify/n8n-nodes-apify` (available on n8n Cloud; on self-hosted n8n install it from Settings > Community nodes).\n\n### How to customize\n- Edit `places` (one per line), `maxStars` and `monitorName` in **Settings**. Use a new `monitorName` to start a fresh history.\n- Add competitors' pages to see what their guests complain about.\n- Replace Slack with Gmail, Microsoft Teams or Google Sheets using the same fields.\n\nReviewer names are not collected. The first run reads the 20 newest reviews of each place and seeds the memory; later runs only pay for new reviews plus a small fee per block of 10 reviews checked.",
        "height": 760,
        "width": 520
      },
      "id": "a51cccae-f0cf-51a3-9fc1-1ffabb6b5bad",
      "name": "Description",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -660,
        -340
      ]
    },
    {
      "parameters": {
        "content": "### Setup\n1. Put your Tripadvisor links in `places` (one per line: hotel, restaurant or attraction page) and choose `maxStars` in **Settings**.\n2. Add your Apify credential (free account at apify.com) to *Get new reviews*.\n3. Connect Slack and pick the channel in *Post to Slack*.\n4. Run once by hand: the first run seeds the memory with the newest reviews.\n\n**Cost:** a small fee per block of 10 reviews checked plus a price per new review (see the Actor's Pricing tab); the node caps each run with *Maximum Cost per Run*.",
        "height": 340,
        "width": 420,
        "color": 7
      },
      "id": "c2dd552a-f1ac-5c49-9dc9-9d73011c3c6c",
      "name": "Setup",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        440,
        -340
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "days",
              "triggerAtHour": 8
            }
          ]
        }
      },
      "id": "7c9be923-e58c-5b02-b534-813c47b40e6d",
      "name": "Every day 8:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        120
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "25e1ce18-62b6-59c5-b216-f917618f792c",
              "name": "places",
              "value": "https://www.tripadvisor.com/Hotel_Review-g60763-d23462501-Reviews-Margaritaville_Times_Square-New_York_City_New_York.html",
              "type": "string"
            },
            {
              "id": "390ec8ef-3174-5acd-ab00-2049183d00e8",
              "name": "maxStars",
              "value": 3,
              "type": "number"
            },
            {
              "id": "a4bffc4b-c705-50d0-add3-342c331c5bf8",
              "name": "monitorName",
              "value": "n8n-new-tripadvisor-reviews",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "652bd0c7-4e8d-5c60-9442-ae2a64eeaa78",
      "name": "Settings",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        120
      ]
    },
    {
      "parameters": {
        "resource": "Actors",
        "operation": "Run actor and get dataset",
        "actorId": "plainrows~tripadvisor-reviews",
        "customBody": "={{ JSON.stringify({ startUrls: $json.places.split('\\n').map((p) => p.trim()).filter(Boolean), maxReviewsPerPlace: 20, sortBy: 'most_recent', onlyNewReviews: true, monitorName: $json.monitorName }) }}",
        "maxTotalChargeUsd": 1
      },
      "id": "ff015191-2cf7-5f9a-8f95-fe6994a81a79",
      "name": "Get new reviews",
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        440,
        120
      ],
      "credentials": {
        "apifyApi": {
          "id": "",
          "name": "Apify account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// One Slack message listing new Tripadvisor reviews at or under maxStars, grouped by place. Nothing to report: no message.\nconst max = Number($('Settings').first().json.maxStars ?? 3);\nconst reviews = $input.all().map((i) => i.json).filter((r) => r.found !== false && r.rating !== null && r.rating !== undefined && r.rating <= max);\nif (reviews.length === 0) return [];\nconst byPlace = {};\nfor (const r of reviews) (byPlace[r.placeTitle ?? r.input] ??= []).push(r);\nconst stars = (n) => '★'.repeat(n) + '☆'.repeat(5 - n);\nconst blocks = Object.entries(byPlace).map(([place, list]) => {\n  const lines = list.slice(0, 10).map((r) => `• ${stars(r.rating)} *${(r.title ?? '').slice(0, 80)}* ${(r.text ?? '(no text)').slice(0, 200)} (${(r.publishedAt ?? '').slice(0, 10)})${r.ownerResponse ? ' (answered)' : ''}${r.reviewUrl ? ` <${r.reviewUrl}|open>` : ''}`);\n  if (list.length > 10) lines.push(`…and ${list.length - 10} more`);\n  return `*${place}*: ${list.length} new review${list.length > 1 ? 's' : ''} at ${max} stars or less\\n${lines.join('\\n')}`;\n});\nreturn [{ json: { text: `:rotating_light: *New Tripadvisor reviews to answer*\\n\\n${blocks.join('\\n\\n')}`, newReviews: reviews.length } }];"
      },
      "id": "10b3bccd-4cec-561a-9fb3-d18620b5a440",
      "name": "Build alert",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        660,
        120
      ]
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "",
          "mode": "list"
        },
        "text": "={{ $json.text }}",
        "otherOptions": {}
      },
      "id": "c3508c71-e7ff-5d97-a5a5-e4bd00f99e65",
      "name": "Post to Slack",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        880,
        120
      ],
      "credentials": {
        "slackApi": {
          "id": "",
          "name": "Slack account"
        }
      }
    }
  ],
  "connections": {
    "Every day 8:00": {
      "main": [
        [
          {
            "node": "Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Settings": {
      "main": [
        [
          {
            "node": "Get new reviews",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get new reviews": {
      "main": [
        [
          {
            "node": "Build alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build alert": {
      "main": [
        [
          {
            "node": "Post to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  }
}
