8
n8n 中文网amn8n.com

使用RapidAPI和Google表格从Google地图提取商业联系线索

高级

这是一个Lead Generation领域的自动化工作流,包含 16 个节点。主要使用 Set, Code, Wait, Merge, HttpRequest 等节点。 使用RapidAPI和Google表格从Google地图提取商业联系线索

前置要求
  • 可能需要目标 API 的认证凭证
  • Google Sheets API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "ea94475e7076b2e72d3d36bb4202c7da062eea5a94e247647c6066ed6cd6f743",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "a4df4dee-6fda-4051-99d0-63824e197820",
      "name": "开始潜在客户生成",
      "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": "配置搜索参数",
      "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 请求",
      "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": "解析业务数据",
      "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": "加载搜索条件",
      "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": "处理每个位置",
      "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": "保存新潜在客户",
      "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": "速率限制延迟",
      "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": "加载现有潜在客户",
      "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": "过滤新搜索",
      "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": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -840,
        -520
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 620,
        "content": "# Google Maps 潜在客户生成工作流"
      },
      "typeVersion": 1
    },
    {
      "id": "45ee9c11-3bf7-44dc-8359-cedf43e7c100",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -280,
        -940
      ],
      "parameters": {
        "color": 5,
        "width": 350,
        "height": 400,
        "content": "## 📊 **输入数据结构**"
      },
      "typeVersion": 1
    },
    {
      "id": "96e90ea0-93e3-4f95-a51a-1d37c17c4476",
      "name": "便签 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        340,
        -740
      ],
      "parameters": {
        "color": 6,
        "width": 320,
        "height": 740,
        "content": "## 🔄 **重复预防**"
      },
      "typeVersion": 1
    },
    {
      "id": "a31ffc0b-2bdd-419c-97b9-583af5b91e3a",
      "name": "便签 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        -520
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 200,
        "content": "## ⚙️ **API 配置**"
      },
      "typeVersion": 1
    },
    {
      "id": "20ddcaad-738a-4bed-93ff-c7a044c3fc21",
      "name": "便签 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1420,
        -720
      ],
      "parameters": {
        "color": 5,
        "width": 540,
        "height": 400,
        "content": "## 📱 **提取的数据**"
      },
      "typeVersion": 1
    },
    {
      "id": "20ccaa92-bf61-4f75-a81b-d6b1e0f550b5",
      "name": "便签 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        -660
      ],
      "parameters": {
        "color": 3,
        "width": 350,
        "height": 340,
        "content": "## 📈 **执行流程**"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "Save New Leads": {
      "main": [
        [
          {
            "node": "Rate Limit Delay",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rate Limit Delay": {
      "main": [
        [
          {
            "node": "Process Each Location",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter New Searches": {
      "main": [
        [
          {
            "node": "Process Each Location",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Existing Leads": {
      "main": [
        [
          {
            "node": "Filter New Searches",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Parse Business Data": {
      "main": [
        [
          {
            "node": "Save New Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Search Criteria": {
      "main": [
        [
          {
            "node": "Filter New Searches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Each Location": {
      "main": [
        [],
        [
          {
            "node": "Configure Search Parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Lead Generation": {
      "main": [
        [
          {
            "node": "Load Search Criteria",
            "type": "main",
            "index": 0
          },
          {
            "node": "Load Existing Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Maps API Request": {
      "main": [
        [
          {
            "node": "Parse Business Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure Search Parameters": {
      "main": [
        [
          {
            "node": "Google Maps API Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 潜在客户开发

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量16
分类1
节点类型9
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
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.

外部链接
在 n8n.io 查看

分享此工作流