AutomationFlowsWeb Scraping › Wf-rev-intake — Owner Text → Customer

Wf-rev-intake — Owner Text → Customer

WF-REV-INTAKE — Owner Text → Customer. Uses httpRequest. Webhook trigger; 16 nodes.

Webhook trigger★★★★☆ complexity16 nodesHTTP Request
Web Scraping Trigger: Webhook Nodes: 16 Complexity: ★★★★☆ Added:

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "WF-REV-INTAKE \u2014 Owner Text \u2192 Customer",
  "nodes": [
    {
      "id": "1",
      "name": "Webhook (Close Inbound)",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        240,
        300
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "wf-rev-intake",
        "responseMode": "onReceived",
        "options": {}
      },
      "notes": "Trigger: Close CRM inbound SMS webhook to client's dedicated intake number",
      "onError": "continueRegularOutput"
    },
    {
      "id": "2",
      "name": "Parse Owner Text",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        300
      ],
      "parameters": {
        "language": "javaScript",
        "jsCode": "// Parse 'FirstName +1XXXXXXXXXX' or 'FirstName XXX-XXX-XXXX'\nconst text = $input.first().json.body?.event?.data?.text || '';\nconst intakePhone = $input.first().json.body?.event?.data?.local_phone || '';\nconst ownerPhone = $input.first().json.body?.event?.data?.remote_phone || '';\nconst match = text.match(/^([A-Za-z]+(?:\\s+[A-Za-z]+)?)\\s+(\\+?1?\\s*\\(?\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{4})$/);\nif (!match) { return [{ json: { parseError: true, text, ownerPhone, intakePhone } }]; }\nconst firstName = match[1].trim();\nconst rawPhone = match[2].replace(/[^0-9]/g, '');\nconst phone = rawPhone.length === 10 ? `+1${rawPhone}` : `+${rawPhone}`;\nreturn [{ json: { parseError: false, firstName, phone, ownerPhone, intakePhone } }];"
      }
    },
    {
      "id": "3",
      "name": "Lookup Client by Intake Phone",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        680,
        300
      ],
      "parameters": {
        "url": "=https://YOUR_CONVEX_DEPLOYMENT/reviews/client-by-intake-phone?intakePhone={{ encodeURIComponent($json.intakePhone) }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpHeaderAuth"
      },
      "notes": "Get clientId from intake phone number",
      "onError": "continueRegularOutput",
      "retryOnFail": true
    },
    {
      "id": "4",
      "name": "POST Customer Add",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        900,
        300
      ],
      "parameters": {
        "method": "POST",
        "url": "https://YOUR_CONVEX_DEPLOYMENT/reviews/customer-add-via-text",
        "sendBody": true,
        "bodyContentType": "json",
        "jsonBody": "={{ JSON.stringify({ clientId: $('Lookup Client by Intake Phone').item.json.clientId, firstName: $('Parse Owner Text').item.json.firstName, phone: $('Parse Owner Text').item.json.phone, intakedFromOwnerPhone: $('Parse Owner Text').item.json.ownerPhone }) }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpHeaderAuth"
      },
      "notes": "Create customer, kick off drip",
      "onError": "continueRegularOutput",
      "retryOnFail": true
    },
    {
      "id": "ad5d35d0-4122-45b8-9cdf-be5b5a94e66c",
      "name": "Parse Error?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        660,
        480
      ],
      "parameters": {
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.parseError }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "id": "condition-1783697634651-ltjeh9fes"
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "d33f0ad0-c5f2-497f-8cb9-fa8ea758c930",
      "name": "SMS Owner: Parse Error",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        880,
        580
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.close.com/api/v1/activity/sms/",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "sendBody": true,
        "bodyContentType": "json",
        "jsonBody": "={{ JSON.stringify({ direction: 'outbound', status: 'outbox', local_phone: $json.intakePhone, remote_phone: $json.ownerPhone, text: 'Couldn\\'t read that. Format: FirstName +1234567890 (or) FirstName 415-555-1234. Try again.' }) }}",
        "options": {}
      },
      "onError": "continueRegularOutput",
      "retryOnFail": true
    },
    {
      "id": "760268a0-2712-4ed9-94ab-03e1b359196d",
      "name": "Check Global Opt-Out",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1100,
        300
      ],
      "parameters": {
        "method": "GET",
        "url": "=https://YOUR_CONVEX_DEPLOYMENT/reviews/opt-out-check?phone={{ encodeURIComponent($node['Parse Owner Text'].json.phone) }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpHeaderAuth"
      },
      "onError": "continueRegularOutput",
      "retryOnFail": true
    },
    {
      "id": "a4ea3b17-3a02-4018-a22c-d009bb7735e5",
      "name": "Is Opted Out?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        1320,
        300
      ],
      "parameters": {
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.optedOut }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "id": "condition-1783701081725-bln2hufww"
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "cb81e966-1796-453e-9156-5991fd0cafe4",
      "name": "SMS Owner: Opt-Out Warning",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1540,
        200
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.close.com/api/v1/activity/sms/",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "sendBody": true,
        "bodyContentType": "json",
        "jsonBody": "={{ JSON.stringify({ direction: 'outbound', status: 'outbox', local_phone: $node['Webhook (Close Inbound)'].json.body.event.data.local_phone, remote_phone: $node['Webhook (Close Inbound)'].json.body.event.data.remote_phone, text: 'Heads up: ' + $node['Parse Owner Text'].json.firstName + ' has opted out of review texts. Not adding to drip.' }) }}",
        "options": {}
      },
      "onError": "continueRegularOutput",
      "retryOnFail": true
    },
    {
      "id": "c5617a0e-7225-40d7-b68e-7ec9dacb49e9",
      "name": "SMS Owner: Confirm Added",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1980,
        300
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.close.com/api/v1/activity/sms/",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "sendBody": true,
        "bodyContentType": "json",
        "jsonBody": "={{ JSON.stringify({ direction: 'outbound', status: 'outbox', local_phone: $node['Webhook (Close Inbound)'].json.body.event.data.local_phone, remote_phone: $node['Webhook (Close Inbound)'].json.body.event.data.remote_phone, text: 'Got it \u2014 ' + $node['Parse Owner Text'].json.firstName + ' added. Check-in text goes out in 2 hours.' }) }}",
        "options": {}
      },
      "onError": "continueRegularOutput",
      "retryOnFail": true
    },
    {
      "id": "04df5a42-00b6-450a-b385-784a1ad730f5",
      "name": "Lookup Found?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        800,
        300
      ],
      "parameters": {
        "conditions": {
          "combinator": "and",
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ Boolean($json.clientId) }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "id": "condition-lookup-found"
            }
          ]
        }
      },
      "notes": "H4: gate downstream on client lookup success."
    },
    {
      "id": "77fffc48-63f3-4830-a02a-2ccba5650521",
      "name": "SMS Owner: Not Registered",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1020,
        460
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.close.com/api/v1/activity/sms/",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "sendBody": true,
        "bodyContentType": "json",
        "jsonBody": "={{ JSON.stringify({ direction: 'outbound', status: 'outbox', local_phone: $node['Webhook (Close Inbound)'].json.body.event.data.local_phone, remote_phone: $node['Webhook (Close Inbound)'].json.body.event.data.remote_phone, text: \"This number isn't registered for Review Engine \u2014 contact support.\" }) }}",
        "options": {}
      },
      "notes": "H4: sent when intake phone lookup returns no client.",
      "onError": "continueRegularOutput",
      "retryOnFail": true
    },
    {
      "id": "e8783c03-0379-407e-a275-6269944dc4de",
      "name": "Customer Add OK?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        1120,
        300
      ],
      "parameters": {
        "conditions": {
          "combinator": "and",
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.ok }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "id": "condition-customer-ok"
            }
          ]
        }
      },
      "notes": "H5: branch on POST Customer Add response \u2014 success / duplicate / opted-out."
    },
    {
      "id": "78b8b652-bc00-4cb6-b023-2df1c2cbab52",
      "name": "Duplicate?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        1340,
        460
      ],
      "parameters": {
        "conditions": {
          "combinator": "and",
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ ($json.reason || '') === 'duplicate' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "id": "condition-duplicate"
            }
          ]
        }
      },
      "notes": "H5: dupe branch vs opt-out branch."
    },
    {
      "id": "261ec2da-3459-4870-b963-607ca5cd3320",
      "name": "SMS Owner: Duplicate",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1560,
        380
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.close.com/api/v1/activity/sms/",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "sendBody": true,
        "bodyContentType": "json",
        "jsonBody": "={{ JSON.stringify({ direction: 'outbound', status: 'outbox', local_phone: $node['Webhook (Close Inbound)'].json.body.event.data.local_phone, remote_phone: $node['Webhook (Close Inbound)'].json.body.event.data.remote_phone, text: $node['Parse Owner Text'].json.firstName + ' already in your list.' }) }}",
        "options": {}
      },
      "notes": "H5: honest response when customer already exists.",
      "onError": "continueRegularOutput",
      "retryOnFail": true
    },
    {
      "id": "831e5ac2-0d61-47c3-9dae-6c62ddab7570",
      "name": "SMS Owner: Opt-Out (Add)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1560,
        540
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.close.com/api/v1/activity/sms/",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "sendBody": true,
        "bodyContentType": "json",
        "jsonBody": "={{ JSON.stringify({ direction: 'outbound', status: 'outbox', local_phone: $node['Webhook (Close Inbound)'].json.body.event.data.local_phone, remote_phone: $node['Webhook (Close Inbound)'].json.body.event.data.remote_phone, text: $node['Parse Owner Text'].json.firstName + ' has opted out \u2014 not added.' }) }}",
        "options": {}
      },
      "notes": "H5: honest response when target is on the global opt-out list.",
      "onError": "continueRegularOutput",
      "retryOnFail": true
    }
  ],
  "connections": {
    "Webhook (Close Inbound)": {
      "main": [
        [
          {
            "node": "Parse Owner Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Owner Text": {
      "main": [
        [
          {
            "node": "Parse Error?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Error?": {
      "main": [
        [
          {
            "node": "SMS Owner: Parse Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Lookup Client by Intake Phone",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Global Opt-Out": {
      "main": [
        [
          {
            "node": "Is Opted Out?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Opted Out?": {
      "main": [
        [
          {
            "node": "SMS Owner: Opt-Out Warning",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "POST Customer Add",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Client by Intake Phone": {
      "main": [
        [
          {
            "node": "Lookup Found?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Found?": {
      "main": [
        [
          {
            "node": "Check Global Opt-Out",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "SMS Owner: Not Registered",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "POST Customer Add": {
      "main": [
        [
          {
            "node": "Customer Add OK?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Customer Add OK?": {
      "main": [
        [
          {
            "node": "SMS Owner: Confirm Added",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Duplicate?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Duplicate?": {
      "main": [
        [
          {
            "node": "SMS Owner: Duplicate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "SMS Owner: Opt-Out (Add)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "America/New_York",
    "saveDataSuccessExecution": "none",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  },
  "active": false
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

WF-REV-INTAKE — Owner Text → Customer. Uses httpRequest. Webhook trigger; 16 nodes.

Source: https://github.com/rafiulislam4246/review-engine/blob/main/workflows/01-intake-owner-text-to-customer.json — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di

n8n, Execute Workflow Trigger, HTTP Request +1
Web Scraping

This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .

HTTP Request, Ssh
Web Scraping

eek-Go v2 (Batch-Then-Review). Uses httpRequest. Webhook trigger; 75 nodes.

HTTP Request
Web Scraping

This workflow receives webhook requests from a content calendar and uses the X API v2 to publish text posts, threads, image/video posts, and polls, as well as delete existing posts and run a credentia

HTTP Request
Web Scraping

This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c

HTTP Request