n8n-nodes-real-estate-api 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +160 -0
- package/dist/credentials/RealEstateApi.credentials.d.ts +9 -0
- package/dist/credentials/RealEstateApi.credentials.js +55 -0
- package/dist/credentials/RealEstateApi.credentials.js.map +1 -0
- package/dist/nodes/RealEstateApi/RealEstateApi.node.d.ts +5 -0
- package/dist/nodes/RealEstateApi/RealEstateApi.node.js +583 -0
- package/dist/nodes/RealEstateApi/RealEstateApi.node.js.map +1 -0
- package/dist/nodes/RealEstateApi/realEstateApi.svg +29 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jason Pellerin / AI Solutionist
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# n8n-nodes-real-estate-api
|
|
2
|
+
|
|
3
|
+
n8n community node for extracting property data from **Zillow** and **Redfin** with built-in PerimeterX anti-bot bypass.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 🏠 **Multi-Source Data**: Extract from Zillow and Redfin simultaneously
|
|
11
|
+
- 💰 **Zestimate Access**: Get automated home valuations (Zestimate, Rent Zestimate)
|
|
12
|
+
- 🛡️ **PerimeterX Bypass**: Built-in anti-bot protection with 99% success rate
|
|
13
|
+
- 🔧 **Self-Healing Selectors**: Auto-adapts when websites change
|
|
14
|
+
- 🚀 **Stealth Mode**: Three levels of detection avoidance
|
|
15
|
+
- 📊 **Rich Property Data**: Price, beds, baths, sqft, year built, lot size, and more
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
### Community Nodes (Recommended)
|
|
20
|
+
|
|
21
|
+
1. Go to **Settings** > **Community Nodes**
|
|
22
|
+
2. Select **Install**
|
|
23
|
+
3. Enter `n8n-nodes-real-estate-api`
|
|
24
|
+
4. Click **Install**
|
|
25
|
+
|
|
26
|
+
### Manual Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd ~/.n8n/nodes
|
|
30
|
+
npm install n8n-nodes-real-estate-api
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Then restart n8n.
|
|
34
|
+
|
|
35
|
+
## Credentials Setup
|
|
36
|
+
|
|
37
|
+
1. **Apify API Token** (Required)
|
|
38
|
+
- Sign up at [apify.com](https://apify.com)
|
|
39
|
+
- Find your token at Console → Settings → Integrations
|
|
40
|
+
|
|
41
|
+
2. **ScraperAPI Key** (Highly Recommended for Zillow)
|
|
42
|
+
- Sign up at [scraperapi.com](https://scraperapi.com)
|
|
43
|
+
- Get 5,000 free requests
|
|
44
|
+
- 99% success rate bypassing Zillow's PerimeterX
|
|
45
|
+
|
|
46
|
+
3. **2Captcha Key** (Optional Backup)
|
|
47
|
+
- Only needed if not using ScraperAPI
|
|
48
|
+
- Get key at [2captcha.com](https://2captcha.com)
|
|
49
|
+
|
|
50
|
+
## Operations
|
|
51
|
+
|
|
52
|
+
### Search by Location
|
|
53
|
+
Find properties in a city, ZIP code, or county:
|
|
54
|
+
- `Denver, CO`
|
|
55
|
+
- `80202`
|
|
56
|
+
- `Los Angeles County`
|
|
57
|
+
|
|
58
|
+
### Search by Address
|
|
59
|
+
Look up a specific property:
|
|
60
|
+
- `1624 Market St, Denver, CO 80202`
|
|
61
|
+
|
|
62
|
+
### Get by ZPID
|
|
63
|
+
Fetch by Zillow Property ID:
|
|
64
|
+
- `13385952`
|
|
65
|
+
|
|
66
|
+
### Get by URL
|
|
67
|
+
Extract from direct listing URLs:
|
|
68
|
+
- `https://www.zillow.com/homedetails/13385952_zpid/`
|
|
69
|
+
|
|
70
|
+
## Output Schema
|
|
71
|
+
|
|
72
|
+
Each property returns:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"zpid": "13385952",
|
|
77
|
+
"address": "1624 Market St",
|
|
78
|
+
"city": "Denver",
|
|
79
|
+
"state": "CO",
|
|
80
|
+
"zipCode": "80202",
|
|
81
|
+
"price": 750000,
|
|
82
|
+
"beds": 3,
|
|
83
|
+
"baths": 2,
|
|
84
|
+
"sqft": 1850,
|
|
85
|
+
"zestimate": 785000,
|
|
86
|
+
"rentZestimate": 3200,
|
|
87
|
+
"yearBuilt": 2015,
|
|
88
|
+
"lotSize": 4500,
|
|
89
|
+
"propertyType": "single_family",
|
|
90
|
+
"listingStatus": "for_sale",
|
|
91
|
+
"daysOnMarket": 14,
|
|
92
|
+
"url": "https://www.zillow.com/...",
|
|
93
|
+
"source": "zillow",
|
|
94
|
+
"extractedAt": "2026-01-23T12:00:00Z"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Filter Options
|
|
99
|
+
|
|
100
|
+
When searching by location, you can filter by:
|
|
101
|
+
|
|
102
|
+
| Filter | Description | Example |
|
|
103
|
+
|--------|-------------|---------|
|
|
104
|
+
| Listing Status | for_sale, pending, sold, for_rent, off_market | `["for_sale", "pending"]` |
|
|
105
|
+
| Property Types | single_family, condo, townhouse, multi_family, land | `["condo", "townhouse"]` |
|
|
106
|
+
| Price Range | Min/Max price | $300,000 - $800,000 |
|
|
107
|
+
| Bedrooms | Min/Max beds | 2 - 4 beds |
|
|
108
|
+
| Bathrooms | Min baths | 2+ baths |
|
|
109
|
+
| Square Feet | Min/Max sqft | 1,500 - 3,000 sqft |
|
|
110
|
+
|
|
111
|
+
## Stealth Levels
|
|
112
|
+
|
|
113
|
+
| Level | Speed | Reliability | Use Case |
|
|
114
|
+
|-------|-------|-------------|----------|
|
|
115
|
+
| Standard | Fast | ~85% | Quick lookups, testing |
|
|
116
|
+
| Careful | Medium | ~95% | Production (recommended) |
|
|
117
|
+
| Paranoid | Slow | ~99% | Large batches, sensitive operations |
|
|
118
|
+
|
|
119
|
+
## Example Workflows
|
|
120
|
+
|
|
121
|
+
### Lead Enrichment
|
|
122
|
+
Enrich real estate leads with current Zestimates:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
[Webhook] → [Real Estate API: Get by Address] → [Update CRM]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Market Analysis
|
|
129
|
+
Track properties in a market:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
[Schedule Trigger] → [Real Estate API: Search Location] → [Google Sheets]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Price Alerts
|
|
136
|
+
Monitor price changes:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
[Schedule Trigger] → [Real Estate API: Get by ZPID] → [IF Price Changed] → [Send Email]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Pricing
|
|
143
|
+
|
|
144
|
+
- **Actor Start**: $0.005 per run
|
|
145
|
+
- **Per Property**: $0.02 per extracted property
|
|
146
|
+
- **Free Tier**: Available through Apify
|
|
147
|
+
|
|
148
|
+
## Support
|
|
149
|
+
|
|
150
|
+
- **Issues**: [GitHub Issues](https://github.com/ai-solutionist/n8n-nodes-real-estate-api/issues)
|
|
151
|
+
- **Documentation**: [Apify Actor Page](https://apify.com/ai_solutionist/real-estate-data-api)
|
|
152
|
+
- **Author**: Jason Pellerin ([jasonpellerin.com](https://jasonpellerinfreelance.com))
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
Built with ❤️ by [AI Solutionist](https://jasonpellerinfreelance.com)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class RealEstateApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
authenticate: IAuthenticateGeneric;
|
|
8
|
+
test: ICredentialTestRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RealEstateApi = void 0;
|
|
4
|
+
class RealEstateApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'realEstateApi';
|
|
7
|
+
this.displayName = 'Real Estate API';
|
|
8
|
+
this.documentationUrl = 'https://docs.apify.com/platform/integrations/api';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'Apify API Token',
|
|
12
|
+
name: 'apiToken',
|
|
13
|
+
type: 'string',
|
|
14
|
+
typeOptions: { password: true },
|
|
15
|
+
default: '',
|
|
16
|
+
required: true,
|
|
17
|
+
description: 'Your Apify API token. Find it at https://console.apify.com/account/integrations',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
displayName: 'ScraperAPI Key (Recommended)',
|
|
21
|
+
name: 'scraperApiKey',
|
|
22
|
+
type: 'string',
|
|
23
|
+
typeOptions: { password: true },
|
|
24
|
+
default: '',
|
|
25
|
+
required: false,
|
|
26
|
+
description: 'HIGHLY RECOMMENDED for Zillow. 99% success rate bypassing PerimeterX. Get 5000 free: scraperapi.com/signup',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
displayName: '2Captcha Key (Backup)',
|
|
30
|
+
name: 'twoCaptchaKey',
|
|
31
|
+
type: 'string',
|
|
32
|
+
typeOptions: { password: true },
|
|
33
|
+
default: '',
|
|
34
|
+
required: false,
|
|
35
|
+
description: 'Fallback CAPTCHA solver. Get key at 2captcha.com',
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
this.authenticate = {
|
|
39
|
+
type: 'generic',
|
|
40
|
+
properties: {
|
|
41
|
+
headers: {
|
|
42
|
+
Authorization: '=Bearer {{$credentials.apiToken}}',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
this.test = {
|
|
47
|
+
request: {
|
|
48
|
+
baseURL: 'https://api.apify.com/v2',
|
|
49
|
+
url: '/users/me',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.RealEstateApi = RealEstateApi;
|
|
55
|
+
//# sourceMappingURL=RealEstateApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealEstateApi.credentials.js","sourceRoot":"","sources":["../../credentials/RealEstateApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,aAAa;IAA1B;QACC,SAAI,GAAG,eAAe,CAAC;QACvB,gBAAW,GAAG,iBAAiB,CAAC;QAChC,qBAAgB,GAAG,kDAAkD,CAAC;QAEtE,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,iBAAiB;gBAC9B,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,iFAAiF;aAC9F;YACD;gBACC,WAAW,EAAE,8BAA8B;gBAC3C,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,4GAA4G;aACzH;YACD;gBACC,WAAW,EAAE,uBAAuB;gBACpC,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,kDAAkD;aAC/D;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,mCAAmC;iBAClD;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,0BAA0B;gBACnC,GAAG,EAAE,WAAW;aAChB;SACD,CAAC;IACH,CAAC;CAAA;AAlDD,sCAkDC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class RealEstateApi implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RealEstateApi = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
class RealEstateApi {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Real Estate API',
|
|
9
|
+
name: 'realEstateApi',
|
|
10
|
+
icon: 'file:realEstateApi.svg',
|
|
11
|
+
group: ['transform'],
|
|
12
|
+
version: 1,
|
|
13
|
+
subtitle: '={{$parameter["operation"]}}',
|
|
14
|
+
description: 'Extract Zillow & Redfin property data, Zestimates, and valuations with PerimeterX bypass',
|
|
15
|
+
defaults: {
|
|
16
|
+
name: 'Real Estate API',
|
|
17
|
+
},
|
|
18
|
+
inputs: ['main'],
|
|
19
|
+
outputs: ['main'],
|
|
20
|
+
credentials: [
|
|
21
|
+
{
|
|
22
|
+
name: 'realEstateApi',
|
|
23
|
+
required: true,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
properties: [
|
|
27
|
+
// Operation
|
|
28
|
+
{
|
|
29
|
+
displayName: 'Operation',
|
|
30
|
+
name: 'operation',
|
|
31
|
+
type: 'options',
|
|
32
|
+
noDataExpression: true,
|
|
33
|
+
options: [
|
|
34
|
+
{
|
|
35
|
+
name: 'Search by Location',
|
|
36
|
+
value: 'searchLocation',
|
|
37
|
+
description: 'Search properties by city, ZIP, or county',
|
|
38
|
+
action: 'Search properties by location',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'Search by Address',
|
|
42
|
+
value: 'searchAddress',
|
|
43
|
+
description: 'Find a specific property by street address',
|
|
44
|
+
action: 'Search property by address',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Get by ZPID',
|
|
48
|
+
value: 'getByZpid',
|
|
49
|
+
description: 'Get property details by Zillow Property ID',
|
|
50
|
+
action: 'Get property by Zillow ID',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'Get by URL',
|
|
54
|
+
value: 'getByUrl',
|
|
55
|
+
description: 'Extract data from Zillow/Redfin listing URL',
|
|
56
|
+
action: 'Get property by URL',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'Get Run Status',
|
|
60
|
+
value: 'getStatus',
|
|
61
|
+
description: 'Check the status of a property extraction run',
|
|
62
|
+
action: 'Get run status',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
default: 'searchLocation',
|
|
66
|
+
},
|
|
67
|
+
// ==========================================
|
|
68
|
+
// SEARCH BY LOCATION
|
|
69
|
+
// ==========================================
|
|
70
|
+
{
|
|
71
|
+
displayName: 'Location',
|
|
72
|
+
name: 'location',
|
|
73
|
+
type: 'string',
|
|
74
|
+
default: '',
|
|
75
|
+
required: true,
|
|
76
|
+
displayOptions: {
|
|
77
|
+
show: {
|
|
78
|
+
operation: ['searchLocation'],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
description: 'City and state, ZIP code, or county. Examples: "Denver, CO", "80202", "Los Angeles County"',
|
|
82
|
+
placeholder: 'Denver, CO',
|
|
83
|
+
},
|
|
84
|
+
// ==========================================
|
|
85
|
+
// SEARCH BY ADDRESS
|
|
86
|
+
// ==========================================
|
|
87
|
+
{
|
|
88
|
+
displayName: 'Street Address',
|
|
89
|
+
name: 'address',
|
|
90
|
+
type: 'string',
|
|
91
|
+
default: '',
|
|
92
|
+
required: true,
|
|
93
|
+
displayOptions: {
|
|
94
|
+
show: {
|
|
95
|
+
operation: ['searchAddress'],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
description: 'Full street address for single property lookup',
|
|
99
|
+
placeholder: '1624 Market St, Denver, CO 80202',
|
|
100
|
+
},
|
|
101
|
+
// ==========================================
|
|
102
|
+
// GET BY ZPID
|
|
103
|
+
// ==========================================
|
|
104
|
+
{
|
|
105
|
+
displayName: 'Zillow Property IDs',
|
|
106
|
+
name: 'zpids',
|
|
107
|
+
type: 'string',
|
|
108
|
+
default: '',
|
|
109
|
+
required: true,
|
|
110
|
+
displayOptions: {
|
|
111
|
+
show: {
|
|
112
|
+
operation: ['getByZpid'],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
description: 'Comma-separated Zillow Property IDs. Find in URL: .../13385952_zpid/',
|
|
116
|
+
placeholder: '13385952, 13385953',
|
|
117
|
+
},
|
|
118
|
+
// ==========================================
|
|
119
|
+
// GET BY URL
|
|
120
|
+
// ==========================================
|
|
121
|
+
{
|
|
122
|
+
displayName: 'Property URLs',
|
|
123
|
+
name: 'urls',
|
|
124
|
+
type: 'string',
|
|
125
|
+
typeOptions: {
|
|
126
|
+
rows: 4,
|
|
127
|
+
},
|
|
128
|
+
default: '',
|
|
129
|
+
required: true,
|
|
130
|
+
displayOptions: {
|
|
131
|
+
show: {
|
|
132
|
+
operation: ['getByUrl'],
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
description: 'Zillow or Redfin property URLs (one per line)',
|
|
136
|
+
placeholder: 'https://www.zillow.com/homedetails/...',
|
|
137
|
+
},
|
|
138
|
+
// ==========================================
|
|
139
|
+
// COMMON OPTIONS FOR ALL SEARCH TYPES
|
|
140
|
+
// ==========================================
|
|
141
|
+
{
|
|
142
|
+
displayName: 'Data Source',
|
|
143
|
+
name: 'sources',
|
|
144
|
+
type: 'multiOptions',
|
|
145
|
+
options: [
|
|
146
|
+
{
|
|
147
|
+
name: 'Zillow',
|
|
148
|
+
value: 'zillow',
|
|
149
|
+
description: 'Includes Zestimate valuations',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'Redfin',
|
|
153
|
+
value: 'redfin',
|
|
154
|
+
description: 'Includes Redfin Estimate',
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
default: ['zillow'],
|
|
158
|
+
displayOptions: {
|
|
159
|
+
show: {
|
|
160
|
+
operation: ['searchLocation', 'searchAddress'],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
description: 'Which platforms to extract from',
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
displayName: 'Max Results',
|
|
167
|
+
name: 'maxResults',
|
|
168
|
+
type: 'number',
|
|
169
|
+
default: 50,
|
|
170
|
+
displayOptions: {
|
|
171
|
+
show: {
|
|
172
|
+
operation: ['searchLocation'],
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
description: 'Maximum properties to return (1-500)',
|
|
176
|
+
typeOptions: {
|
|
177
|
+
minValue: 1,
|
|
178
|
+
maxValue: 500,
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
displayName: 'Include Zestimate',
|
|
183
|
+
name: 'includeValuations',
|
|
184
|
+
type: 'boolean',
|
|
185
|
+
default: true,
|
|
186
|
+
displayOptions: {
|
|
187
|
+
show: {
|
|
188
|
+
operation: ['searchLocation', 'searchAddress', 'getByZpid', 'getByUrl'],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
description: 'Whether to fetch Zestimate and valuation data (adds ~1s per property)',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
displayName: 'Wait for Completion',
|
|
195
|
+
name: 'waitForCompletion',
|
|
196
|
+
type: 'boolean',
|
|
197
|
+
default: true,
|
|
198
|
+
displayOptions: {
|
|
199
|
+
show: {
|
|
200
|
+
operation: ['searchLocation', 'searchAddress', 'getByZpid', 'getByUrl'],
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
description: 'Whether to wait for extraction to complete',
|
|
204
|
+
},
|
|
205
|
+
// ==========================================
|
|
206
|
+
// FILTERS (Location Search Only)
|
|
207
|
+
// ==========================================
|
|
208
|
+
{
|
|
209
|
+
displayName: 'Filters',
|
|
210
|
+
name: 'filters',
|
|
211
|
+
type: 'collection',
|
|
212
|
+
placeholder: 'Add Filter',
|
|
213
|
+
default: {},
|
|
214
|
+
displayOptions: {
|
|
215
|
+
show: {
|
|
216
|
+
operation: ['searchLocation'],
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
options: [
|
|
220
|
+
{
|
|
221
|
+
displayName: 'Listing Status',
|
|
222
|
+
name: 'listingStatus',
|
|
223
|
+
type: 'multiOptions',
|
|
224
|
+
options: [
|
|
225
|
+
{ name: 'For Sale', value: 'for_sale' },
|
|
226
|
+
{ name: 'Pending', value: 'pending' },
|
|
227
|
+
{ name: 'Sold', value: 'sold' },
|
|
228
|
+
{ name: 'For Rent', value: 'for_rent' },
|
|
229
|
+
{ name: 'Off Market', value: 'off_market' },
|
|
230
|
+
],
|
|
231
|
+
default: ['for_sale'],
|
|
232
|
+
description: 'Filter by property listing status',
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
displayName: 'Property Types',
|
|
236
|
+
name: 'propertyTypes',
|
|
237
|
+
type: 'multiOptions',
|
|
238
|
+
options: [
|
|
239
|
+
{ name: 'Single Family', value: 'single_family' },
|
|
240
|
+
{ name: 'Condo', value: 'condo' },
|
|
241
|
+
{ name: 'Townhouse', value: 'townhouse' },
|
|
242
|
+
{ name: 'Multi Family', value: 'multi_family' },
|
|
243
|
+
{ name: 'Land', value: 'land' },
|
|
244
|
+
{ name: 'Manufactured', value: 'manufactured' },
|
|
245
|
+
{ name: 'Apartment', value: 'apartment' },
|
|
246
|
+
],
|
|
247
|
+
default: ['single_family', 'condo', 'townhouse'],
|
|
248
|
+
description: 'Filter by property type',
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
displayName: 'Min Price',
|
|
252
|
+
name: 'priceMin',
|
|
253
|
+
type: 'number',
|
|
254
|
+
default: 0,
|
|
255
|
+
description: 'Minimum listing price ($)',
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
displayName: 'Max Price',
|
|
259
|
+
name: 'priceMax',
|
|
260
|
+
type: 'number',
|
|
261
|
+
default: 0,
|
|
262
|
+
description: 'Maximum listing price ($). 0 = no limit.',
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
displayName: 'Min Bedrooms',
|
|
266
|
+
name: 'bedsMin',
|
|
267
|
+
type: 'number',
|
|
268
|
+
default: 0,
|
|
269
|
+
description: 'Minimum number of bedrooms',
|
|
270
|
+
typeOptions: { minValue: 0, maxValue: 10 },
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
displayName: 'Max Bedrooms',
|
|
274
|
+
name: 'bedsMax',
|
|
275
|
+
type: 'number',
|
|
276
|
+
default: 0,
|
|
277
|
+
description: 'Maximum number of bedrooms. 0 = no limit.',
|
|
278
|
+
typeOptions: { minValue: 0, maxValue: 10 },
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
displayName: 'Min Bathrooms',
|
|
282
|
+
name: 'bathsMin',
|
|
283
|
+
type: 'number',
|
|
284
|
+
default: 0,
|
|
285
|
+
description: 'Minimum number of bathrooms',
|
|
286
|
+
typeOptions: { minValue: 0, maxValue: 10 },
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
displayName: 'Min Sqft',
|
|
290
|
+
name: 'sqftMin',
|
|
291
|
+
type: 'number',
|
|
292
|
+
default: 0,
|
|
293
|
+
description: 'Minimum square footage',
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
displayName: 'Max Sqft',
|
|
297
|
+
name: 'sqftMax',
|
|
298
|
+
type: 'number',
|
|
299
|
+
default: 0,
|
|
300
|
+
description: 'Maximum square footage. 0 = no limit.',
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
},
|
|
304
|
+
// ==========================================
|
|
305
|
+
// ADDITIONAL OPTIONS
|
|
306
|
+
// ==========================================
|
|
307
|
+
{
|
|
308
|
+
displayName: 'Additional Options',
|
|
309
|
+
name: 'additionalOptions',
|
|
310
|
+
type: 'collection',
|
|
311
|
+
placeholder: 'Add Option',
|
|
312
|
+
default: {},
|
|
313
|
+
displayOptions: {
|
|
314
|
+
show: {
|
|
315
|
+
operation: ['searchLocation', 'searchAddress', 'getByZpid', 'getByUrl'],
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
options: [
|
|
319
|
+
{
|
|
320
|
+
displayName: 'Stealth Level',
|
|
321
|
+
name: 'stealthLevel',
|
|
322
|
+
type: 'options',
|
|
323
|
+
options: [
|
|
324
|
+
{ name: 'Standard (Fast)', value: 'standard', description: 'Quick but may hit rate limits' },
|
|
325
|
+
{ name: 'Careful (Recommended)', value: 'careful', description: 'Balanced speed and reliability' },
|
|
326
|
+
{ name: 'Paranoid (Safest)', value: 'paranoid', description: 'Slowest but maximum stealth' },
|
|
327
|
+
],
|
|
328
|
+
default: 'careful',
|
|
329
|
+
description: 'Anti-bot detection avoidance level',
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
displayName: 'Include Photos',
|
|
333
|
+
name: 'includePhotos',
|
|
334
|
+
type: 'boolean',
|
|
335
|
+
default: false,
|
|
336
|
+
description: 'Whether to include property photo URLs',
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
displayName: 'Include Price History',
|
|
340
|
+
name: 'includeHistory',
|
|
341
|
+
type: 'boolean',
|
|
342
|
+
default: false,
|
|
343
|
+
description: 'Whether to include historical listing prices',
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
displayName: 'Self-Healing Mode',
|
|
347
|
+
name: 'selfHealingEnabled',
|
|
348
|
+
type: 'boolean',
|
|
349
|
+
default: true,
|
|
350
|
+
description: 'Whether to auto-fix selectors when website changes',
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
displayName: 'Timeout (seconds)',
|
|
354
|
+
name: 'timeout',
|
|
355
|
+
type: 'number',
|
|
356
|
+
default: 300,
|
|
357
|
+
description: 'Maximum time to wait for completion',
|
|
358
|
+
},
|
|
359
|
+
],
|
|
360
|
+
},
|
|
361
|
+
// ==========================================
|
|
362
|
+
// GET STATUS OPERATION
|
|
363
|
+
// ==========================================
|
|
364
|
+
{
|
|
365
|
+
displayName: 'Run ID',
|
|
366
|
+
name: 'runId',
|
|
367
|
+
type: 'string',
|
|
368
|
+
default: '',
|
|
369
|
+
required: true,
|
|
370
|
+
displayOptions: {
|
|
371
|
+
show: {
|
|
372
|
+
operation: ['getStatus'],
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
description: 'The ID of the actor run to check',
|
|
376
|
+
},
|
|
377
|
+
],
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
async execute() {
|
|
381
|
+
var _a, _b;
|
|
382
|
+
const items = this.getInputData();
|
|
383
|
+
const returnData = [];
|
|
384
|
+
const operation = this.getNodeParameter('operation', 0);
|
|
385
|
+
const credentials = await this.getCredentials('realEstateApi');
|
|
386
|
+
const baseUrl = 'https://api.apify.com/v2';
|
|
387
|
+
const actorId = 'ai_solutionist~real-estate-data-api';
|
|
388
|
+
for (let i = 0; i < items.length; i++) {
|
|
389
|
+
try {
|
|
390
|
+
if (operation === 'searchLocation' || operation === 'searchAddress' || operation === 'getByZpid' || operation === 'getByUrl') {
|
|
391
|
+
// Build input payload based on operation
|
|
392
|
+
const input = {};
|
|
393
|
+
// Add ScraperAPI key if provided
|
|
394
|
+
if (credentials.scraperApiKey) {
|
|
395
|
+
input.scraperApiKey = credentials.scraperApiKey;
|
|
396
|
+
}
|
|
397
|
+
if (credentials.twoCaptchaKey) {
|
|
398
|
+
input.twoCaptchaKey = credentials.twoCaptchaKey;
|
|
399
|
+
}
|
|
400
|
+
// Set search type and parameters
|
|
401
|
+
if (operation === 'searchLocation') {
|
|
402
|
+
input.searchType = 'location';
|
|
403
|
+
input.location = this.getNodeParameter('location', i);
|
|
404
|
+
input.maxResults = this.getNodeParameter('maxResults', i);
|
|
405
|
+
input.sources = this.getNodeParameter('sources', i);
|
|
406
|
+
// Add filters
|
|
407
|
+
const filters = this.getNodeParameter('filters', i);
|
|
408
|
+
if ((_a = filters.listingStatus) === null || _a === void 0 ? void 0 : _a.length)
|
|
409
|
+
input.listingStatus = filters.listingStatus;
|
|
410
|
+
if ((_b = filters.propertyTypes) === null || _b === void 0 ? void 0 : _b.length)
|
|
411
|
+
input.propertyTypes = filters.propertyTypes;
|
|
412
|
+
if (filters.priceMin)
|
|
413
|
+
input.priceMin = filters.priceMin;
|
|
414
|
+
if (filters.priceMax)
|
|
415
|
+
input.priceMax = filters.priceMax;
|
|
416
|
+
if (filters.bedsMin)
|
|
417
|
+
input.bedsMin = filters.bedsMin;
|
|
418
|
+
if (filters.bedsMax)
|
|
419
|
+
input.bedsMax = filters.bedsMax;
|
|
420
|
+
if (filters.bathsMin)
|
|
421
|
+
input.bathsMin = filters.bathsMin;
|
|
422
|
+
if (filters.sqftMin)
|
|
423
|
+
input.sqftMin = filters.sqftMin;
|
|
424
|
+
if (filters.sqftMax)
|
|
425
|
+
input.sqftMax = filters.sqftMax;
|
|
426
|
+
}
|
|
427
|
+
else if (operation === 'searchAddress') {
|
|
428
|
+
input.searchType = 'address';
|
|
429
|
+
input.address = this.getNodeParameter('address', i);
|
|
430
|
+
input.sources = this.getNodeParameter('sources', i);
|
|
431
|
+
}
|
|
432
|
+
else if (operation === 'getByZpid') {
|
|
433
|
+
input.searchType = 'zpid';
|
|
434
|
+
const zpidsInput = this.getNodeParameter('zpids', i);
|
|
435
|
+
input.zpids = zpidsInput.split(',').map((z) => z.trim()).filter((z) => z.length > 0);
|
|
436
|
+
}
|
|
437
|
+
else if (operation === 'getByUrl') {
|
|
438
|
+
input.searchType = 'url';
|
|
439
|
+
const urlsInput = this.getNodeParameter('urls', i);
|
|
440
|
+
input.urls = urlsInput.split(/[\n,]/).map((u) => u.trim()).filter((u) => u.length > 0);
|
|
441
|
+
}
|
|
442
|
+
// Common options
|
|
443
|
+
input.includeValuations = this.getNodeParameter('includeValuations', i);
|
|
444
|
+
const waitForCompletion = this.getNodeParameter('waitForCompletion', i);
|
|
445
|
+
// Additional options
|
|
446
|
+
const additionalOptions = this.getNodeParameter('additionalOptions', i);
|
|
447
|
+
input.stealthLevel = additionalOptions.stealthLevel || 'careful';
|
|
448
|
+
input.includePhotos = additionalOptions.includePhotos || false;
|
|
449
|
+
input.includeHistory = additionalOptions.includeHistory || false;
|
|
450
|
+
input.selfHealingEnabled = additionalOptions.selfHealingEnabled !== false;
|
|
451
|
+
// Start the actor run
|
|
452
|
+
const startResponse = await this.helpers.httpRequest({
|
|
453
|
+
method: 'POST',
|
|
454
|
+
url: `${baseUrl}/acts/${actorId}/runs`,
|
|
455
|
+
headers: {
|
|
456
|
+
Authorization: `Bearer ${credentials.apiToken}`,
|
|
457
|
+
'Content-Type': 'application/json',
|
|
458
|
+
},
|
|
459
|
+
body: input,
|
|
460
|
+
json: true,
|
|
461
|
+
});
|
|
462
|
+
const runId = startResponse.data.id;
|
|
463
|
+
const datasetId = startResponse.data.defaultDatasetId;
|
|
464
|
+
if (!waitForCompletion) {
|
|
465
|
+
returnData.push({
|
|
466
|
+
json: {
|
|
467
|
+
success: true,
|
|
468
|
+
status: 'RUNNING',
|
|
469
|
+
runId,
|
|
470
|
+
datasetId,
|
|
471
|
+
message: 'Property extraction started. Use "Get Run Status" to check progress.',
|
|
472
|
+
},
|
|
473
|
+
});
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
// Poll for completion
|
|
477
|
+
const timeout = (additionalOptions.timeout || 300) * 1000;
|
|
478
|
+
const startTime = Date.now();
|
|
479
|
+
let status = 'RUNNING';
|
|
480
|
+
while (status === 'RUNNING' && Date.now() - startTime < timeout) {
|
|
481
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
482
|
+
const statusResponse = await this.helpers.httpRequest({
|
|
483
|
+
method: 'GET',
|
|
484
|
+
url: `${baseUrl}/actor-runs/${runId}`,
|
|
485
|
+
headers: {
|
|
486
|
+
Authorization: `Bearer ${credentials.apiToken}`,
|
|
487
|
+
},
|
|
488
|
+
json: true,
|
|
489
|
+
});
|
|
490
|
+
status = statusResponse.data.status;
|
|
491
|
+
}
|
|
492
|
+
if (status !== 'SUCCEEDED') {
|
|
493
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Property extraction failed with status: ${status}`, { itemIndex: i });
|
|
494
|
+
}
|
|
495
|
+
// Fetch results
|
|
496
|
+
const resultsResponse = await this.helpers.httpRequest({
|
|
497
|
+
method: 'GET',
|
|
498
|
+
url: `${baseUrl}/datasets/${datasetId}/items`,
|
|
499
|
+
headers: {
|
|
500
|
+
Authorization: `Bearer ${credentials.apiToken}`,
|
|
501
|
+
},
|
|
502
|
+
json: true,
|
|
503
|
+
});
|
|
504
|
+
const results = Array.isArray(resultsResponse) ? resultsResponse : [resultsResponse];
|
|
505
|
+
// Return each property as a separate item
|
|
506
|
+
for (const property of results) {
|
|
507
|
+
returnData.push({
|
|
508
|
+
json: {
|
|
509
|
+
// Core fields
|
|
510
|
+
zpid: property.zpid,
|
|
511
|
+
address: property.address,
|
|
512
|
+
city: property.city,
|
|
513
|
+
state: property.state,
|
|
514
|
+
zipCode: property.zipCode,
|
|
515
|
+
price: property.price,
|
|
516
|
+
beds: property.beds,
|
|
517
|
+
baths: property.baths,
|
|
518
|
+
sqft: property.sqft,
|
|
519
|
+
// Valuations
|
|
520
|
+
zestimate: property.zestimate,
|
|
521
|
+
rentZestimate: property.rentZestimate,
|
|
522
|
+
redfinEstimate: property.redfinEstimate,
|
|
523
|
+
// Additional details
|
|
524
|
+
yearBuilt: property.yearBuilt,
|
|
525
|
+
lotSize: property.lotSize,
|
|
526
|
+
propertyType: property.propertyType,
|
|
527
|
+
listingStatus: property.listingStatus,
|
|
528
|
+
daysOnMarket: property.daysOnMarket,
|
|
529
|
+
// Photos & History
|
|
530
|
+
photos: property.photos,
|
|
531
|
+
priceHistory: property.priceHistory,
|
|
532
|
+
// URLs
|
|
533
|
+
url: property.url,
|
|
534
|
+
// Metadata
|
|
535
|
+
source: property.source,
|
|
536
|
+
extractedAt: property.extractedAt,
|
|
537
|
+
_runId: runId,
|
|
538
|
+
_datasetId: datasetId,
|
|
539
|
+
},
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
else if (operation === 'getStatus') {
|
|
544
|
+
const runId = this.getNodeParameter('runId', i);
|
|
545
|
+
const response = await this.helpers.httpRequest({
|
|
546
|
+
method: 'GET',
|
|
547
|
+
url: `${baseUrl}/actor-runs/${runId}`,
|
|
548
|
+
headers: {
|
|
549
|
+
Authorization: `Bearer ${credentials.apiToken}`,
|
|
550
|
+
},
|
|
551
|
+
json: true,
|
|
552
|
+
});
|
|
553
|
+
returnData.push({
|
|
554
|
+
json: {
|
|
555
|
+
runId,
|
|
556
|
+
status: response.data.status,
|
|
557
|
+
startedAt: response.data.startedAt,
|
|
558
|
+
finishedAt: response.data.finishedAt,
|
|
559
|
+
datasetId: response.data.defaultDatasetId,
|
|
560
|
+
isFinished: ['SUCCEEDED', 'FAILED', 'ABORTED', 'TIMED-OUT'].includes(response.data.status),
|
|
561
|
+
},
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
catch (error) {
|
|
566
|
+
if (this.continueOnFail()) {
|
|
567
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
568
|
+
returnData.push({
|
|
569
|
+
json: {
|
|
570
|
+
error: errorMessage,
|
|
571
|
+
},
|
|
572
|
+
pairedItem: { item: i },
|
|
573
|
+
});
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
throw error;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
return [returnData];
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
exports.RealEstateApi = RealEstateApi;
|
|
583
|
+
//# sourceMappingURL=RealEstateApi.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealEstateApi.node.js","sourceRoot":"","sources":["../../../nodes/RealEstateApi/RealEstateApi.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" style="stop-color:#10b981"/>
|
|
5
|
+
<stop offset="100%" style="stop-color:#059669"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
|
|
9
|
+
<!-- Background -->
|
|
10
|
+
<rect width="100" height="100" rx="16" fill="url(#bgGrad)"/>
|
|
11
|
+
|
|
12
|
+
<!-- House shape -->
|
|
13
|
+
<path d="M50 18 L82 45 L82 82 L18 82 L18 45 Z" fill="white" opacity="0.95"/>
|
|
14
|
+
|
|
15
|
+
<!-- Roof -->
|
|
16
|
+
<path d="M50 12 L88 45 L82 45 L50 18 L18 45 L12 45 Z" fill="white"/>
|
|
17
|
+
|
|
18
|
+
<!-- Door -->
|
|
19
|
+
<rect x="42" y="55" width="16" height="27" rx="2" fill="#10b981"/>
|
|
20
|
+
|
|
21
|
+
<!-- Windows -->
|
|
22
|
+
<rect x="26" y="50" width="12" height="12" rx="1" fill="#10b981"/>
|
|
23
|
+
<rect x="62" y="50" width="12" height="12" rx="1" fill="#10b981"/>
|
|
24
|
+
|
|
25
|
+
<!-- Data dots -->
|
|
26
|
+
<circle cx="72" cy="28" r="4" fill="#fbbf24"/>
|
|
27
|
+
<circle cx="82" cy="36" r="3" fill="#fbbf24"/>
|
|
28
|
+
<circle cx="78" cy="22" r="2.5" fill="#fbbf24"/>
|
|
29
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-real-estate-api",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "n8n community node for Real Estate Data API - Extract Zillow & Redfin property data with PerimeterX bypass",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"n8n",
|
|
8
|
+
"real-estate",
|
|
9
|
+
"zillow",
|
|
10
|
+
"redfin",
|
|
11
|
+
"property",
|
|
12
|
+
"zestimate",
|
|
13
|
+
"api",
|
|
14
|
+
"scraper",
|
|
15
|
+
"apify",
|
|
16
|
+
"proptech",
|
|
17
|
+
"mls",
|
|
18
|
+
"automation"
|
|
19
|
+
],
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"homepage": "https://github.com/ai-solutionist/n8n-nodes-real-estate-api",
|
|
22
|
+
"author": {
|
|
23
|
+
"name": "Jason Pellerin",
|
|
24
|
+
"email": "jason@jasonpellerin.com",
|
|
25
|
+
"url": "https://jasonpellerinfreelance.com"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/ai-solutionist/n8n-nodes-real-estate-api.git"
|
|
30
|
+
},
|
|
31
|
+
"main": "index.js",
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc && gulp build:icons",
|
|
34
|
+
"dev": "tsc --watch",
|
|
35
|
+
"format": "prettier nodes credentials --write",
|
|
36
|
+
"lint": "eslint nodes credentials package.json",
|
|
37
|
+
"lintfix": "eslint nodes credentials package.json --fix",
|
|
38
|
+
"prepublishOnly": "npm run build"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist"
|
|
42
|
+
],
|
|
43
|
+
"n8n": {
|
|
44
|
+
"n8nNodesApiVersion": 1,
|
|
45
|
+
"credentials": [
|
|
46
|
+
"dist/credentials/RealEstateApi.credentials.js"
|
|
47
|
+
],
|
|
48
|
+
"nodes": [
|
|
49
|
+
"dist/nodes/RealEstateApi/RealEstateApi.node.js"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^20.10.0",
|
|
54
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
55
|
+
"eslint": "^8.56.0",
|
|
56
|
+
"gulp": "^4.0.2",
|
|
57
|
+
"n8n-workflow": "^1.0.0",
|
|
58
|
+
"prettier": "^3.1.0",
|
|
59
|
+
"typescript": "^5.3.0"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"n8n-workflow": "*"
|
|
63
|
+
}
|
|
64
|
+
}
|