AutomationFlowsGeneral › AI Land Expansion Analysis with Google Sheets

AI Land Expansion Analysis with Google Sheets

Original n8n title: Sia — Portal De Expansão De Terrenos (principal)

Sia — Portal de Expansão de Terrenos (Principal). Uses chainLlm, lmChatGroq, googleSheets. Webhook trigger; 12 nodes.

Webhook trigger★★★★☆ complexityAI-powered12 nodesChain LlmGroq ChatGoogle Sheets
General Trigger: Webhook Nodes: 12 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Chainllm → Google Sheets recipe pattern — see all workflows that pair these two integrations.

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": "Sia \u2014 Portal de Expans\u00e3o de Terrenos (Principal)",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "sia-terrenos",
        "responseMode": "responseNode",
        "options": {
          "allowedOrigins": "*"
        }
      },
      "id": "a1b2c3d4-0001-4000-8000-000000000001",
      "name": "Webhook \u2014 Receber Proposta",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "field-001",
              "name": "nome_corretor",
              "value": "={{ $json.body.nome_corretor }}",
              "type": "string"
            },
            {
              "id": "field-002",
              "name": "email",
              "value": "={{ $json.body.email }}",
              "type": "string"
            },
            {
              "id": "field-003",
              "name": "descricao",
              "value": "={{ $json.body.descricao }}",
              "type": "string"
            },
            {
              "id": "field-004",
              "name": "timestamp",
              "value": "={{ $now.toISO() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "a1b2c3d4-0002-4000-8000-000000000002",
      "name": "Preparar Dados",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "SEU_SUB_WORKFLOW_ID",
          "mode": "id"
        },
        "options": {}
      },
      "id": "a1b2c3d4-0003-4000-8000-000000000003",
      "name": "Identificar Corretor (Sub-Workflow)",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.1,
      "position": [
        680,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond-001",
              "leftValue": "={{ $json.found }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "a1b2c3d4-0004-4000-8000-000000000004",
      "name": "Corretor Cadastrado?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "err-001",
              "name": "success",
              "value": false,
              "type": "boolean"
            },
            {
              "id": "err-002",
              "name": "status",
              "value": "error",
              "type": "string"
            },
            {
              "id": "err-003",
              "name": "mensagem",
              "value": "={{ 'Corretor n\u00e3o encontrado em nossa base. Por favor, entre em contato com nossa equipe para realizar seu cadastro antes de enviar propostas.' }}",
              "type": "string"
            },
            {
              "id": "err-004",
              "name": "codigo",
              "value": "CORRETOR_NAO_CADASTRADO",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "a1b2c3d4-0005-4000-8000-000000000005",
      "name": "Erro \u2014 Corretor N\u00e3o Cadastrado",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        900,
        520
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}",
        "options": {
          "responseCode": 403
        }
      },
      "id": "a1b2c3d4-0006-4000-8000-000000000006",
      "name": "Resposta \u2014 N\u00e3o Cadastrado",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1120,
        520
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Voc\u00ea \u00e9 a Sia, a Intelig\u00eancia Artificial da Seazone especializada em an\u00e1lise imobili\u00e1ria.\n\nAnalise a descri\u00e7\u00e3o do terreno abaixo e extraia as informa\u00e7\u00f5es solicitadas.\n\n\u26a0\ufe0f RETORNE APENAS um JSON v\u00e1lido, sem texto adicional, sem blocos markdown, sem explica\u00e7\u00f5es:\n\n{\n  \"cidade\": \"nome exato da cidade mencionada\",\n  \"area_m2\": NUMERO_SEM_ASPAS (ex: 500),\n  \"valor\": NUMERO_SEM_ASPAS_EM_REAIS (ex: 2000000),\n  \"valor_por_m2\": NUMERO_CALCULADO (valor dividido por area_m2),\n  \"classificacao\": \"Interesse Imediato\" OU \"Manter em Base\"\n}\n\nRegras de classifica\u00e7\u00e3o:\n- \"Interesse Imediato\": SOMENTE se a cidade for exatamente uma destas: Florian\u00f3polis, Balne\u00e1rio Cambori\u00fa, Itapema, Bombinhas, Porto Belo, Tijucas, Governador Celso Ramos\n- \"Manter em Base\": qualquer outra cidade\n\nSe um campo n\u00e3o for mencionado, use null.\nSe o valor for mencionado em \"milh\u00f5es\" (ex: 2 milh\u00f5es), converta para n\u00famero inteiro (ex: 2000000).\n\nDescri\u00e7\u00e3o do terreno:\n{{ $('Preparar Dados').item.json.descricao }}",
        "options": {}
      },
      "id": "a1b2c3d4-0007-4000-8000-000000000007",
      "name": "Sia \u2014 Analisar Terreno",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.5,
      "position": [
        1120,
        300
      ]
    },
    {
      "parameters": {
        "model": "llama-3.3-70b-versatile",
        "options": {
          "temperature": 0.1,
          "maxTokens": 512
        }
      },
      "id": "a1b2c3d4-0008-4000-8000-000000000008",
      "name": "Groq \u2014 Sia Brain",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "typeVersion": 1,
      "position": [
        1120,
        120
      ],
      "credentials": {
        "groqApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// \u2500\u2500 Recuperar dados das etapas anteriores \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst dadosForm = $('Preparar Dados').first().json;\nconst aiRaw     = $input.first().json.text || $input.first().json.output || '';\n\n// \u2500\u2500 Parsear resposta JSON da IA \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet terreno = { cidade: null, area_m2: null, valor: null, valor_por_m2: null, classificacao: null };\n\ntry {\n  const match = aiRaw.match(/\\{[\\s\\S]*\\}/);\n  if (match) terreno = JSON.parse(match[0]);\n} catch (e) {\n  terreno.classificacao = 'Manter em Base';\n}\n\n// \u2500\u2500 Normalizar classifica\u00e7\u00e3o: detectar cidades priorit\u00e1rias \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst cidadesAlta = [\n  'florianopolis', 'florian\u00f3polis',\n  'balneario camboriu', 'balne\u00e1rio cambori\u00fa',\n  'itapema', 'bombinhas',\n  'porto belo', 'governador celso ramos',\n  'tijucas'\n];\n\nfunction normalizar(str) {\n  return (str || '')\n    .toLowerCase()\n    .normalize('NFD')\n    .replace(/[\\u0300-\\u036f]/g, '')\n    .trim();\n}\n\nconst cidadeNorm = normalizar(terreno.cidade || '');\nconst isAlta     = cidadesAlta.some(c => cidadeNorm.includes(normalizar(c)));\n\nconst classificacao = isAlta ? 'Interesse Imediato' : 'Manter em Base';\nconst prioridade    = isAlta ? 'Alta' : 'Baixa';\n\n// \u2500\u2500 Calcular valor/m\u00b2 se n\u00e3o retornado pela IA \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nif (terreno.area_m2 && terreno.valor && !terreno.valor_por_m2) {\n  terreno.valor_por_m2 = Math.round(terreno.valor / terreno.area_m2);\n}\n\n// \u2500\u2500 Montar mensagem personalizada da Sia \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet mensagem, status;\n\nif (isAlta) {\n  mensagem = `Excelente! J\u00e1 encaminhei sua proposta para nosso time de expans\u00e3o. ` +\n             `Seu terreno${terreno.cidade ? ' em ' + terreno.cidade : ''}` +\n             `${terreno.area_m2 ? ' com ' + terreno.area_m2 + 'm\u00b2' : ''} ` +\n             `demonstra grande potencial para nossos projetos!`;\n  status = 'success';\n} else {\n  mensagem = `No momento n\u00e3o estamos operando nesta regi\u00e3o, mas guardaremos seu contato.` +\n             `${terreno.cidade ? ' Entraremos em contato quando expandirmos para ' + terreno.cidade + '.' : ''}`;\n  status = 'info';\n}\n\n// \u2500\u2500 Construir objeto de retorno completo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst responseObj = {\n  success:        true,\n  status:         status,\n  prioridade:     prioridade,\n  classificacao:  classificacao,\n  mensagem:       mensagem,\n  dados: {\n    cidade:      terreno.cidade,\n    area_m2:     terreno.area_m2,\n    valor:       terreno.valor,\n    valor_por_m2: terreno.valor_por_m2\n  },\n  corretor: dadosForm.nome_corretor\n};\n\nreturn [{\n  json: {\n    // Para Sheets \u2014 aba Terrenos\n    nome_corretor:  dadosForm.nome_corretor,\n    email:          dadosForm.email,\n    descricao:      dadosForm.descricao,\n    cidade:         terreno.cidade,\n    area_m2:        terreno.area_m2,\n    valor:          terreno.valor,\n    valor_por_m2:   terreno.valor_por_m2,\n    classificacao:  classificacao,\n    prioridade:     prioridade,\n    timestamp:      dadosForm.timestamp,\n    ia_raw:         aiRaw,\n\n    // Para resposta ao frontend\n    response:     responseObj,\n    responseJson: JSON.stringify(responseObj)\n  }\n}];\n"
      },
      "id": "a1b2c3d4-0009-4000-8000-000000000009",
      "name": "Processar Resposta da IA",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1340,
        300
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "SEU_SPREADSHEET_ID_AQUI",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Terrenos",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {}
        },
        "options": {}
      },
      "id": "a1b2c3d4-0010-4000-8000-000000000010",
      "name": "Salvar Terreno no Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1560,
        300
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "SEU_SPREADSHEET_ID_AQUI",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Logs",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {}
        },
        "options": {}
      },
      "id": "a1b2c3d4-0011-4000-8000-000000000011",
      "name": "Salvar Log no Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1780,
        300
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $('Processar Resposta da IA').first().json.responseJson }}",
        "options": {
          "responseCode": 200
        }
      },
      "id": "a1b2c3d4-0012-4000-8000-000000000012",
      "name": "Retornar Veredito Sia",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        2000,
        300
      ]
    }
  ],
  "connections": {
    "Webhook \u2014 Receber Proposta": {
      "main": [
        [
          {
            "node": "Preparar Dados",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preparar Dados": {
      "main": [
        [
          {
            "node": "Identificar Corretor (Sub-Workflow)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Identificar Corretor (Sub-Workflow)": {
      "main": [
        [
          {
            "node": "Corretor Cadastrado?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Corretor Cadastrado?": {
      "main": [
        [
          {
            "node": "Sia \u2014 Analisar Terreno",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Erro \u2014 Corretor N\u00e3o Cadastrado",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Erro \u2014 Corretor N\u00e3o Cadastrado": {
      "main": [
        [
          {
            "node": "Resposta \u2014 N\u00e3o Cadastrado",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Groq \u2014 Sia Brain": {
      "ai_languageModel": [
        [
          {
            "node": "Sia \u2014 Analisar Terreno",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Sia \u2014 Analisar Terreno": {
      "main": [
        [
          {
            "node": "Processar Resposta da IA",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Processar Resposta da IA": {
      "main": [
        [
          {
            "node": "Salvar Terreno no Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Salvar Terreno no Sheets": {
      "main": [
        [
          {
            "node": "Salvar Log no Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Salvar Log no Sheets": {
      "main": [
        [
          {
            "node": "Retornar Veredito Sia",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": ""
  },
  "id": "sia-workflow-principal-001",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "versionId": "v1.0.0-seazone",
  "tags": [
    {
      "id": "tag-seazone-001",
      "name": "Seazone"
    },
    {
      "id": "tag-sia-001",
      "name": "Sia"
    },
    {
      "id": "tag-terrenos-001",
      "name": "Terrenos"
    }
  ]
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

How this works

This workflow streamlines the expansion of land holdings by automating the analysis of real estate proposals through an AI-powered portal, saving estate managers and brokers hours of manual review. It receives proposals via webhook, verifies the submitting broker against a Google Sheets database, and employs chainLLM and Groq's lmChat to evaluate terrain suitability, generating actionable insights on expansion potential. The key step involves the AI brain assessing factors like location and zoning, delivering a clear recommendation to guide decisions.

Use this workflow for high-volume land acquisition processes where quick, data-driven terrain evaluations are essential, such as in commercial real estate development. Avoid it for one-off assessments lacking broker verification or when detailed legal reviews are needed beyond AI capabilities. Common variations include integrating additional data sources like mapping APIs for enhanced geographic analysis or adapting it for non-real-estate asset expansions.

About this workflow

Sia — Portal de Expansão de Terrenos (Principal). Uses chainLlm, lmChatGroq, googleSheets. Webhook trigger; 12 nodes.

Source: https://github.com/BryanSnows/seazone-ia/blob/b05ba55f786c1d31b69aba25abfe99736c284852/n8n/workflow_principal.json — original creator credit. Request a take-down →

More General workflows → · Browse all categories →

Related workflows

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

General

RoboNuggets - Faceless POV AI Machine (R24). Uses scheduleTrigger, googleSheets, chainLlm, lmChatOpenAi. Scheduled trigger; 31 nodes.

Google Sheets, Chain Llm, OpenAI Chat +5
General

Video Automation (images only). Uses chainLlm, lmChatOpenAi, outputParserStructured, splitOut. Scheduled trigger; 28 nodes.

Chain Llm, OpenAI Chat, Output Parser Structured +4
General

This n8n template demonstrates how to automate personalized cold email follow-ups using AI personalization and database tracking. Perfect for sales teams, recruiters, and agencies managing high-volume

Noco Db, Groq Chat, Email Send +1
General

TWBS. Uses httpRequest, chainLlm, lmChatAzureOpenAi. Webhook trigger; 14 nodes.

HTTP Request, Chain Llm, Lm Chat Azure Open Ai
General

This n8n template demonstrates how to automate personalized cold email outreach using AI and a lead database. It’s designed to contact unengaged leads, personalize messages at scale, and schedule foll

Noco Db, Chain Llm, Groq Chat +1