Extracción de contactos comerciales de Google Maps a Google Sheets con RapidAPI y Google Sheets

Avanzado

Este es unLead Generationflujo de automatización del dominio deautomatización que contiene 16 nodos.Utiliza principalmente nodos como Set, Code, Wait, Merge, HttpRequest. Extraer线索 de contacto de negocios de Google Maps a Google Sheets con RapidAPI y Google Sheets

Requisitos previos
  • Pueden requerirse credenciales de autenticación para la API de destino
  • Credenciales de API de Google Sheets
Vista previa del flujo de trabajo
Visualización de las conexiones entre nodos, con soporte para zoom y panorámica
Exportar flujo de trabajo
Copie la siguiente configuración JSON en n8n para importar y usar este flujo de trabajo
{
  "meta": {
    "instanceId": "ea94475e7076b2e72d3d36bb4202c7da062eea5a94e247647c6066ed6cd6f743",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "a4df4dee-6fda-4051-99d0-63824e197820",
      "name": "Iniciar Generación de Leads",
      "type": "n8n-nodes-base.manualTrigger",
      "notes": "🚀 Click here to start extracting Google Maps business leads. Ensure your search criteria are configured in the Google Sheets 'keyword_searches' tab first.",
      "position": [
        -360,
        -320
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "51c45a00-0d87-4ff0-836c-5354e332f802",
      "name": "Configurar Parámetros de Búsqueda",
      "type": "n8n-nodes-base.set",
      "notes": "⚙️ Prepares API search parameters from Google Sheets data. Modify the limit (max 100) and other parameters as needed for your use case.",
      "position": [
        1100,
        -300
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b7344336-0887-40f5-b853-276eb1dba1bf",
              "name": "search",
              "type": "string",
              "value": "={{ $json.query }}"
            },
            {
              "id": "1eb2f614-e6e7-4b0f-bc39-02ce929873e6",
              "name": "latitude",
              "type": "string",
              "value": "={{ $json.lat }}"
            },
            {
              "id": "0cf94d77-ef0d-4b06-bbb1-c3040dd60a24",
              "name": "longitude",
              "type": "string",
              "value": "={{ $json.lon }}"
            },
            {
              "id": "0fc8e386-f81a-44b4-a5c4-162c1d85fd46",
              "name": "region",
              "type": "string",
              "value": "={{ $json.country_iso_code }}"
            },
            {
              "id": "c368eb39-dfc9-4790-987f-b97fd0297245",
              "name": "language",
              "type": "string",
              "value": "EN"
            },
            {
              "id": "cdb5db50-6d2f-4b80-9e47-4ace539290ba",
              "name": "zoom",
              "type": "string",
              "value": "13"
            },
            {
              "id": "d47e2e85-bcc8-48d0-a8a2-8b1d04bd2a16",
              "name": "limit",
              "type": "string",
              "value": "100"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e6385c2d-4f61-495a-93ab-766541fa4579",
      "name": "Google Maps API Request",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "🗺️ Calls RapidAPI's Local Business Data service to extract comprehensive business information from Google Maps, including emails and social media contacts.",
      "onError": "continueRegularOutput",
      "position": [
        1460,
        -300
      ],
      "parameters": {
        "url": "https://local-business-data.p.rapidapi.com/search-in-area",
        "options": {},
        "jsonQuery": "={\"query\":\"{{ $json.search }}\"\n  ,\"lat\":\"{{ $json.latitude }}\"\n  ,\"lng\":\"{{ $json.longitude }}\"\n  ,\"zoom\":\"{{ $json.zoom }}\"\n  ,\"limit\":\"{{ $json.limit }}\"\n  ,\"language\":\"{{ $json.language }}\"\n  ,\"region\":\"{{ $json.region }}\"\n  ,\"extract_emails_and_contacts\":\"true\"} ",
        "sendQuery": true,
        "specifyQuery": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "1UBwOxs2haJZLITp",
          "name": "Google Maps API"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "5ddb7eca-5989-4572-9ef6-d7f74f566b33",
      "name": "Analizar Datos de Negocios",
      "type": "n8n-nodes-base.code",
      "notes": "🔄 Processes API response and extracts all business information including contact details, social media profiles, and location data into a structured format.",
      "position": [
        1800,
        -300
      ],
      "parameters": {
        "jsCode": "// Get the input data\nconst inputData = $input.first().json;\n\n// Try to find the data array and parameters\nlet data, parameters;\n\n// Check if inputData is the array directly\nif (Array.isArray(inputData)) {\n  // If inputData is an array, look for the object with data property\n  const dataObj = inputData.find(item => item.data);\n  if (dataObj) {\n    data = dataObj.data;\n    parameters = dataObj.parameters;\n  }\n} else if (inputData.data) {\n  // If inputData is an object with data property\n  data = inputData.data;\n  parameters = inputData.parameters;\n}\n\n// If we still don't have data, return an error\nif (!data || !Array.isArray(data)) {\n  return [{ json: { error: \"Could not find data array\", inputStructure: Object.keys(inputData) } }];\n}\n\n// Helper function to extract emails as comma-separated string\nfunction extractEmails(emailsArray) {\n  if (!emailsArray || !Array.isArray(emailsArray) || emailsArray.length === 0) {\n    return null;\n  }\n  return emailsArray.join(', ');\n}\n\n// Process each business\nconst outputData = data.map(business => ({\n  // Search parameters\n  query: parameters?.query || null,\n  language: parameters?.language || null,\n  lat: parameters?.lat || null,\n  lon: parameters?.lng || parameters?.lon || null,\n  zoom: parameters?.zoom || null,\n  limit: parameters?.limit || null,\n  \n  // Business data\n  business_id: business.business_id || null,\n  place_id: business.place_id || null,\n  phone_number: business.phone_number || null,\n  name: business.name || null,\n  full_address: business.full_address || null,\n  review_count: business.review_count || null,\n  rating: business.rating || null,\n  website: business.website || null,\n  verified: business.verified || null,\n  type: business.type || null,\n  reviews_link: business.reviews_link || null,\n  place_link: business.place_link || null,\n  about_summary: business.about?.summary || null,\n  address: business.address || null,\n  price_level: business.price_level || null,\n  district: business.district || null,\n  street_address: business.street_address || null,\n  city: business.city || null,\n  zipcode: business.zipcode || null,\n  state: business.state || null,\n  country: business.country || null,\n  \n  // Extract emails and social media contacts\n  email: extractEmails(business.emails_and_contacts?.emails),\n  linkedin: business.emails_and_contacts?.linkedin || null,\n  instagram: business.emails_and_contacts?.instagram || null,\n  \n  // Additional social media fields\n  facebook: business.emails_and_contacts?.facebook || null,\n  twitter: business.emails_and_contacts?.twitter || null,\n  youtube: business.emails_and_contacts?.youtube || null,\n  tiktok: business.emails_and_contacts?.tiktok || null,\n  pinterest: business.emails_and_contacts?.pinterest || null,\n  snapchat: business.emails_and_contacts?.snapchat || null,\n  github: business.emails_and_contacts?.github || null,\n  yelp: business.emails_and_contacts?.yelp || null,\n  \n  // Additional phone numbers from emails_and_contacts\n  additional_phones: business.emails_and_contacts?.phone_numbers?.length > 0 \n    ? business.emails_and_contacts.phone_numbers.join(', ') \n    : null\n}));\n\n// Return the processed data\nreturn outputData.map(item => ({ json: item }));"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "e88dbb0c-d2d6-4a3b-a4c1-0862a2755f4a",
      "name": "Cargar Criterios de Búsqueda",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "📋 Reads search criteria from the 'keyword_searches' sheet. Only processes rows marked with 'X' in the 'select' column for targeted lead generation.",
      "position": [
        80,
        -540
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "X",
              "lookupColumn": "select"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "keyword_searches"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "c7deb7f2-0df6-4929-9996-7e17bc6c493a",
      "name": "Procesar Cada Ubicación",
      "type": "n8n-nodes-base.splitInBatches",
      "notes": "🔄 Loops through each selected search criteria to avoid overwhelming the API and ensure reliable processing of multiple locations.",
      "position": [
        740,
        -320
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "932ee9e5-1924-4fa1-b7ed-b76817d8d1a0",
      "name": "Guardar Nuevos Leads",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "💾 Saves only new business leads to the 'stores_data' sheet. Duplicates are filtered out by the previous merge step.",
      "position": [
        2100,
        -300
      ],
      "parameters": {
        "columns": {
          "value": {
            "lat": "={{ $json.lat }}",
            "lon": "={{ $json.lon }}",
            "city": "={{ $json.city }}",
            "name": "={{ $json.name }}",
            "type": "={{ $json.type }}",
            "zoom": "={{ $json.zoom }}",
            "email": "={{ $json.email }}",
            "limit": "={{ $json.limit }}",
            "query": "={{ $json.query }}",
            "state": "={{ $json.state }}",
            "rating": "={{ $json.rating }}",
            "address": "={{ $json.full_address }}",
            "country": "={{ $json.country }}",
            "website": "={{ $json.website }}",
            "district": "={{ $json.district }}",
            "language": "={{ $json.language }}",
            "linkedin": "={{ $json.linkedin }}",
            "place_id": "={{ $json.place_id }}",
            "verified": "={{ $json.verified }}",
            "zip_code": "={{ $json.zipcode }}",
            "instagram": "={{ $json.instagram }}",
            "place_link": "={{ $json.place_link }}",
            "business_id": "={{ $json.business_id }}",
            "price_level": "={{ $json.price_level }}",
            "full_address": "={{ $json.full_address }}",
            "phone_number": "={{ $json.phone_number }}",
            "review_count": "={{ $json.review_count }}",
            "reviews_link": "={{ $json.reviews_link }}",
            "about_summary": "={{ $json.about_summary }}",
            "street_address": "={{ $json.street_address }}",
            "additional_phones": "={{ $json.additional_phones }}"
          },
          "schema": [
            {
              "id": "business_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "business_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "query",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "query",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone_number",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "phone_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "website",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "website",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "full_address",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "full_address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "rating",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "rating",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "linkedin",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "linkedin",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "instagram",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "instagram",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "stores_data"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "8a36189b-b07f-4af1-bc55-f0c835251927",
      "name": "Retraso por Límite de Tasa",
      "type": "n8n-nodes-base.wait",
      "notes": "⏱️ 10-second delay between API calls to respect rate limits and prevent being blocked. Adjust timing based on your API plan.",
      "position": [
        2100,
        -20
      ],
      "webhookId": "0bb83f04-8260-42b7-b108-632b91040a0e",
      "parameters": {
        "amount": 10
      },
      "typeVersion": 1.1
    },
    {
      "id": "53044569-b459-4825-8ce5-a82c2d80fb45",
      "name": "Cargar Leads Existentes",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "📊 Reads existing leads from the database to enable duplicate detection and prevent re-processing the same businesses.",
      "position": [
        60,
        -40
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "stores_data"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "YnLHwhwL7bsy8LoY",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "511e0baf-8741-431f-9c88-b2e2237b9ebb",
      "name": "Filtrar Búsquedas Nuevas",
      "type": "n8n-nodes-base.merge",
      "notes": "🔍 Smart duplicate prevention: Only processes search criteria that haven't been executed before, saving API calls and avoiding duplicate data.",
      "position": [
        440,
        -320
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "joinMode": "keepNonMatches",
        "outputDataFrom": "input1",
        "fieldsToMatchString": "query, lat"
      },
      "typeVersion": 3.2
    },
    {
      "id": "73efc100-3000-4936-a67b-30bdde13ba7d",
      "name": "Nota Adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -840,
        -520
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 620,
        "content": "# Google Maps Lead Generation Workflow\n\n## 🎯 **Overview**\nThis workflow extracts business leads from Google Maps with contact information and stores them in Google Sheets with intelligent duplicate prevention.\n\n## 📋 **Before Starting:**\n1. Set up RapidAPI account with Local Business Data API\n2. Create Google Sheet with 'keyword_searches' and 'stores_data' tabs\n3. Configure credentials in n8n\n4. Add your search queries to Google Sheets\n\n## 🚀 **How to Use:**\n- Mark search queries with 'X' in select column\n- Click 'Start Lead Generation' to begin\n- Workflow automatically prevents duplicates\n- Results saved to 'stores_data' sheet"
      },
      "typeVersion": 1
    },
    {
      "id": "45ee9c11-3bf7-44dc-8359-cedf43e7c100",
      "name": "Nota Adhesiva1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -280,
        -940
      ],
      "parameters": {
        "color": 5,
        "width": 350,
        "height": 400,
        "content": "## 📊 **INPUT DATA STRUCTURE**\n\n**keyword_searches** sheet columns:\n```\n| select | query | lat | lon | country_iso_code |\n|--------|-------|-----|-----|------------------|\n| X | Restaurants Madrid | 40.4168 | -3.7038 | ES |\n| X | Hair Salons NYC | 40.7589 | -73.9851 | US |\n```\n\n**Tips:**\n- Use 'X' to mark queries for processing\n- Be specific with search terms\n- Include accurate coordinates\n- Use 2-letter country codes"
      },
      "typeVersion": 1
    },
    {
      "id": "96e90ea0-93e3-4f95-a51a-1d37c17c4476",
      "name": "Nota Adhesiva2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        340,
        -740
      ],
      "parameters": {
        "color": 6,
        "width": 320,
        "height": 740,
        "content": "## 🔄 **DUPLICATE PREVENTION**\n\nThis workflow has **2-level duplicate prevention:**\n\n**Level 1: Search Level**\n- Compares new queries with existing data\n- Skips queries already processed\n- Saves API costs (50-80% reduction)\n\n**Level 2: Business Level**\n- Each business has unique business_id\n- Prevents duplicate business entries\n- Maintains data integrity"
      },
      "typeVersion": 1
    },
    {
      "id": "a31ffc0b-2bdd-419c-97b9-583af5b91e3a",
      "name": "Nota Adhesiva3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        -520
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 200,
        "content": "## ⚙️ **API CONFIGURATION**\n\n**Search Parameters:**\n- **Limit**: 100 results max per query\n- **Zoom**: 13 (city-wide) to 18 (local)\n- **Language**: EN, ES, FR, etc.\n- **Extract Contacts**: Always enabled\n\n**Rate Limiting:**\n- 10 seconds between requests\n- Prevents API blocking\n- Adjustable based on your plan"
      },
      "typeVersion": 1
    },
    {
      "id": "20ddcaad-738a-4bed-93ff-c7a044c3fc21",
      "name": "Nota Adhesiva4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1420,
        -720
      ],
      "parameters": {
        "color": 5,
        "width": 540,
        "height": 400,
        "content": "## 📱 **EXTRACTED DATA**\n\n**Business Information:**\n- Name, address, phone, website\n- Rating, reviews, verification status\n- Business type, price level\n\n**Contact Details:**\n- Email addresses\n- LinkedIn, Instagram profiles\n- Facebook, Twitter, YouTube\n- Additional phone numbers\n\n**Location Data:**\n- Full address, coordinates\n- City, state, country, zip code"
      },
      "typeVersion": 1
    },
    {
      "id": "20ccaa92-bf61-4f75-a81b-d6b1e0f550b5",
      "name": "Nota Adhesiva5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        -660
      ],
      "parameters": {
        "color": 3,
        "width": 350,
        "height": 340,
        "content": "## 📈 **EXECUTION FLOW**\n\n**1.** Load search criteria (marked with X)\n**2.** Load existing leads for comparison\n**3.** Filter out already processed searches\n**4.** Loop through each new search\n**5.** Configure API parameters\n**6.** Call Google Maps API\n**7.** Parse and structure data\n**8.** Save new leads to sheet\n**9.** Wait 10 seconds (rate limiting)\n**10.** Continue to next search\n\n✅ **Result**: Clean, organized lead database without duplicates!"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "932ee9e5-1924-4fa1-b7ed-b76817d8d1a0": {
      "main": [
        [
          {
            "node": "8a36189b-b07f-4af1-bc55-f0c835251927",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8a36189b-b07f-4af1-bc55-f0c835251927": {
      "main": [
        [
          {
            "node": "c7deb7f2-0df6-4929-9996-7e17bc6c493a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "511e0baf-8741-431f-9c88-b2e2237b9ebb": {
      "main": [
        [
          {
            "node": "c7deb7f2-0df6-4929-9996-7e17bc6c493a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "53044569-b459-4825-8ce5-a82c2d80fb45": {
      "main": [
        [
          {
            "node": "511e0baf-8741-431f-9c88-b2e2237b9ebb",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "5ddb7eca-5989-4572-9ef6-d7f74f566b33": {
      "main": [
        [
          {
            "node": "932ee9e5-1924-4fa1-b7ed-b76817d8d1a0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e88dbb0c-d2d6-4a3b-a4c1-0862a2755f4a": {
      "main": [
        [
          {
            "node": "511e0baf-8741-431f-9c88-b2e2237b9ebb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c7deb7f2-0df6-4929-9996-7e17bc6c493a": {
      "main": [
        [],
        [
          {
            "node": "51c45a00-0d87-4ff0-836c-5354e332f802",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a4df4dee-6fda-4051-99d0-63824e197820": {
      "main": [
        [
          {
            "node": "e88dbb0c-d2d6-4a3b-a4c1-0862a2755f4a",
            "type": "main",
            "index": 0
          },
          {
            "node": "53044569-b459-4825-8ce5-a82c2d80fb45",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e6385c2d-4f61-495a-93ab-766541fa4579": {
      "main": [
        [
          {
            "node": "5ddb7eca-5989-4572-9ef6-d7f74f566b33",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "51c45a00-0d87-4ff0-836c-5354e332f802": {
      "main": [
        [
          {
            "node": "e6385c2d-4f61-495a-93ab-766541fa4579",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Preguntas frecuentes

¿Cómo usar este flujo de trabajo?

Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.

¿En qué escenarios es adecuado este flujo de trabajo?

Avanzado - Generación de leads

¿Es de pago?

Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.

Información del flujo de trabajo
Nivel de dificultad
Avanzado
Número de nodos16
Categoría1
Tipos de nodos9
Descripción de la dificultad

Adecuado para usuarios avanzados, flujos de trabajo complejos con 16+ nodos

Autor
Javier Hita

Javier Hita

@javierhita

Building Automation tools as a Data Analyst for over 6 years, N8N is a great tool to leverage that background.

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34