n8n-nodes-immometrica-v2
Version:
n8n community node for ImmoMetrica real estate data extraction with CSV-based approach and agent tool compatibility
266 lines • 12.4 kB
TypeScript
import type { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
import { WebDriver } from 'selenium-webdriver';
interface SavedSearch {
id: string;
title: string;
url: string;
resultCount?: number;
}
interface PropertyData {
address: string;
propertyType: string;
buildingType: string;
purchasePrice: number;
pricePerSqm: number;
livingAreaSqm: number;
rooms: number;
yearBuilt: number;
condition: string;
availableFrom: string;
commissionPercent: number;
commissionText: string;
privateSale: boolean;
isRented: boolean;
isForeclosure: boolean;
hasTerrace: boolean;
hasGarden: boolean;
hasGuestToilet: boolean;
hasBasement: boolean;
energyCertificateAvailable: boolean;
energySource: string;
heatingType: string;
expectedRentPerMonth: number;
expectedRentPerSqm: number;
expectedYieldPercent: number;
actualYieldPercent: number;
estimatedRentSoll: number;
estimatedRentPerSqmSoll: number;
marketValuation: number;
marketValuationPerSqm: number;
marketValuationEstimatePerSqm: number;
marketDeviationPercent: number;
regionalAverageYield: number;
regionalPricePerSqm: number;
regionalMarketDeviationPercent: number;
immometricaMarktumfeldRenditeSoll: number;
immometricaMarktumfeldRenditeIst: number;
immometricaMarktumfeldMieteSoll: number;
immometricaMarktumfeldMieteIst: number;
firstSeenDate: string;
daysOnline: number;
isNew: boolean;
isActive?: boolean;
platformLinks: {
immoscout?: string;
immowelt?: string;
immonet?: string;
};
immometricaLink: string;
sourceSearchName: string;
sourceSearchId: string;
scrapeTimestamp: string;
postalCode: string;
title: string;
maintenanceCosts: number;
grossYieldPercent: number;
trend: string;
isPrivateSale: boolean;
currency: string;
cashFlow: number;
csvPlatformLinks: {
immoscout?: string;
kleinanzeigen?: string;
immonet?: string;
immowelt?: string;
ohneMakler?: string;
wohnungJetzt?: string;
regionalimmobilien?: string;
zvg24?: string;
homegate?: string;
newhome?: string;
flatfox?: string;
willhaben?: string;
immoscoutat?: string;
derstandard?: string;
makler?: string;
zeitungen?: string;
};
fullPageText?: string;
}
export declare class ImmoMetrica implements INodeType {
private static sessionCache;
private static csvCache;
description: INodeTypeDescription;
methods: {
loadOptions: {
/**
* Retrieves saved searches from ImmoMetrica for use in node parameter options
* @description Loads all available saved searches from the user's ImmoMetrica account
* and formats them as options for the savedSearchId parameter dropdown
* @returns Promise<INodePropertyOptions[]> Array of saved search options with name and value
* @throws {Error} When credentials are invalid or ImmoMetrica is unreachable
* @example
* // Returns format:
* [
* { name: "Zurich Apartments", value: "search-123" },
* { name: "Basel Houses", value: "search-456" }
* ]
*/
getSavedSearches(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
};
};
/**
* Main execution method for the ImmoMetrica node
* @description Executes the selected operation (getSavedSearches or extractPropertyData)
* with support for AI agent tool input parsing and comprehensive error handling
* @returns Promise<INodeExecutionData[][]> Array of execution results with property data
* @throws {NodeOperationError} When operation fails or invalid parameters provided
* @example
* // Tool input for AI agents:
* {
* "operation": "extractPropertyData",
* "savedSearchId": "search-123",
* "maxResults": 100,
* "enableDetailScraping": true
* }
*
* // Returns:
* [[{ json: { properties: [...], metadata: {...} } }]]
*/
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
/**
* Creates and configures a Chrome WebDriver instance for web scraping
* @description Sets up a headless Chrome WebDriver with optimized options for ImmoMetrica scraping
* @returns Promise<WebDriver> Configured Chrome WebDriver with headless options
* @throws {Error} When Chrome/ChromeDriver is not available or configuration fails
* @example
* const driver = await ImmoMetrica.createWebDriver();
* // Returns configured headless Chrome WebDriver with security and performance options
*/
static createWebDriver(): Promise<WebDriver>;
/**
* Authenticates with ImmoMetrica using provided credentials
* @description Handles login with session caching, retry logic, and automatic session validation
* @param driver WebDriver instance for browser automation
* @param email ImmoMetrica account email address
* @param password ImmoMetrica account password
* @param baseUrl ImmoMetrica base URL (e.g., https://www.immometrica.com)
* @param retryCount Current retry attempt number (default: 0)
* @returns Promise<void> Resolves when login is successful
* @throws {Error} When login fails after maximum retry attempts or credentials are invalid
* @example
* await node.loginToImmoMetrica(driver, 'user@example.com', 'password', 'https://www.immometrica.com');
* // Logs in with session caching and automatic retry on failure
*/
loginToImmoMetrica(driver: WebDriver, email: string, password: string, baseUrl: string, retryCount?: number): Promise<void>;
/**
* Retrieves all saved searches from the user's ImmoMetrica account
* @description Scrapes the saved searches page to extract search IDs, titles, URLs, and result counts
* @param driver WebDriver instance for browser automation
* @param baseUrl ImmoMetrica base URL (e.g., https://www.immometrica.com)
* @returns Promise<SavedSearch[]> Array of saved search objects with id, title, url, and resultCount
* @throws {Error} When unable to access saved searches page or parse search data
* @example
* const searches = await node.getSavedSearches(driver, 'https://www.immometrica.com');
* // Returns: [{ id: "123", title: "Zurich Apartments", url: "...", resultCount: 45 }]
*/
getSavedSearches(driver: WebDriver, baseUrl: string): Promise<SavedSearch[]>;
/**
* Extracts property data from ImmoMetrica using CSV download with optional detail scraping
* @description Main data extraction method that downloads CSV data and optionally scrapes detailed property information
* @param driver WebDriver instance for browser automation
* @param baseUrl ImmoMetrica base URL (e.g., https://www.immometrica.com)
* @param savedSearchId ID of the saved search to extract data from
* @param searchName Human-readable name of the search for logging
* @param maxResults Maximum number of properties to extract (limited to 1000 by ImmoMetrica)
* @param enableDetailScraping Whether to scrape detailed property information from individual pages
* @param filterOptions Additional filtering options to apply to the results
* @returns Promise<PropertyData[]> Array of property data objects with basic and detailed information
* @throws {Error} When search ID is invalid, CSV download fails, or detail scraping encounters errors
* @example
* const properties = await node.extractPropertyDataCSV(
* driver, 'https://www.immometrica.com', 'search-123', 'Zurich Apartments', 100, true, {}
* );
* // Returns array of PropertyData objects with comprehensive property information
*/
extractPropertyDataCSV(driver: WebDriver, baseUrl: string, savedSearchId: string, searchName: string, maxResults: number, enableDetailScraping: boolean, filterOptions: any): Promise<PropertyData[]>;
/**
* Downloads CSV data from the current ImmoMetrica search results page
* @description Attempts to download CSV data with caching and retry logic, falls back to table scraping if needed
* @param driver WebDriver instance for browser automation
* @param retryCount Current retry attempt number (default: 0)
* @returns Promise<string> CSV data as string with property information
* @throws {Error} When CSV download fails after maximum retry attempts or session expires
* @example
* const csvData = await node.downloadCSVFromPage(driver);
* // Returns CSV string with property data that can be parsed
* @private
*/
private downloadCSVFromPage;
private fallbackTableScraping;
private parseNumber;
private parseBoolean;
/**
* Extracts detailed property information from individual property pages
* @description Scrapes comprehensive property details including amenities, platform links, and additional KPIs
* @param driver WebDriver instance for browser automation
* @param detailsUrl URL of the individual property detail page
* @param retryCount Current retry attempt number (default: 0)
* @returns Promise<Partial<PropertyData>> Object containing detailed property information
* @throws {Error} When detail page is inaccessible or scraping fails after retries
* @example
* const details = await node.extractPropertyDetails(driver, 'https://immometrica.com/property/123');
* // Returns: { energyLabel: 'B', hasBalcony: true, platformLinks: {...}, ... }
* @private
*/
private extractPropertyDetails;
/**
* Extracts and processes individual field data from property detail pages
* @param details - Partial property data object to populate
* @param key - Field key/name from the detail page (case-insensitive)
* @param value - Field value from the detail page
* @description Processes various property fields including:
* - Art field extraction for accurate property type classification (v1.0.9+)
* - Energy certificate and heating information
* - Commission and availability details
* - Property condition and amenities
* - Fallback logic for property type when Art field is missing
*/
private extractDetailField;
private applyKPIFallbacks;
private extractKPIFromText;
private extractAmenities;
private extractPlatformLinks;
private passesFilters;
getRegionalStatistics(driver: WebDriver, baseUrl: string): Promise<any>;
getMarketOverview(): Promise<any>;
/**
* Validates and sanitizes operation parameter for AI agent tool integration
* @param operation - Operation name from tool input (case-insensitive)
* @param node - n8n node instance for error reporting
* @returns string Validated and properly cased operation name
* @throws NodeOperationError if operation is invalid or not supported
* @example
* const validOp = node.validateAndSanitizeOperation('extractpropertydata', this.getNode());
* // Returns: 'extractPropertyData'
*/
validateAndSanitizeOperation(operation: any, node: any): string;
/**
* Validates and sanitizes tool input parameters for AI agent integration
* @param toolInput - Raw tool input object from AI agent
* @param operation - Operation type to validate parameters for
* @param node - n8n node instance for error reporting
* @returns any Validated and sanitized parameter object
* @throws NodeOperationError if required parameters are missing or invalid
* @example
* const params = node.validateAndSanitizeToolInput({
* savedSearchId: 'search-123',
* maxResults: '50',
* enableDetailScraping: 'true'
* }, 'extractPropertyData', this.getNode());
* // Returns: { savedSearchId: 'search-123', maxResults: 50, enableDetailScraping: true, ... }
*/
validateAndSanitizeToolInput(toolInput: any, operation: string, node: any): any;
}
export {};
//# sourceMappingURL=ImmoMetrica.node.d.ts.map