From 2b57dcb6e4b5d15c943a9cd0a61a3328c202911f Mon Sep 17 00:00:00 2001 From: nusquama Date: Sun, 15 Mar 2026 12:00:57 +0800 Subject: [PATCH] creation --- ...emails_with_scrapercity_and_sync_contacts_to_hubspot_crm.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 workflows/Reverse lookup emails with ScraperCity and sync contacts to HubSpot CRM-13975/reverse_lookup_emails_with_scrapercity_and_sync_contacts_to_hubspot_crm.json diff --git a/workflows/Reverse lookup emails with ScraperCity and sync contacts to HubSpot CRM-13975/reverse_lookup_emails_with_scrapercity_and_sync_contacts_to_hubspot_crm.json b/workflows/Reverse lookup emails with ScraperCity and sync contacts to HubSpot CRM-13975/reverse_lookup_emails_with_scrapercity_and_sync_contacts_to_hubspot_crm.json new file mode 100644 index 000000000..a17188d5d --- /dev/null +++ b/workflows/Reverse lookup emails with ScraperCity and sync contacts to HubSpot CRM-13975/reverse_lookup_emails_with_scrapercity_and_sync_contacts_to_hubspot_crm.json @@ -0,0 +1 @@ +{"meta":{"templateCredsSetupCompleted":false},"nodes":[{"id":"a1000000-0000-0000-0000-000000000001","name":"When clicking 'Execute workflow'","type":"n8n-nodes-base.manualTrigger","position":[-2000,400],"parameters":{},"typeVersion":1},{"id":"a1000000-0000-0000-0000-000000000002","name":"Configure Lookup Parameters","type":"n8n-nodes-base.set","position":[-1750,400],"parameters":{"options":{},"assignments":{"assignments":[{"id":"cfg-01","name":"emails","type":"string","value":"user@example.com,user@example.com"},{"id":"cfg-02","name":"maxResults","type":"number","value":5}]}},"typeVersion":3.4},{"id":"a1000000-0000-0000-0000-000000000003","name":"Start People Finder Scrape","type":"n8n-nodes-base.httpRequest","position":[-1500,400],"parameters":{"url":"https://app.scrapercity.com/api/v1/scrape/people-finder","method":"POST","options":{},"jsonBody":"={\n \"name\": [],\n \"email\": {{ JSON.stringify($json.emails.split(',').map(e => e.trim())) }},\n \"phone_number\": [],\n \"street_citystatezip\": [],\n \"max_results\": {{ $json.maxResults }}\n}","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"credential-id","name":"ScraperCity API Key"}},"typeVersion":4.2},{"id":"a1000000-0000-0000-0000-000000000004","name":"Store Run ID","type":"n8n-nodes-base.set","position":[-1250,400],"parameters":{"options":{},"assignments":{"assignments":[{"id":"rid-01","name":"runId","type":"string","value":"={{ $json.runId }}"}]}},"typeVersion":3.4},{"id":"a1000000-0000-0000-0000-000000000005","name":"Wait Before First Poll","type":"n8n-nodes-base.wait","position":[-1000,400],"webhookId":"a1000000-wait-0000-0000-000000000005","parameters":{"amount":30},"typeVersion":1.1},{"id":"a1000000-0000-0000-0000-000000000006","name":"Poll Loop","type":"n8n-nodes-base.splitInBatches","position":[-750,400],"parameters":{"options":{"reset":false},"batchSize":1},"typeVersion":3},{"id":"a1000000-0000-0000-0000-000000000007","name":"Check Scrape Status","type":"n8n-nodes-base.httpRequest","position":[-500,400],"parameters":{"url":"=https://app.scrapercity.com/api/v1/scrape/status/{{ $('Store Run ID').item.json.runId }}","method":"GET","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"credential-id","name":"ScraperCity API Key"}},"typeVersion":4.2},{"id":"a1000000-0000-0000-0000-000000000008","name":"Is Scrape Complete?","type":"n8n-nodes-base.if","position":[-250,400],"parameters":{"options":{},"conditions":{"options":{"version":2,"caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"cond-01","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"SUCCEEDED"}]}},"typeVersion":2.2},{"id":"a1000000-0000-0000-0000-000000000009","name":"Wait Before Retry","type":"n8n-nodes-base.wait","position":[-250,592],"webhookId":"a1000000-wait-0000-0000-000000000009","parameters":{"amount":60},"typeVersion":1.1},{"id":"a1000000-0000-0000-0000-000000000010","name":"Download Scrape Results","type":"n8n-nodes-base.httpRequest","position":[0,400],"parameters":{"url":"=https://app.scrapercity.com/api/downloads/{{ $('Store Run ID').item.json.runId }}","method":"GET","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"credential-id","name":"ScraperCity API Key"}},"typeVersion":4.2},{"id":"a1000000-0000-0000-0000-000000000011","name":"Parse CSV Results","type":"n8n-nodes-base.code","position":[250,400],"parameters":{"jsCode":"// Parse CSV text returned by the download endpoint\n// Handles both a raw CSV string and a JSON body with a 'data' or 'csv' field\n\nconst raw = $input.first().json;\nlet csvText = '';\n\nif (typeof raw === 'string') {\n csvText = raw;\n} else if (raw.data && typeof raw.data === 'string') {\n csvText = raw.data;\n} else if (raw.csv && typeof raw.csv === 'string') {\n csvText = raw.csv;\n} else {\n // Fallback: treat entire body as an array of contact objects\n const contacts = Array.isArray(raw) ? raw : (raw.results || []);\n return contacts.map(c => ({ json: c }));\n}\n\nconst lines = csvText.trim().split('\\n').filter(l => l.trim() !== '');\nif (lines.length < 2) return [];\n\nconst headers = lines[0].split(',').map(h => h.trim().replace(/^\"|\"$/g, ''));\n\nconst results = [];\nfor (let i = 1; i < lines.length; i++) {\n const values = lines[i].split(',').map(v => v.trim().replace(/^\"|\"$/g, ''));\n const obj = {};\n headers.forEach((h, idx) => {\n obj[h] = values[idx] || '';\n });\n results.push({ json: obj });\n}\n\nreturn results;"},"typeVersion":2},{"id":"a1000000-0000-0000-0000-000000000012","name":"Remove Duplicate Contacts","type":"n8n-nodes-base.removeDuplicates","position":[500,400],"parameters":{"options":{},"fieldsToCompare":{"fields":[{"fieldName":"email"}]}},"typeVersion":2},{"id":"a1000000-0000-0000-0000-000000000013","name":"Filter Valid Contacts","type":"n8n-nodes-base.filter","position":[750,400],"parameters":{"options":{},"conditions":{"options":{"version":2,"caseSensitive":false,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"flt-01","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.email }}","rightValue":""}]}},"typeVersion":2.2},{"id":"a1000000-0000-0000-0000-000000000014","name":"Map Contact Fields","type":"n8n-nodes-base.set","position":[1000,400],"parameters":{"options":{},"assignments":{"assignments":[{"id":"map-01","name":"email","type":"string","value":"={{ ($json.email || '').trim().toLowerCase() }}"},{"id":"map-02","name":"firstName","type":"string","value":"={{ $json.first_name || $json.firstName || '' }}"},{"id":"map-03","name":"lastName","type":"string","value":"={{ $json.last_name || $json.lastName || '' }}"},{"id":"map-04","name":"phone","type":"string","value":"={{ $json.phone || $json.phone_number || '' }}"},{"id":"map-05","name":"address","type":"string","value":"={{ $json.address || $json.street || '' }}"},{"id":"map-06","name":"city","type":"string","value":"={{ $json.city || '' }}"},{"id":"map-07","name":"state","type":"string","value":"={{ $json.state || '' }}"},{"id":"map-08","name":"zip","type":"string","value":"={{ $json.zip || $json.zipcode || '' }}"}]}},"typeVersion":3.4},{"id":"a1000000-0000-0000-0000-000000000015","name":"Upsert Contact in HubSpot","type":"n8n-nodes-base.hubspot","position":[1250,400],"parameters":{"email":"={{ $json.email }}","options":{},"authentication":"appToken","additionalFields":{"zip":"={{ $json.zip }}","city":"={{ $json.city }}","phone":"={{ $json.phone }}","state":"={{ $json.state }}","message":"=Address: {{ $json.address }}, {{ $json.city }}, {{ $json.state }} {{ $json.zip }}\nSource: ScraperCity People Finder reverse lookup","lastName":"={{ $json.lastName }}","firstName":"={{ $json.firstName }}"}},"credentials":{"hubspotAppToken":{"id":"credential-id","name":"HubSpot App Token"}},"typeVersion":2},{"id":"a1000000-0000-0000-0000-000000000099","name":"Overview","type":"n8n-nodes-base.stickyNote","position":[-2600,100],"parameters":{"width":450,"height":580,"content":"## How it works\n1. **Configure Lookup Parameters** -- set the email addresses you want to reverse-lookup and the max results per search.\n2. **Start People Finder Scrape** -- submits the emails to ScraperCity and receives an async job ID.\n3. **Polling loop** -- checks job status every 60 seconds until the scrape status is SUCCEEDED.\n4. **Download and parse** -- fetches the CSV result, parses rows into contact records, deduplicates by email, and filters out rows missing an email.\n5. **Upsert to HubSpot** -- maps name, phone, and address fields and creates or updates each contact in HubSpot CRM.\n\n## Setup steps\n1. Add a **ScraperCity API Key** credential: HTTP Header Auth, header `Authorization`, value `Bearer YOUR_KEY`.\n2. Add a **HubSpot App Token** credential using your HubSpot private app token.\n3. In **Configure Lookup Parameters**, replace the example emails with your target list (comma-separated).\n4. Click **Execute workflow** to run."},"typeVersion":1},{"id":"a1000000-0000-0000-0000-000000000100","name":"Section -- Config","type":"n8n-nodes-base.stickyNote","position":[-2040,-160],"parameters":{"color":7,"width":730,"height":330,"content":"## Configuration\n**Configure Lookup Parameters** is the only node you must edit. Enter target emails as a comma-separated string. **max_results** controls how many address records ScraperCity returns per email. All credentials are managed through n8n credential store -- no API keys in node parameters."},"typeVersion":1},{"id":"a1000000-0000-0000-0000-000000000101","name":"Section -- Scrape Submit","type":"n8n-nodes-base.stickyNote","position":[-1290,-160],"parameters":{"color":7,"width":730,"height":330,"content":"## Scrape Submission\n**Start People Finder Scrape** posts the email list to ScraperCity's People Finder endpoint. **Store Run ID** captures the returned `runId` so the polling loop can reference it. **Wait Before First Poll** pauses 30 seconds before the first status check."},"typeVersion":1},{"id":"a1000000-0000-0000-0000-000000000102","name":"Section -- Async Polling Loop","type":"n8n-nodes-base.stickyNote","position":[-540,-160],"parameters":{"color":7,"width":480,"height":530,"content":"## Async Polling Loop\n**Poll Loop** iterates the status check. **Check Scrape Status** queries `/api/v1/scrape/status/{runId}`. **Is Scrape Complete?** routes to download on `SUCCEEDED`. Otherwise **Wait Before Retry** pauses 60 seconds and routes back into **Poll Loop** to retry. ScraperCity scrapes typically finish in 10--60 minutes."},"typeVersion":1},{"id":"a1000000-0000-0000-0000-000000000103","name":"Section -- Results Processing","type":"n8n-nodes-base.stickyNote","position":[-40,-160],"parameters":{"color":7,"width":730,"height":330,"content":"## Results Processing\n**Download Scrape Results** fetches the completed CSV. **Parse CSV Results** converts rows to JSON objects. **Remove Duplicate Contacts** deduplicates by email field. **Filter Valid Contacts** drops any rows without an email address. **Map Contact Fields** normalises field names ready for HubSpot."},"typeVersion":1},{"id":"a1000000-0000-0000-0000-000000000104","name":"Section -- HubSpot Output","type":"n8n-nodes-base.stickyNote","position":[710,-160],"parameters":{"color":7,"width":730,"height":330,"content":"## HubSpot Output\n**Upsert Contact in HubSpot** creates or updates a contact for each result using the email as the unique key. Address, phone, city, state, and zip are all written to standard HubSpot contact properties. Add a HubSpot App Token credential before running."},"typeVersion":1}],"settings":{"executionOrder":"v1"},"connections":{"Poll Loop":{"main":[[{"node":"Check Scrape Status","type":"main","index":0}],[]]},"Store Run ID":{"main":[[{"node":"Wait Before First Poll","type":"main","index":0}]]},"Parse CSV Results":{"main":[[{"node":"Remove Duplicate Contacts","type":"main","index":0}]]},"Wait Before Retry":{"main":[[{"node":"Poll Loop","type":"main","index":0}]]},"Map Contact Fields":{"main":[[{"node":"Upsert Contact in HubSpot","type":"main","index":0}]]},"Check Scrape Status":{"main":[[{"node":"Is Scrape Complete?","type":"main","index":0}]]},"Is Scrape Complete?":{"main":[[{"node":"Download Scrape Results","type":"main","index":0}],[{"node":"Wait Before Retry","type":"main","index":0}]]},"Filter Valid Contacts":{"main":[[{"node":"Map Contact Fields","type":"main","index":0}]]},"Wait Before First Poll":{"main":[[{"node":"Poll Loop","type":"main","index":0}]]},"Download Scrape Results":{"main":[[{"node":"Parse CSV Results","type":"main","index":0}]]},"Remove Duplicate Contacts":{"main":[[{"node":"Filter Valid Contacts","type":"main","index":0}]]},"Start People Finder Scrape":{"main":[[{"node":"Store Run ID","type":"main","index":0}]]},"Configure Lookup Parameters":{"main":[[{"node":"Start People Finder Scrape","type":"main","index":0}]]},"When clicking 'Execute workflow'":{"main":[[{"node":"Configure Lookup Parameters","type":"main","index":0}]]}}} \ No newline at end of file