{
  "id": "tUgWnB-WzSZhmHRXKQgvp",
  "meta": {
    "site": "https://github.com/zengfr/n8n-workflow-all-templates",
    "name": "Generate Google Maps lead lists with SerpApi, Google Gemini and Sheets",
    "wechat": "youandme10086",
    "id": 13678,
    "update_time": "2026-03-12"
  },
  "name": "V2-GoogleMaps-Envio_A_n8n_",
  "tags": [],
  "nodes": [
    {
      "id": "1c57131a-7ff0-4851-ab6c-7b41eb4d3e17",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1136,
        1424
      ],
      "parameters": {
        "options": {
          "temperature": 0.2
        }
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3fce3e64-036d-4dd1-b72d-0a31eab9a703",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        544
      ],
      "parameters": {
        "width": 1792,
        "height": 416,
        "content": "# Market intelligence AI agent for lead discovery and sales strategy\nThis workflow automates the process of identifying local businesses with a weak digital presence to offer them specialized marketing services. By combining real-time data from Google Maps with the analytical power of Gemini AI, it transforms raw search results into a structured sales pipeline.\n\n## How it works\n1.  **Data Extraction:** The process starts with a form where you enter search keywords (e.g., \"restaurants in Lima\"). The workflow then queries the SerpApi to fetch the top local results from Google Maps.\n2. **Filtering & Prioritization:** It filters results by region and sorts them by rating. It specifically targets the top 5 businesses with the lowest ratings or missing information, as these represent the highest conversion opportunities.\n3. **AI Analysis:** The Gemini AI agent acts as a senior consultant. It analyzes each lead's weaknesses, assigns a priority score, and generates a personalized sales pitch and email copy.\n4. **Record Keeping:** Finally, all enriched data, including the AI-generated strategy, is formatted and saved into a Google Sheet for immediate sales action.\n\n## Setup steps\n- **SerpApi:** Register at serpapi.com to get your API key and add it to the HTTP Request node credentials.\n- **Google Gemini:** Set up your Google AI Studio credentials for the AI Agent node.\n- **Google Sheets:** Create a spreadsheet with columns for Company Name, Rating, Address, AI Score, and Sales Strategy. Link it in the final node."
      },
      "typeVersion": 1
    },
    {
      "id": "c633b41a-b91d-4ef9-823b-72a056077b7e",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -128,
        560
      ],
      "parameters": {
        "color": 3,
        "width": 448,
        "height": 112,
        "content": "##  JESUS ANTONIO PACAHUALA ARROYO"
      },
      "typeVersion": 1
    },
    {
      "id": "04df2820-f5fa-464d-b9d5-23e871299fca",
      "name": "Lead Search Trigger",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -496,
        1248
      ],
      "parameters": {
        "options": {},
        "formTitle": "B\u00fascador de Negocios",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Qu\u00e9 tipo de negocios y en qu\u00e9 zona buscas?",
              "placeholder": "Ejemplo: restaurantes en san isidro lima",
              "requiredField": true
            }
          ]
        },
        "formDescription": "Este formulario permite buscar negocios en los distintos lugares del pa\u00eds."
      },
      "executeOnce": false,
      "notesInFlow": false,
      "typeVersion": 2.5,
      "alwaysOutputData": false
    },
    {
      "id": "1222c612-92c6-4360-b54f-e1b2c0e417f4",
      "name": "Fetch Google Maps Data (SerpApi)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -272,
        1248
      ],
      "parameters": {
        "url": "=https://serpapi.com/search.json",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "engine",
              "value": "google_maps"
            },
            {
              "name": "q",
              "value": "={{ $json['Qu\u00e9 tipo de negocios y en qu\u00e9 zona buscas?'] }}"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "0f4f8249-40a7-4154-abbc-b15f985a5813",
      "name": "Extract Business List",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -48,
        1248
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "local_results"
      },
      "typeVersion": 1
    },
    {
      "id": "a3fca73c-a7f1-4c72-80cf-9d8a453602bf",
      "name": "Filter by Region (Peru)",
      "type": "n8n-nodes-base.filter",
      "position": [
        256,
        1248
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "35b3a229-1ba8-4903-a20b-a25ceeaf091a",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.address }}",
              "rightValue": "Peru"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "a7458e69-ce03-4316-839e-e8981f5cf7f1",
      "name": "Prioritize Low-Rating Leads",
      "type": "n8n-nodes-base.sort",
      "position": [
        448,
        1248
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "fieldName": "rating"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "26ed24ca-add9-4f97-911d-3537dc78b10a",
      "name": "Select Top 5 Critical Cases",
      "type": "n8n-nodes-base.limit",
      "position": [
        640,
        1248
      ],
      "parameters": {
        "maxItems": 5
      },
      "typeVersion": 1
    },
    {
      "id": "5cf3e969-1c54-4f3e-8816-106e89344515",
      "name": "Batch Leads for AI Processing",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        896,
        1248
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "lista_de_negocios"
      },
      "typeVersion": 1
    },
    {
      "id": "86dd9b0c-6b23-4526-a090-83eec2ebdc48",
      "name": "Market Intelligence Strategy Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1136,
        1248
      ],
      "parameters": {
        "text": "=SISTEMA:\nEres un analista experto en recuperaci\u00f3n de negocios y reputaci\u00f3n online. Tu \u00fanica fuente de verdad es la variable \"DATOS_REALES\". Est\u00e1 prohibido inventar nombres de negocios o usar datos que no est\u00e9n en esa lista.\n\nDATOS_REALES (Procesar estos negocios):\n{{ JSON.stringify($json.lista_de_negocios) }}\n\nTU TAREA:\nPara cada uno de los negocios en DATOS_REALES, analiza su situaci\u00f3n actual (especialmente su bajo rating o falta de presencia web) y genera:\n\nscore: Calificaci\u00f3n del 1 al 10 seg\u00fan la urgencia de mejora (10 = situaci\u00f3n cr\u00edtica, necesita ayuda inmediata).\n\npuntos_debiles: 2 fallos espec\u00edficos que est\u00e1n da\u00f1ando su reputaci\u00f3n o ventas.\n\ngancho: Una frase rompehielo emp\u00e1tica que mencione un problema real detectado sin sonar ofensivo.\n\nemail_template: Un correo breve de venta ofreciendo soluciones espec\u00edficas (ej: mejorar rese\u00f1as, dise\u00f1o web, o SEO local) para revertir su situaci\u00f3n actual.\n\nREGLAS e Instrucciones de formato (CR\u00cdTICO):\n\nSi un dato (como tel\u00e9fono o web) no viene en la lista, pon \"No disponible\".\n\nMant\u00e9n el mismo orden de la lista original.\n\nResponde SOLO con el Array de JSON v\u00e1lido. Sin texto antes ni despu\u00e9s.\n\nNo incluyas explicaciones, ni etiquetas de c\u00f3digo Markdown como ```json.\n\nESTRUCTURA EXACTA:\n[\n{\n\"Nombre\": \"...\", \n\"Tipo\": \"...\", \n\"Tel\u00e9fono\": \"...\", \n\"Web\": \"...\", \n\"Direcci\u00f3n\": \"...\", \n\"Latitud\": 0, \n\"Longitud\": 0, \n\"Rating\": 8, \n\"Link_Google\": \"...\",\n\"Puntuaci\u00f3n_Calidad\": [Tu nota de urgencia 1-10], \n\"Puntos_D\u00e9biles\": \"[Tu an\u00e1lisis]\", \n\"Gancho_de_Venta\": \"[Tu frase]\",\n\"Plantilla_de_Correo\": \"[Tu correo]\"\n}\n]\n\n",
        "options": {},
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 3.1,
      "waitBetweenTries": 2000
    },
    {
      "id": "a0784339-5746-4969-ac14-bea2ef9f7c35",
      "name": "Clean AI Raw Response",
      "type": "n8n-nodes-base.set",
      "position": [
        1440,
        1248
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "5049b179-7480-411f-89dc-6be6c4ceb8fe",
              "name": "datos_limpios",
              "type": "string",
              "value": "={{ $json.output }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8317f5fb-6797-449a-9538-6da467bc6c3c",
      "name": "Parse AI Output to JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        1648,
        1248
      ],
      "parameters": {
        "jsCode": "// Tomamos el texto que envi\u00f3 Gemini y lo convertimos en una lista real\nconst rawData = $input.item.json.datos_limpios;\nconst cleanData = JSON.parse(rawData);\n\n// Devolvemos la lista para que n8n la reconozca como items individuales\nreturn cleanData;"
      },
      "typeVersion": 2
    },
    {
      "id": "4949dd9e-3dd6-4cf1-86e9-8cbab0913a21",
      "name": "Final Data Formatting",
      "type": "n8n-nodes-base.set",
      "position": [
        1968,
        1248
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "081ef9a2-2a41-459b-ba81-5cb142f7e3ed",
              "name": "Estado",
              "type": "string",
              "value": "Por contactar"
            },
            {
              "id": "90a37b18-fc16-45ae-b4d2-c107b870d9b1",
              "name": "Fecha_Procesamiento",
              "type": "string",
              "value": "={{ $now.format('yyyy-MM-dd HH:mm') }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "636e46af-3463-44a1-9cbb-e1f4203ae2c4",
      "name": "Save Strategies to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2240,
        1248
      ],
      "parameters": {
        "columns": {
          "value": {
            "Web": "={{ $json.Web }}",
            "Tipo": "={{ $json.Tipo }}",
            "Estado": "={{ $json.Estado }}",
            "Nombre": "={{ $json.Nombre }}",
            "Rating": "={{ $json.Rating }}",
            "Latitud": "={{ $json.Latitud }}",
            "Longitud": "={{ $json.Longitud }}",
            "Tel\u00e9fono": "={{ $json[\"Tel\u00e9fono\"].replace(/[^0-9]/g, '') }}",
            "Direcci\u00f3n": "={{ $json['Direcci\u00f3n'] }}",
            "Link_Google": "={{ $json.Link_Google }}",
            "Gancho_de_Venta": "={{ $json.Gancho_de_Venta }}",
            "Puntos_D\u00e9biles": "={{ $json['Puntos_D\u00e9biles'] }}",
            "Fecha_Procesamiento": "={{ $json.Fecha_Procesamiento }}",
            "Plantilla_de_Correo": "={{ $json.Plantilla_de_Correo }}",
            "Puntuaci\u00f3n-Calidad": "={{ $json['Puntuaci\u00f3n_Calidad'] }}"
          },
          "schema": [
            {
              "id": "Nombre",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Nombre",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tipo",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Tipo",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tel\u00e9fono",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Tel\u00e9fono",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Web",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Web",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Direcci\u00f3n",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Direcci\u00f3n",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Latitud",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Latitud",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Longitud",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Longitud",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Rating",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Rating",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Link_Google",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Link_Google",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Puntuaci\u00f3n-Calidad",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Puntuaci\u00f3n-Calidad",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Puntos_D\u00e9biles",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Puntos_D\u00e9biles",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Gancho_de_Venta",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Gancho_de_Venta",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Plantilla_de_Correo",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Plantilla_de_Correo",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Estado",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Estado",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Fecha_Procesamiento",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Fecha_Procesamiento",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "="
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "="
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "16771ec8-0785-4c85-af2f-28c0894fdb82",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        1056
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 512,
        "content": "## Data Acquisition\n\nCaptures search keywords from a form and retrieves raw business data from Google Maps via SerpApi, converting the results into individual items for processing."
      },
      "typeVersion": 1
    },
    {
      "id": "72a72350-cf14-4991-b847-296c3976228d",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        1056
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 512,
        "content": "## Lead Filtering & Selection\n\nFilters leads to ensure geographic relevance and sorts them by rating to identify the businesses with the highest need for improvement."
      },
      "typeVersion": 1
    },
    {
      "id": "801e2569-5250-4034-92ea-a5febb876b84",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1040,
        1056
      ],
      "parameters": {
        "color": 7,
        "width": 784,
        "height": 512,
        "content": "## AI Intelligence & Strategy\n\nUses Gemini AI to analyze business gaps and generate a custom sales strategy, including a priority score and personalized outreach copy."
      },
      "typeVersion": 1
    },
    {
      "id": "77d0511d-b372-41b0-adff-6932bc24a8a9",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1904,
        1056
      ],
      "parameters": {
        "color": 7,
        "width": 784,
        "height": 512,
        "content": "## Output & Storage\n\nStandardizes the enriched lead data and records it into a Google Spreadsheet for the sales team to follow up."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "2c08962e-3d99-41bc-8443-5b58781a85a8",
  "connections": {
    "Lead Search Trigger": {
      "main": [
        [
          {
            "node": "Fetch Google Maps Data (SerpApi)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean AI Raw Response": {
      "main": [
        [
          {
            "node": "Parse AI Output to JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Business List": {
      "main": [
        [
          {
            "node": "Filter by Region (Peru)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Final Data Formatting": {
      "main": [
        [
          {
            "node": "Save Strategies to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter by Region (Peru)": {
      "main": [
        [
          {
            "node": "Prioritize Low-Rating Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Output to JSON": {
      "main": [
        [
          {
            "node": "Final Data Formatting",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Market Intelligence Strategy Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Prioritize Low-Rating Leads": {
      "main": [
        [
          {
            "node": "Select Top 5 Critical Cases",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Top 5 Critical Cases": {
      "main": [
        [
          {
            "node": "Batch Leads for AI Processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Batch Leads for AI Processing": {
      "main": [
        [
          {
            "node": "Market Intelligence Strategy Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Google Maps Data (SerpApi)": {
      "main": [
        [
          {
            "node": "Extract Business List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Market Intelligence Strategy Agent": {
      "main": [
        [
          {
            "node": "Clean AI Raw Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}