Workflow: Scrape Trustpilot Reviews to Google Sheets
Integrations: code, googleSheets, httpRequest, manualTrigger, scheduleTrigger, set, splitOut, stickyNote

{"id": "DqvkhR9nzoPQKxGh", "meta": {"instanceId": "workflow-93781d19", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:53.962572", "updatedAt": "2025-09-29T07:07:53.962588", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production"}, "name": "Scrape Trustpilot Reviews to Google Sheets", "tags": ["automation", "n8n", "production-ready", "excellent", "optimized"], "nodes": [{"id": "6680358c-de48-4459-aac7-dd7b903e542d", "name": "When clicking \u2018Test workflow\u2019", "type": "n8n-nodes-base.manualTrigger", "position": [-1300, 340], "parameters": {}, "typeVersion": 1, "notes": "This manualTrigger node performs automated tasks as part of the workflow."}, {"id": "896d5dcb-d2cf-4a86-8c84-7997bc7a2d0a", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [-1000, 40], "parameters": {"width": 232, "height": 346, "content": "## Edit this node \ud83d\udc47\n\nChange to the name of the company registered on Trustpilot and the maximum number of pages to scrape"}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "4d208d18-991b-4dfd-a717-8f752ea74a90", "name": "Get reviews", "type": "n8n-nodes-base.httpRequest", "position": [-700, 220], "parameters": {"url": "{{ $env.BASE_URL }}", "options": {"pagination": {"pagination": {"parameters": {"parameters": [{"name": "page", "value": "={{ $pageCount + 1 }}"}]}, "maxRequests": "={{ $json.max_page }}", "requestInterval": 5000, "limitPagesFetched": true, "paginationCompleteWhen": "receiveSpecificStatusCodes", "statusCodesWhenComplete": "404"}}}, "sendQuery": true, "queryParameters": {"parameters": [{"name": "sort", "value": "recency"}]}}, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow."}, {"id": "b3e4c576-a9f4-48c8-ad27-696c0e0fc69d", "name": "Global", "type": "n8n-nodes-base.set", "position": [-960, 220], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "556e201d-242a-4c0e-bc13-787c2b60f800", "name": "company_id", "type": "string", "value": "n8n.io"}, {"id": "a1f239df-df08-41d8-8b78-d6502266a581", "name": "max_page", "type": "number", "value": 100}]}}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "f2dd1771-cba9-408f-93bd-2e83201edae9", "name": "Parse reviews", "type": "n8n-nodes-base.code", "position": [-480, 220], "parameters": {"jsCode": "const cheerio = require('cheerio');\n\nasync function getReviewsFromPage(content) {\n    try {\n        const $ = cheerio.load(content);\n        const scriptTag = $('#__NEXT_DATA__');\n        \n        if (!scriptTag.length) {\n            console.warn(\"Warning: Could not find review data in page\");\n            return [];\n        }\n\n        const reviewsRaw = JSON.parse(scriptTag.html());\n        return reviewsRaw.props.pageProps.reviews || [];\n    } catch (error) {\n        console.error(`Error fetching reviews: ${error.message}`);\n        return [];\n    }\n}\n\nasync function scrapeTrustpilotReviews() {\n    let reviewsData = [];\n    \n    for (let page = 0; page < $input.all().length; page++) {\n        console.log(`\\nScraping page ${page}...`);\n        const content = $input.all()[page].json.data;\n        const reviews = await getReviewsFromPage(content);\n        \n        if (!reviews.length) {\n            console.log(\"No more reviews found.\");\n            break;\n        }\n\n        console.log(`Found ${reviews.length} reviews on page ${page}`);\n        reviews.forEach(review => {\n            const data = {\n                Date: new Date(review.dates.publishedDate).toISOString().split('T')[0],\n                Author: review.consumer.displayName,\n                Body: review.text,\n                Heading: review.title,\n                Rating: review.rating,\n                Location: review.consumer.countryCode\n            };\n            reviewsData.push(review);\n        });\n    }\n    \n    return reviewsData;\n}\n\nconst reviews = await scrapeTrustpilotReviews();\n\n\nreturn {reviews:reviews};"}, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow."}, {"id": "b5204815-4feb-4311-a153-205933a325b2", "name": "HelpfulCrowd edits", "type": "n8n-nodes-base.set", "position": [-40, 460], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "e57e50a2-cf1c-4e9c-bcab-38c97ffc79d4", "name": "product_id", "type": "string", "value": ""}, {"id": "acce9f30-1bae-4e75-9f96-a8590642e47c", "name": "rating", "type": "string", "value": "={{ $json.rating }}"}, {"id": "6662028a-6c37-4a79-9d60-ea38d514b7b9", "name": "title", "type": "string", "value": "={{ $json.title }}"}, {"id": "3bfe0ca5-d154-420f-8fbc-bd091472edb5", "name": "feedback", "type": "string", "value": "={{ $json.text }}"}, {"id": "aa3e14f3-5f83-41fb-a2e2-fa8e2cfd74e6", "name": "customer_name", "type": "string", "value": "={{ $json.consumer.displayName }}"}, {"id": "9048a66b-8c70-424f-a849-56f989be0b52", "name": "customer_email", "type": "string", "value": ""}, {"id": "08cfc9c4-48fd-4ac7-ae4c-78bceaa3e745", "name": "comment", "type": "string", "value": ""}, {"id": "90ec5664-4fcc-43d1-be72-144c3ea48475", "name": "status", "type": "string", "value": "={{ $json.pending ? 'pending' : 'published' }}"}, {"id": "7076f725-b6c2-4c24-b517-c84f78ae69dc", "name": "review_date", "type": "string", "value": "={{ $json.dates.publishedDate.split('T')[0] }}"}, {"id": "92c79888-dfb4-4be8-9f0d-c140a151ef0e", "name": "verified", "type": "string", "value": "={{ $json.labels.verification.isVerified ? 'yes' : 'no' }}"}, {"id": "93e7b8b9-aea6-4ca4-bc7b-1e5469ddb39e", "name": "media_1", "type": "string", "value": ""}, {"id": "5a2688d3-c9dd-4f5e-a975-f4357c752c95", "name": "media_2", "type": "string", "value": ""}, {"id": "c6bbf887-bc47-4f9e-a3b0-bb6ba403b5b3", "name": "media_3", "type": "string", "value": ""}, {"id": "218d7c77-44f1-4c22-a82c-8d7b49dcaf4a", "name": "media_4", "type": "string", "value": ""}, {"id": "893356ab-fe8a-4500-be7b-d000fe78ebb7", "name": "media_5", "type": "string", "value": ""}, {"id": "50355cf7-2d4d-49da-b62d-695916d9db77", "name": "review_id", "type": "string", "value": "={{ $json.id }}"}]}}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "746bca7f-7d79-403b-b281-37c74db04b50", "name": "Split Out", "type": "n8n-nodes-base.splitOut", "position": [-260, 220], "parameters": {"options": {}, "fieldToSplitOut": "reviews"}, "typeVersion": 1, "notes": "This splitOut node performs automated tasks as part of the workflow."}, {"id": "fc5aa26e-8b12-435b-8229-549c3034dc5b", "name": "General edits", "type": "n8n-nodes-base.set", "position": [-40, -60], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "e57e50a2-cf1c-4e9c-bcab-38c97ffc79d4", "name": "Date", "type": "string", "value": "={{ $json.dates.publishedDate }}"}, {"id": "fcbae9ed-47c4-4084-87b4-c8dac07396ba", "name": "Author", "type": "string", "value": "={{ $('Parse reviews').item.json.reviews[0].consumer.displayName }}"}, {"id": "829a0a42-c7fb-4de2-9fa3-dd0c6dbf5624", "name": "Body", "type": "string", "value": "={{ $json.text }}"}, {"id": "26c1bca9-b08c-43f7-90f9-eaa8b9666515", "name": "Heading", "type": "string", "value": "={{ $json.title }}"}, {"id": "8855995e-f45d-4ae7-bd22-f9b406a16913", "name": "Rating", "type": "string", "value": "={{ $json.rating }}"}, {"id": "bcf78f11-1c72-4305-9a02-fe2c937249f9", "name": "Location", "type": "string", "value": "={{ $json.consumer.countryCode }}"}, {"id": "50355cf7-2d4d-49da-b62d-695916d9db77", "name": "review_id", "type": "string", "value": "={{ $json.id }}"}]}}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "13f3720d-0753-49fc-a5e6-1473d5411e29", "name": "General sheet", "type": "n8n-nodes-base.googleSheets", "position": [360, -60], "parameters": {"columns": {"value": {"Body": "={{ $json.Body }}", "Date": "={{ $json.Date }}", "Author": "={{ $json.Author }}", "Rating": "={{ $json.Rating }}", "Heading": "={{ $json.Heading }}", "Location": "={{ $json.Location }}", "review_id": "={{ $json.review_id }}"}, "schema": [{"id": "Date", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Date", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "Author", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Author", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "Body", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Body", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "Heading", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Heading", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "Rating", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Rating", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "Location", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Location", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "review_id", "type": "string", "display": true, "removed": false, "required": false, "displayName": "review_id", "defaultMatch": false, "canBeUsedToMatch": true}], "mappingMode": "defineBelow", "matchingColumns": ["review_id"], "attemptToConvertTypes": false, "convertFieldsToString": false}, "options": {}, "operation": "appendOrUpdate", "sheetName": {"__rl": true, "mode": "list", "value": 323953858, "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "trustpilot"}, "documentId": {"__rl": true, "mode": "list", "value": "1yf_RYZGFHpMyOvD3RKGSvIFY2vumvI4474Qm_1t4-jM", "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "Squarespace automation"}}, "credentials": {"googleSheetsOAuth2Api": {"id": "JgI9maibw5DnBXRP", "name": "Google Sheets account"}}, "typeVersion": 4.5, "notes": "This googleSheets node performs automated tasks as part of the workflow."}, {"id": "0ffeed7c-7787-461f-a47b-704fa665dcc6", "name": "HelpfulCrowd Sheets", "type": "n8n-nodes-base.googleSheets", "position": [380, 460], "parameters": {"columns": {"value": {"title": "={{ $('HelpfulCrowd edits').item.json.title }}", "comment": "={{ $('HelpfulCrowd edits').item.json.comment }}", "rating*": "={{ $('HelpfulCrowd edits').item.json.rating }}", "status*": "={{ $('HelpfulCrowd edits').item.json.status }}", "verified": "={{ $('HelpfulCrowd edits').item.json.verified }}", "feedback*": "={{ $('HelpfulCrowd edits').item.json.feedback }}", "review_id": "={{ $('HelpfulCrowd edits').item.json.review_id }}", "product_id*": "={{ $('HelpfulCrowd edits').item.json.product_id }}", "review_date*": "={{ $('HelpfulCrowd edits').item.json.review_date }}", "customer_email": "={{ $('HelpfulCrowd edits').item.json.customer_email }}", "customer_name*": "={{ $('HelpfulCrowd edits').item.json.customer_name }}"}, "schema": [{"id": "product_id*", "type": "string", "display": true, "required": false, "displayName": "product_id*", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "rating*", "type": "string", "display": true, "required": false, "displayName": "rating*", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "title", "type": "string", "display": true, "required": false, "displayName": "title", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "feedback*", "type": "string", "display": true, "required": false, "displayName": "feedback*", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "customer_name*", "type": "string", "display": true, "required": false, "displayName": "customer_name*", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "customer_email", "type": "string", "display": true, "required": false, "displayName": "customer_email", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "comment", "type": "string", "display": true, "required": false, "displayName": "comment", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "status*", "type": "string", "display": true, "required": false, "displayName": "status*", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "review_date*", "type": "string", "display": true, "required": false, "displayName": "review_date*", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "verified", "type": "string", "display": true, "required": false, "displayName": "verified", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "media_1", "type": "string", "display": true, "required": false, "displayName": "media_1", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "media_2", "type": "string", "display": true, "required": false, "displayName": "media_2", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "media_3", "type": "string", "display": true, "required": false, "displayName": "media_3", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "media_4", "type": "string", "display": true, "required": false, "displayName": "media_4", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "media_5", "type": "string", "display": true, "required": false, "displayName": "media_5", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "review_id", "type": "string", "display": true, "removed": false, "required": false, "displayName": "review_id", "defaultMatch": false, "canBeUsedToMatch": true}], "mappingMode": "defineBelow", "matchingColumns": ["review_id"], "attemptToConvertTypes": false, "convertFieldsToString": false}, "options": {}, "operation": "appendOrUpdate", "sheetName": {"__rl": true, "mode": "list", "value": 1811842087, "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "helpfulcrowd"}, "documentId": {"__rl": true, "mode": "list", "value": "1yf_RYZGFHpMyOvD3RKGSvIFY2vumvI4474Qm_1t4-jM", "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "Squarespace automation"}}, "credentials": {"googleSheetsOAuth2Api": {"id": "JgI9maibw5DnBXRP", "name": "Google Sheets account"}}, "typeVersion": 4.5, "notes": "This googleSheets node performs automated tasks as part of the workflow."}, {"id": "23f1b89f-ef06-4908-b00a-fa7b1f47b945", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [340, 80], "parameters": {"width": 252, "height": 166, "content": "## Clone this spreadsheet\n\n{{ $env.WEBHOOK_URL }}"}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "2864095b-d6d5-4e58-bd33-0c0b0441df1e", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [340, 360], "parameters": {"width": 252, "height": 326, "content": "### HelpfulCrowd column\n\nCheck this docs\n{{ $env.WEBHOOK_URL }}"}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "d1f55902-441c-4658-ade9-033e89d9681b", "name": "Schedule Trigger", "type": "n8n-nodes-base.scheduleTrigger", "position": [-1300, 120], "parameters": {"rule": {"interval": [{}]}}, "typeVersion": 1.2, "notes": "This scheduleTrigger node performs automated tasks as part of the workflow."}], "active": false, "pinData": {}, "settings": {"executionOrder": "v1", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000}, "versionId": "a4b9bac7-f986-4744-9eeb-1e8faa1bab67", "connections": {"4d208d18-991b-4dfd-a717-8f752ea74a90": {"main": [[{"node": "error-handler-4d208d18-991b-4dfd-a717-8f752ea74a90", "type": "main", "index": 0}], [{"node": "error-handler-4d208d18-991b-4dfd-a717-8f752ea74a90-1fdcdc9d", "type": "main", "index": 0}], [{"node": "error-handler-4d208d18-991b-4dfd-a717-8f752ea74a90-55880d25", "type": "main", "index": 0}], [{"node": "error-handler-4d208d18-991b-4dfd-a717-8f752ea74a90-9394f55d", "type": "main", "index": 0}], [{"node": "error-handler-4d208d18-991b-4dfd-a717-8f752ea74a90-c07e535a", "type": "main", "index": 0}], [{"node": "error-handler-4d208d18-991b-4dfd-a717-8f752ea74a90-fac1b544", "type": "main", "index": 0}], [{"node": "error-handler-4d208d18-991b-4dfd-a717-8f752ea74a90-9c5766a7", "type": "main", "index": 0}], [{"node": "error-handler-4d208d18-991b-4dfd-a717-8f752ea74a90-a1a9f7ef", "type": "main", "index": 0}], [{"node": "error-handler-4d208d18-991b-4dfd-a717-8f752ea74a90-7b33072f", "type": "main", "index": 0}]]}, "13f3720d-0753-49fc-a5e6-1473d5411e29": {"main": [[{"node": "error-handler-13f3720d-0753-49fc-a5e6-1473d5411e29-d1d6e73d", "type": "main", "index": 0}]]}, "0ffeed7c-7787-461f-a47b-704fa665dcc6": {"main": [[{"node": "error-handler-0ffeed7c-7787-461f-a47b-704fa665dcc6-650b5fc1", "type": "main", "index": 0}]]}}, "description": "Automated workflow: Scrape Trustpilot Reviews to Google Sheets. This workflow integrates 9 different services: stickyNote, httpRequest, code, scheduleTrigger, splitOut. It contains 17 nodes and follows best practices for error handling and security.", "notes": "Excellent quality workflow: Scrape Trustpilot Reviews to Google Sheets. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}