AutomationFlowsAI & RAG › Qualify Leads & Find Emails with OpenAI & Sheets

Qualify Leads & Find Emails with OpenAI & Sheets

Original n8n title: Qualify Lead Lists and Find Professional Emails with Openai and Google Sheets

ByDevon Toh @devontoh on n8n.io

Drop a lead list into Google Drive. This workflow reads it, finds professional emails using OpenAI, and splits leads into Qualified and Unqualified sheets fully automated. Watch For New Leads Google Drive trigger monitors a folder. When a new spreadsheet lands, the workflow…

Event trigger★★★★☆ complexityAI-powered15 nodesGoogle Drive TriggerGoogle SheetsOpenAI
AI & RAG Trigger: Event Nodes: 15 Complexity: ★★★★☆ AI nodes: yes Added:
Qualify Leads & Find Emails with OpenAI & Sheets — n8n workflow card showing Google Drive Trigger, Google Sheets, OpenAI integration

This workflow corresponds to n8n.io template #14198 — we link there as the canonical source.

This workflow follows the Google Drive Trigger → 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
{
  "id": "K21Bckb0tNhDFwdd",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Qualify Lead Lists And Find Professional Emails With OpenAI and Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "b8e4e5ba-00e2-4a27-94ca-45677f7f0ee2",
      "name": "Watch For New Leads",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        -608,
        1872
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "id",
          "value": "your-google-drive-folder-id"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e0be8b6d-02bd-4d35-aa61-f9c0271b4881",
      "name": "Read Lead Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -384,
        1872
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "dacbacba-8ff0-439c-a83b-0e0f3492ad07",
      "name": "Normalize Lead Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -160,
        1872
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "db94ea23-daec-40d3-af78-3f1762ac96fd",
              "name": "fullName",
              "type": "string",
              "value": "={{ ($json['first name'] ?? '') + ' ' + ($json['last name'] ?? '') }}"
            },
            {
              "id": "dfa2a05c-377b-4e2b-99d0-e5af272c5144",
              "name": "companyName",
              "type": "string",
              "value": "={{ $json.company }}"
            },
            {
              "id": "a724d6f2-48e7-450a-a1c2-b57995abe5f4",
              "name": "companyWebsite",
              "type": "string",
              "value": "={{ $json['corporate website'] }}"
            },
            {
              "id": "c99c4227-c7ab-49ef-88b1-f727155a0ecc",
              "name": "linkedinIndustry",
              "type": "string",
              "value": "={{ $json['linkedin industry'] }}"
            },
            {
              "id": "4bfb3873-543a-40a6-9741-c9f13b17bf5b",
              "name": "linkedinUrl",
              "type": "string",
              "value": "={{ $json['linkedin url'] }}"
            },
            {
              "id": "e2845dae-a257-48bf-9a7a-13aa748cc659",
              "name": "jobTitle",
              "type": "string",
              "value": "={{ $json['job title'] }}"
            },
            {
              "id": "0fa84796-0be3-48e3-948d-1b624767aabf",
              "name": "location",
              "type": "string",
              "value": "={{ $json.location }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "dfc85f4e-b5bf-4587-bf04-8a258dbe2dd2",
      "name": "Batch Leads",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        64,
        1872
      ],
      "parameters": {
        "options": {},
        "batchSize": 3
      },
      "typeVersion": 3
    },
    {
      "id": "0d1cda8b-ce5a-4fed-909e-bf5dfce4ea04",
      "name": "Find Email via OpenAI",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        400,
        1888
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "GPT-4O"
        },
        "options": {},
        "responses": {
          "values": [
            {}
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.1,
      "waitBetweenTries": 5000
    },
    {
      "id": "e39b6db4-74d8-4bd7-b101-80f4b7fb9c01",
      "name": "Rate Limit Delay",
      "type": "n8n-nodes-base.wait",
      "position": [
        752,
        1888
      ],
      "parameters": {
        "amount": 1.5
      },
      "typeVersion": 1.1,
      "alwaysOutputData": true
    },
    {
      "id": "771dc58e-ab45-4454-b345-434e3db6b2b1",
      "name": "Parse Email Results",
      "type": "n8n-nodes-base.set",
      "position": [
        1008,
        1888
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d7f492b9-5b46-46a9-92d0-503033ed417f",
              "name": "fullName",
              "type": "string",
              "value": "={{ $('Normalize Lead Data').item.json.fullName }}"
            },
            {
              "id": "3e0dc4e9-b1b1-40e8-b226-5533c88c401e",
              "name": "companyName",
              "type": "string",
              "value": "={{ $('Normalize Lead Data').item.json.companyName }}"
            },
            {
              "id": "3ec87184-191e-4cd0-8d20-e65e129dc113",
              "name": "companyWebsite",
              "type": "string",
              "value": "={{ $('Normalize Lead Data').item.json.companyWebsite }}"
            },
            {
              "id": "4ef9451d-6067-47d5-9fca-f889e4e177dc",
              "name": "linkedinIndustry",
              "type": "string",
              "value": "={{ $('Normalize Lead Data').item.json.linkedinIndustry }}"
            },
            {
              "id": "212c0ec2-6919-4003-acf6-9760239c564c",
              "name": "linkedinUrl",
              "type": "string",
              "value": "={{ $('Normalize Lead Data').item.json.linkedinUrl }}"
            },
            {
              "id": "f204ab88-2ece-4bf7-91d6-730f5cb5abe6",
              "name": "jobTitle",
              "type": "string",
              "value": "={{ $('Normalize Lead Data').item.json.jobTitle }}"
            },
            {
              "id": "96397794-c3cd-43d7-b958-ff8f1afa0474",
              "name": "location",
              "type": "string",
              "value": "={{ $('Normalize Lead Data').item.json.location }}"
            },
            {
              "id": "292fd51c-b01f-4edd-9928-aefa01c55937",
              "name": "email",
              "type": "string",
              "value": "={{ JSON.parse($json.text.replace(/```json|```/g, '').trim()).email }}"
            },
            {
              "id": "d50559ff-5f90-47e4-b2f9-7a891ac02bf1",
              "name": "source",
              "type": "string",
              "value": "={{ JSON.parse($json.text.replace(/```json|```/g, '').trim()).source }}"
            },
            {
              "id": "8b7d0284-c65e-458f-bf0d-8e9e0a713553",
              "name": "confidence",
              "type": "string",
              "value": "={{ JSON.parse($json.text.replace(/```json|```/g, '').trim()).confidence }}"
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 3.4
    },
    {
      "id": "4fd2271a-4b2c-4de7-9f61-834d700ee662",
      "name": "Has Valid Email?",
      "type": "n8n-nodes-base.if",
      "position": [
        496,
        1520
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "dbd13ac8-645e-4d7b-9019-7df4c86300ea",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $('Parse Email Results').item.json.email }}",
              "rightValue": "@"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "9f258023-f2df-4722-a23d-48f664e9b4a0",
      "name": "Save Qualified Lead",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        752,
        1376
      ],
      "parameters": {
        "columns": {
          "value": {
            "email": "={{ $('Parse Email Results').item.json.email }}",
            "source": "={{ $('Parse Email Results').item.json.source }}",
            "fullName": "={{ $('Parse Email Results').item.json.fullName }}",
            "jobTitle": "={{ $('Parse Email Results').item.json.jobTitle }}",
            "location": "={{ $('Parse Email Results').item.json.location }}",
            "confidence": "={{ $('Parse Email Results').item.json.confidence }}",
            "companyName": "={{ $('Parse Email Results').item.json.companyName }}",
            "linkedinUrl": "={{ $('Parse Email Results').item.json.linkedinUrl }}",
            "companyWebsite": "={{ $('Parse Email Results').item.json.companyWebsite }}"
          },
          "schema": [
            {
              "id": "fullName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "fullName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "companyName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "companyName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "companyWebsite",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "companyWebsite",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "linkedinUrl",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "linkedinUrl",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "jobTitle",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "jobTitle",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "location",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "source",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "confidence",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Qualified",
          "cachedResultName": "Qualified"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Watch For New Leads').item.json.id }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "d916daa6-7c65-42fb-84cb-34733c6a30b5",
      "name": "Save Unqualified Lead",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        752,
        1616
      ],
      "parameters": {
        "columns": {
          "value": {
            "email": "={{ $('Parse Email Results').item.json.email }}",
            "source": "={{ $('Parse Email Results').item.json.source }}",
            "fullName": "={{ $('Parse Email Results').item.json.fullName }}",
            "jobTitle": "={{ $('Parse Email Results').item.json.jobTitle }}",
            "location": "={{ $('Parse Email Results').item.json.location }}",
            "confidence": "={{ $('Parse Email Results').item.json.confidence }}",
            "companyName": "={{ $('Parse Email Results').item.json.companyName }}",
            "linkedinUrl": "={{ $('Parse Email Results').item.json.linkedinUrl }}",
            "companyWebsite": "={{ $('Parse Email Results').item.json.companyWebsite }}"
          },
          "schema": [
            {
              "id": "fullName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "fullName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "companyName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "companyName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "companyWebsite",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "companyWebsite",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "linkedinUrl",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "linkedinUrl",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "jobTitle",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "jobTitle",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "location",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "source",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "confidence",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Unqualified",
          "cachedResultName": "Unqualified"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Watch For New Leads').item.json.id }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "41db010d-81f6-4d39-b5a3-879d4f12bd71",
      "name": "Main Description",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1344,
        1328
      ],
      "parameters": {
        "color": "#3A3B0C",
        "width": 660,
        "height": 784,
        "content": "## Qualify Lead Lists & Find Professional Emails\n\nDrop a lead list into Google Drive. This workflow reads every row, uses OpenAI to find professional emails, and splits leads into Qualified and Unqualified tabs automatically.\n\n### How it works\n\n1. Google Drive trigger detects a new spreadsheet in your watched folder\n2. Reads all rows and normalizes fields (name, company, title, LinkedIn, location)\n3. Sends each lead to OpenAI in batches to find a verified professional email\n4. Validates results -- leads with a valid email go to \"Qualified\", the rest to \"Unqualified\"\n\n### Setup\n\n- [ ] Connect Google Drive and Google Sheets OAuth2 credentials\n- [ ] Set your watched folder ID in the trigger node\n- [ ] Connect your OpenAI API key\n- [ ] Input sheet columns: first name, last name, company, corporate website, linkedin industry, linkedin url, job title, location\n- [ ] Create \"Qualified\" and \"Unqualified\" tabs with columns: fullName, companyName, companyWebsite, linkedinUrl, jobTitle, location, email, source, confidence\n\n### Customization\n\n- Adjust batch size (default 3) and delay (default 1.5s) for your API tier\n- Swap GPT-4o for a cheaper model on high-volume lists"
      },
      "typeVersion": 1
    },
    {
      "id": "819bc1a3-4781-4c42-be8f-766942e18f6d",
      "name": "Section - Ingest",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        1776
      ],
      "parameters": {
        "color": 4,
        "width": 644,
        "height": 320,
        "content": "### Ingest leads\nWatches a Google Drive folder for new spreadsheets, reads all rows, and normalizes fields into a consistent format."
      },
      "typeVersion": 1
    },
    {
      "id": "1bfca190-b028-4e0e-8ef6-80531fc8415f",
      "name": "Section - Find Emails",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        1776
      ],
      "parameters": {
        "color": 2,
        "width": 1180,
        "height": 320,
        "content": "### Find & parse emails\nProcesses leads in batches of 3 with rate limiting. OpenAI searches for a verified professional email and returns email, source, and confidence score."
      },
      "typeVersion": 1
    },
    {
      "id": "4dd8d3fc-5b8b-48eb-b6b8-9786dab04ef7",
      "name": "Section - Route Results",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        1280
      ],
      "parameters": {
        "color": "#1A4651",
        "width": 544,
        "height": 484,
        "content": "### Route results\nChecks if a valid email was found. Qualified leads (with email) and unqualified leads (without) are written to separate tabs on the same sheet."
      },
      "typeVersion": 1
    },
    {
      "id": "477271b1-227c-45a9-b3ef-df985c5ce3a7",
      "name": "Warning",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        1632
      ],
      "parameters": {
        "color": 3,
        "width": 244,
        "height": 120,
        "content": "**Dont forget to** Connect your Google Drive, Sheets, and OpenAI credentials and update the folder ID in the trigger node before activating this workflow."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "6fd6fc41-3d56-4cc8-84fb-e0ba43400cd0",
  "connections": {
    "Batch Leads": {
      "main": [
        [
          {
            "node": "Has Valid Email?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Find Email via OpenAI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Lead Sheet": {
      "main": [
        [
          {
            "node": "Normalize Lead Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Valid Email?": {
      "main": [
        [
          {
            "node": "Save Qualified Lead",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save Unqualified Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rate Limit Delay": {
      "main": [
        [
          {
            "node": "Parse Email Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Lead Data": {
      "main": [
        [
          {
            "node": "Batch Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Email Results": {
      "main": [
        [
          {
            "node": "Batch Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Watch For New Leads": {
      "main": [
        [
          {
            "node": "Read Lead Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Email via OpenAI": {
      "main": [
        [
          {
            "node": "Rate Limit Delay",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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

About this workflow

Drop a lead list into Google Drive. This workflow reads it, finds professional emails using OpenAI, and splits leads into Qualified and Unqualified sheets fully automated. Watch For New Leads Google Drive trigger monitors a folder. When a new spreadsheet lands, the workflow…

Source: https://n8n.io/workflows/14198/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

The Problem That it Solves

Google Drive Trigger, OpenAI, Google Drive +5
AI & RAG

Content creators, YouTubers, and social media managers who want to repurpose long form videos into short clips without doing it manually. Works on self hosted n8n instances.

Google Drive Trigger, Google Drive, N8N Nodes Renderio +3
AI & RAG

This workflow is designed for teams and businesses that receive invoices in Google Drive and want to automatically extract structured financial data without manual processing. It is ideal for finance

Telegram Trigger, Google Drive Trigger, Google Drive +3
AI & RAG

Recibos video. Uses googleDriveTrigger, googleDrive, httpRequest, openAi. Event-driven trigger; 18 nodes.

Google Drive Trigger, Google Drive, HTTP Request +2
AI & RAG

This workflow automates end-to-end contract analysis when a new file is uploaded to Google Drive. It downloads the contract, extracts its content, and uses AI to analyze legal terms, obligations, and

Google Drive, OpenAI, Gmail +2