AutomationFlowsWeb Scraping › Wholestack Wf-010: Seller Communication

Wholestack Wf-010: Seller Communication

WholeStack WF-010: Seller Communication. Uses httpRequest. Webhook trigger; 14 nodes.

Webhook trigger★★★★☆ complexity14 nodesHTTP Request
Web Scraping Trigger: Webhook Nodes: 14 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": "WholeStack WF-010: Seller Communication",
  "nodes": [
    {
      "id": "webhook",
      "name": "Seller Notify Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        250,
        300
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "wholestack-seller-notify",
        "responseMode": "responseNode",
        "options": {}
      },
      "onError": "continueRegularOutput"
    },
    {
      "id": "fetchDeal",
      "name": "Fetch Deal",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        470,
        300
      ],
      "parameters": {
        "method": "POST",
        "url": "https://YOUR_CONVEX_DEPLOYMENT.convex.site/getDeal",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ dealId: $json.body.dealId }) }}"
      }
    },
    {
      "id": "ifHasSeller",
      "name": "IF Has Seller",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        690,
        300
      ],
      "parameters": {
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond1",
              "leftValue": "={{ $json.data.sellerId }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              }
            }
          ]
        }
      }
    },
    {
      "id": "respondNoSeller",
      "name": "Respond No Seller",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        910,
        450
      ],
      "parameters": {
        "respondWith": "json",
        "responseCode": 200,
        "responseBody": "={{ JSON.stringify({ success: true, skipped: true, reason: 'no_seller' }) }}"
      }
    },
    {
      "id": "fetchSeller",
      "name": "Fetch Seller",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        910,
        150
      ],
      "parameters": {
        "method": "POST",
        "url": "https://YOUR_CONVEX_DEPLOYMENT.convex.site/getSeller",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ sellerId: $('Fetch Deal').first().json.data.sellerId }) }}"
      }
    },
    {
      "id": "selectTemplate",
      "name": "Select SMS Template",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1130,
        150
      ],
      "parameters": {
        "jsCode": "var deal = $('Fetch Deal').first().json.data;\nvar seller = $input.first().json.data;\nvar newStatus = $('Seller Notify Webhook').first().json.newStatus;\nvar event = $('Seller Notify Webhook').first().json.event;\nvar context = $('Seller Notify Webhook').first().json.context || {};\n\nif (seller.status === 'dnc') {\n  return { json: { shouldSend: false, reason: 'seller_dnc' } };\n}\n\nvar templates = {\n  'active': 'Your property at ' + deal.address + ' is live with our buyers. I will keep you posted.',\n  'first_interest': 'Got interest on ' + deal.address + '. Working on it.',\n  'reserved': 'Buyer locked in on ' + deal.address + '. Getting next steps together.',\n  'package_sent': 'Full package sent to the buyer on ' + deal.address + '. I will follow up.',\n  'under_contract': 'Contract signed on ' + deal.address + '. Closing process started.',\n  'expired': 'No bites yet on ' + deal.address + '. Want to adjust the price?',\n  'sold': 'Closed on ' + deal.address + '. Assignment fee: $' + ((context.assignmentFee || deal.assignmentFee || 0).toLocaleString()) + '. Thanks for the deal!'\n};\n\nvar templateKey = event === 'first_interest' ? 'first_interest' : newStatus;\nvar smsText = templates[templateKey] || templates['active'];\n\nreturn { json: { shouldSend: true, seller: seller, deal: deal, smsText: smsText } };"
      }
    },
    {
      "id": "ifShouldSend",
      "name": "IF Should Send SMS",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1350,
        150
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond2",
              "leftValue": "={{ $json.shouldSend }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ]
        }
      }
    },
    {
      "id": "respondDnc",
      "name": "Respond Seller DNC",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1570,
        300
      ],
      "parameters": {
        "respondWith": "json",
        "responseCode": 200,
        "responseBody": "={{ JSON.stringify({ success: true, skipped: true, reason: 'seller_dnc' }) }}"
      }
    },
    {
      "id": "sendSms",
      "name": "Send Seller SMS",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1570,
        0
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.close.com/api/v1/activity/sms/",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ lead_id: $json.seller.closeLeadId || null, local_phone: '+15555550100', remote_phone: $json.seller.phone, text: $json.smsText, direction: 'outbound', status: 'outbox' }) }}"
      },
      "disabled": false
    },
    {
      "id": "updateSellerContact",
      "name": "Update Seller Contact",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1790,
        0
      ],
      "parameters": {
        "method": "POST",
        "url": "https://YOUR_CONVEX_DEPLOYMENT.convex.site/updateSellerStatus",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ sellerId: $('Select SMS Template').first().json.seller._id, lastContacted: Date.now() }) }}"
      }
    },
    {
      "id": "respondSuccess",
      "name": "Respond Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        2010,
        0
      ],
      "parameters": {
        "respondWith": "json",
        "responseCode": 200,
        "responseBody": "={{ JSON.stringify({ success: true, sellerId: $('Select SMS Template').first().json.seller._id, smsSent: true }) }}"
      }
    },
    {
      "id": "get-close-status",
      "name": "Get Close Lead Status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1460,
        0
      ],
      "parameters": {
        "method": "GET",
        "url": "=https://api.close.com/api/v1/lead/{{ $json.seller.closeLeadId }}/",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "options": {}
      },
      "onError": "continueRegularOutput"
    },
    {
      "id": "check-protected",
      "name": "Check Protected Status",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1510,
        0
      ],
      "parameters": {
        "jsCode": "// Check if seller lead has protected status\nvar closeData = $json;\nvar templateData = $('Select SMS Template').first().json;\nvar statusLabel = (closeData.status_label || '').toLowerCase().trim();\n\n// PROTECTED STATUSES - NO SMS for these\nvar protectedStatuses = [\n  'human hand', 'hot lead', 'hot', 'warm lead',\n  'interested', 'not interested', 'dnc', 'dead',\n  'vetted buyer', 'vip'\n];\n\nvar isProtected = protectedStatuses.indexOf(statusLabel) !== -1;\n\nreturn [{\n  json: {\n    ...templateData,\n    _closeStatus: statusLabel,\n    _isProtectedStatus: isProtected,\n    canSend: !isProtected\n  }\n}];"
      }
    },
    {
      "id": "is-protected",
      "name": "Is Protected?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1510,
        100
      ],
      "parameters": {
        "conditions": {
          "conditions": [
            {
              "id": "protected-check",
              "leftValue": "={{ $json.canSend }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and",
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          }
        },
        "options": {}
      }
    }
  ],
  "connections": {
    "Seller Notify Webhook": {
      "main": [
        [
          {
            "node": "Fetch Deal",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Deal": {
      "main": [
        [
          {
            "node": "IF Has Seller",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Has Seller": {
      "main": [
        [
          {
            "node": "Fetch Seller",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond No Seller",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Seller": {
      "main": [
        [
          {
            "node": "Select SMS Template",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select SMS Template": {
      "main": [
        [
          {
            "node": "IF Should Send SMS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Should Send SMS": {
      "main": [
        [
          {
            "node": "Get Close Lead Status",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond Seller DNC",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Close Lead Status": {
      "main": [
        [
          {
            "node": "Check Protected Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Protected Status": {
      "main": [
        [
          {
            "node": "Is Protected?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Protected?": {
      "main": [
        [
          {
            "node": "Send Seller SMS",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond Seller DNC",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Seller SMS": {
      "main": [
        [
          {
            "node": "Update Seller Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Seller Contact": {
      "main": [
        [
          {
            "node": "Respond Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "all",
    "saveManualExecutions": true,
    "saveExecutionProgress": true,
    "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

WholeStack WF-010: Seller Communication. Uses httpRequest. Webhook trigger; 14 nodes.

Source: https://github.com/rafiulislam4246/real-estate-disposition-workflows/blob/main/workflows/10-seller-communication.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