AutomationFlowsAI & RAG › Enrich Website Leads and Draft Outreach with Serpapi, Gpt-4o-mini, Sheets,…

Enrich Website Leads and Draft Outreach with Serpapi, Gpt-4o-mini, Sheets,…

Original n8n title: Enrich Website Leads and Draft Outreach with Serpapi, Gpt-4o-mini, Sheets, Gmail and Slack

ByRahul Joshi @rahul08 on n8n.io

This workflow captures website visitor form submissions, researches the visitor’s company using SerpApi, extracts structured insights and drafts a personalized outreach email with OpenAI, logs the enriched lead to Google Sheets, and emails the sales team via Gmail, with Slack…

Event trigger★★★★☆ complexityAI-powered21 nodesError TriggerSlackForm TriggerHTTP RequestOpenAIGoogle SheetsGmail
AI & RAG Trigger: Event Nodes: 21 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Error Trigger → Gmail 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": "8RgAemjkqY6xCF2n",
  "name": "AI Website Visitor Intelligence & Personalized Sales Outreach System",
  "tags": [],
  "nodes": [
    {
      "id": "770d471b-ac9c-45bd-8910-6185d38fe6bc",
      "name": "Section \u2013 Error Handling",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        3088
      ],
      "parameters": {
        "color": 7,
        "width": 652,
        "height": 456,
        "content": "## \u26a0\ufe0f Error Handling\nA workflow-level error trigger catches any node failure and posts an alert to Slack. Replace `YOUR_SLACK_CHANNEL_ID` with your ops or alerts channel before going live."
      },
      "typeVersion": 1
    },
    {
      "id": "9cc5a511-a867-45bd-9994-b74422427507",
      "name": "On Workflow Error",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        464,
        3312
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "b8775a8e-56da-45d8-ac78-298479d2442e",
      "name": "Slack \u2013 Post Workflow Error Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        736,
        3312
      ],
      "parameters": {
        "text": "=\u26a0\ufe0f *AI Crisis Management Agent Error*\n\n*Workflow:* {{ $workflow.name }}\n*Failed Node:* {{ $execution.lastNodeExecuted }}\n*Time:* {{ $now.format('MMM D, YYYY \u2013 HH:mm') }}\n*Execution ID:* {{ $execution.id }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SLACK_CHANNEL_ID",
          "cachedResultName": "your-alerts-channel"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.3
    },
    {
      "id": "496ff3ef-6d46-493f-a04f-7bf45173c8bf",
      "name": "Slack \u2013 Post AI Research Error",
      "type": "n8n-nodes-base.slack",
      "position": [
        2288,
        2768
      ],
      "parameters": {
        "text": "=Error in the Ai node ",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SLACK_CHANNEL_ID",
          "cachedResultName": "your-alerts-channel"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.3
    },
    {
      "id": "c3c37a1f-9ad0-4d88-b9d2-63b61d4df49c",
      "name": "Slack \u2013 Post AI Outreach Error",
      "type": "n8n-nodes-base.slack",
      "position": [
        2800,
        2848
      ],
      "parameters": {
        "text": "=Error in the Ai node ",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SLACK_CHANNEL_ID",
          "cachedResultName": "your-alerts-channel"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.3
    },
    {
      "id": "aa2ac24a-be54-4a30-82ea-b41e0196065e",
      "name": "\ud83d\udccc Overview \u2013 How This Workflow Works1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -736,
        1632
      ],
      "parameters": {
        "color": 2,
        "width": 836,
        "height": 612,
        "content": "## \ud83d\udd0d Website Visitor Research Agent\n\n### How it works\nA visitor fills in an n8n form with their name, company, website, and job title. The workflow fires two parallel SerpApi searches \u2014 a company overview and a LinkedIn profile lookup \u2014 and merges the results. GPT-4o-mini then plays B2B research analyst, extracting company size, industry, funding stage, tech stack, and buying signals. A second AI pass writes a personalised outreach email for that visitor's role and context. The enriched profile is logged to Google Sheets and the sales rep gets a Gmail notification with the research summary and ready-to-send outreach draft. Both AI nodes have dedicated Slack error alerts, and a global error trigger covers any other failure.\n\n### Setup steps\n1. Connect **Google Sheets OAuth2** and create a `CRM Records` tab. Replace `YOUR_GOOGLE_SHEET_ID` in the Create CRM Record node.\n2. Connect **OpenAI API** to both AI nodes.\n3. Connect **SerpApi** to both search nodes.\n4. Connect **Gmail OAuth2** and update `sales@yourcompany.com` in the Notify Sales Rep node.\n5. Connect **Slack OAuth2** and replace `YOUR_SLACK_CHANNEL_ID` in all three Slack nodes.\n6. Activate the form trigger and embed the production URL on your website."
      },
      "typeVersion": 1
    },
    {
      "id": "e9df51b9-bb21-4e1c-82ec-8627b6f18228",
      "name": "Section \u2013 Visitor Intake & Normalisation1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        2240
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 552,
        "content": "## \ud83d\udccb Visitor Intake & Normalisation\nCaptures the visitor's form submission and standardises the field names \u2014 company name, website, visitor name, job title \u2014 into a clean structure that every downstream node reads consistently."
      },
      "typeVersion": 1
    },
    {
      "id": "86be2571-d5b7-47ec-bcf3-84351ef44528",
      "name": "Section \u2013 Parallel Web Research1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        992,
        2240
      ],
      "parameters": {
        "color": 7,
        "width": 816,
        "height": 552,
        "content": "## \ud83c\udf10 Parallel Web Research\nTwo SerpApi calls run simultaneously \u2014 one for a company overview with funding and size signals, one for the visitor's LinkedIn profile. Results are combined into a single payload before the AI analysis step."
      },
      "typeVersion": 1
    },
    {
      "id": "2e6a8619-9309-4582-9943-9af8fa64ba50",
      "name": "Section \u2013 AI Research & Outreach Generation1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1840,
        2240
      ],
      "parameters": {
        "color": 7,
        "width": 1160,
        "height": 856,
        "content": "## \ud83e\udd16 AI Research & Outreach Generation\nGPT-4o-mini first extracts structured intelligence from the raw search results \u2014 industry, tech stack, buying signals. A second pass writes a personalised outreach email for the visitor's role and company context. Each AI node routes failures to its own Slack alert."
      },
      "typeVersion": 1
    },
    {
      "id": "77c1cf1f-0459-44cc-a680-165d97d69992",
      "name": "Section \u2013 CRM Logging & Sales Rep Notification1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3104,
        2240
      ],
      "parameters": {
        "color": 7,
        "width": 888,
        "height": 472,
        "content": "## \ud83d\udcbe CRM Logging & Sales Rep Notification\nBuilds a structured CRM row from the enriched profile and appends it to Google Sheets. The sales rep receives a Gmail alert with the full research summary and the personalised outreach draft \u2014 ready to review and send."
      },
      "typeVersion": 1
    },
    {
      "id": "460e7129-047a-411b-9c87-d7832dbfffce",
      "name": "Website Visitor Form1",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        400,
        2480
      ],
      "parameters": {
        "options": {
          "buttonLabel": "Submit"
        },
        "formTitle": "Talk to Our Team",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Full Name",
              "requiredField": true
            },
            {
              "fieldType": "email",
              "fieldLabel": "Work Email",
              "requiredField": true
            },
            {
              "fieldLabel": "Company Name",
              "requiredField": true
            },
            {
              "fieldLabel": "Company Website",
              "requiredField": true
            },
            {
              "fieldLabel": "Job Title"
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "What are you interested in?"
            }
          ]
        },
        "formDescription": "Tell us a bit about yourself and we'll get back to you shortly."
      },
      "typeVersion": 2.2
    },
    {
      "id": "52716fb2-8efe-41ae-bf41-3f0e2ae1de78",
      "name": "Normalize Visitor Data1",
      "type": "n8n-nodes-base.set",
      "position": [
        672,
        2480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "contactName",
              "type": "string",
              "value": "={{ $json['Full Name'] }}"
            },
            {
              "id": "a2",
              "name": "contactEmail",
              "type": "string",
              "value": "={{ $json['Work Email'] }}"
            },
            {
              "id": "a3",
              "name": "companyName",
              "type": "string",
              "value": "={{ $json['Company Name'] }}"
            },
            {
              "id": "a4",
              "name": "companyWebsite",
              "type": "string",
              "value": "={{ $json['Company Website'] }}"
            },
            {
              "id": "a5",
              "name": "jobTitle",
              "type": "string",
              "value": "={{ $json['Job Title'] }}"
            },
            {
              "id": "a6",
              "name": "interest",
              "type": "string",
              "value": "={{ $json['What are you interested in?'] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8518576b-efe4-4b1b-b785-0e762f9b7425",
      "name": "SerpApi - Company Overview Search1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1088,
        2480
      ],
      "parameters": {
        "url": "https://serpapi.com/search.json",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "engine",
              "value": "google"
            },
            {
              "name": "q",
              "value": "={{ $json.companyName }} company size employees funding tech stack"
            },
            {
              "name": "num",
              "value": "10"
            }
          ]
        },
        "nodeCredentialType": "serpApi"
      },
      "typeVersion": 4.2
    },
    {
      "id": "254bb69d-13c5-4db9-b77d-06933b2a85af",
      "name": "SerpApi - LinkedIn Search1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1376,
        2480
      ],
      "parameters": {
        "url": "https://serpapi.com/search.json",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "engine",
              "value": "google"
            },
            {
              "name": "q",
              "value": "={{ $('Normalize Visitor Data1').item.json.companyName }} site:linkedin.com/company"
            },
            {
              "name": "num",
              "value": "5"
            }
          ]
        },
        "nodeCredentialType": "serpApi"
      },
      "typeVersion": 4.2
    },
    {
      "id": "ef247e34-4646-4e3e-a7f3-e5a359e7f697",
      "name": "Combine Search Results1",
      "type": "n8n-nodes-base.code",
      "position": [
        1664,
        2480
      ],
      "parameters": {
        "jsCode": "const formData = $('Normalize Visitor Data1').item.json;\nconst generalResults = $('SerpApi - Company Overview Search1').item.json;\nconst linkedinResults = $('SerpApi - LinkedIn Search1').item.json;\n\nfunction summarize(results) {\n  const organic = results.organic_results || [];\n  return organic.slice(0, 8).map((r, i) => `${i + 1}. ${r.title || ''} - ${r.snippet || ''} (${r.link || ''})`).join('\\n');\n}\n\nconst knowledgeGraph = generalResults.knowledge_graph ? JSON.stringify(generalResults.knowledge_graph) : 'none';\n\nreturn [{\n  json: {\n    contactName: formData.contactName,\n    contactEmail: formData.contactEmail,\n    jobTitle: formData.jobTitle,\n    companyName: formData.companyName,\n    companyWebsite: formData.companyWebsite,\n    interest: formData.interest,\n    generalSearchText: summarize(generalResults) + '\\n\\nKnowledge Graph: ' + knowledgeGraph,\n    linkedinSearchText: summarize(linkedinResults)\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "43f13093-a18c-46b7-8263-7b4f60091ea9",
      "name": "AI Research Analyst1",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "onError": "continueErrorOutput",
      "position": [
        1888,
        2480
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a B2B company research analyst. You will receive raw Google search snippets about a company. Extract and reasonably infer the following fields, using the search data first and filling gaps with sound inference when data is missing. Respond with ONLY valid JSON (no markdown, no commentary) matching exactly this schema:\n{\"linkedin_url\":\"\",\"company_size\":\"\",\"estimated_funding\":\"\",\"tech_stack\":[],\"recent_news\":[],\"competitors\":[]}"
            },
            {
              "content": "=Company Name: {{ $json.companyName }}\nWebsite: {{ $json.companyWebsite }}\n\nGeneral Search Results:\n{{ $json.generalSearchText }}\n\nLinkedIn Search Results:\n{{ $json.linkedinSearchText }}\n\nExtract the company research data as the specified JSON schema."
            }
          ]
        },
        "jsonOutput": true
      },
      "typeVersion": 1.8
    },
    {
      "id": "6eb0620b-c4de-4490-b3da-c61eed32fff4",
      "name": "Parse Research Data1",
      "type": "n8n-nodes-base.code",
      "position": [
        2256,
        2480
      ],
      "parameters": {
        "jsCode": "const formData = $('Combine Search Results1').item.json;\nconst aiOutput = $json.message.content;\n\n// jsonOutput:true on the OpenAI node already returns a parsed object.\n// Only JSON.parse it if it actually came back as a string.\nlet research = aiOutput;\nif (typeof aiOutput === 'string') {\n  try {\n    research = JSON.parse(aiOutput);\n  } catch (e) {\n    research = {\n      linkedin_url: '',\n      company_size: '',\n      estimated_funding: '',\n      tech_stack: [],\n      recent_news: [],\n      competitors: []\n    };\n  }\n}\n\nreturn [{\n  json: {\n    ...formData,\n    linkedinUrl: research.linkedin_url || '',\n    companySize: research.company_size || '',\n    estimatedFunding: research.estimated_funding || '',\n    techStack: Array.isArray(research.tech_stack) ? research.tech_stack.join(', ') : (research.tech_stack || ''),\n    recentNews: Array.isArray(research.recent_news) ? research.recent_news.join(' | ') : (research.recent_news || ''),\n    competitors: Array.isArray(research.competitors) ? research.competitors.join(', ') : (research.competitors || '')\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "afce95e6-484b-45c2-8ffc-b88240aad6c3",
      "name": "AI Outreach Generator1",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "onError": "continueErrorOutput",
      "position": [
        2512,
        2480
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are an expert B2B sales development rep writing short, highly personalized first-touch outreach emails. Use the company research provided to reference something specific and relevant. Keep it under 120 words, no generic fluff, one clear call to action. Respond with ONLY valid JSON (no markdown, no commentary) matching exactly this schema:\n{\"subject\":\"\",\"email_body\":\"\"}"
            },
            {
              "content": "=Visitor Name: {{ $json.contactName }}\nJob Title: {{ $json.jobTitle }}\nCompany: {{ $json.companyName }}\nWhat they're interested in: {{ $json.interest }}\n\nCompany Research:\n- LinkedIn: {{ $json.linkedinUrl }}\n- Company Size: {{ $json.companySize }}\n- Funding: {{ $json.estimatedFunding }}\n- Tech Stack: {{ $json.techStack }}\n- Recent News: {{ $json.recentNews }}\n- Competitors: {{ $json.competitors }}\n\nWrite the personalized outreach email as the specified JSON."
            }
          ]
        },
        "jsonOutput": true
      },
      "typeVersion": 1.8
    },
    {
      "id": "cbcfbd83-63dd-426e-bb15-c9d727b28bd9",
      "name": "Build CRM Record1",
      "type": "n8n-nodes-base.code",
      "position": [
        3248,
        2464
      ],
      "parameters": {
        "jsCode": "const data = $('Parse Research Data1').item.json;\nconst aiOutreach = $json.message.content;\n\n// Same fix here: jsonOutput:true already returns an object.\nlet outreach = aiOutreach;\nif (typeof aiOutreach === 'string') {\n  try {\n    outreach = JSON.parse(aiOutreach);\n  } catch (e) {\n    outreach = { subject: `Quick question, ${data.contactName}`, email_body: aiOutreach };\n  }\n}\n\nreturn [{\n  json: {\n    ...data,\n    outreachSubject: outreach.subject,\n    outreachBody: outreach.email_body,\n    dateResearched: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "f5bd943f-d1fe-404a-bbcf-306b12f4e207",
      "name": "Create CRM Record1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3520,
        2464
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $json.dateResearched }}",
            "Email": "={{ $json.contactEmail }}",
            "Funding": "={{ $json.estimatedFunding }}",
            "Website": "={{ $json.companyWebsite }}",
            "Interest": "={{ $json.interest }}",
            "Job Title": "={{ $json.jobTitle }}",
            "Tech Stack": "={{ $json.techStack }}",
            "Competitors": "={{ $json.competitors }}",
            "Recent News": "={{ $json.recentNews }}",
            "Company Name": "={{ $json.companyName }}",
            "Company Size": "={{ $json.companySize }}",
            "Contact Name": "={{ $json.contactName }}",
            "LinkedIn URL": "={{ $json.linkedinUrl }}",
            "Outreach Body": "={{ $json.outreachBody }}",
            "Outreach Subject": "={{ $json.outreachSubject }}"
          },
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contact Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Job Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Job Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Company Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Website",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Website",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Interest",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Interest",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LinkedIn URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "LinkedIn URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Size",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Company Size",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Funding",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Funding",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tech Stack",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Tech Stack",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Recent News",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Recent News",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Competitors",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Competitors",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Outreach Subject",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Outreach Subject",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Outreach Body",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Outreach Body",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1128329709,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=1128329709",
          "cachedResultName": "CRM Records"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_SHEET_ID",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit?usp=drivesdk",
          "cachedResultName": "CRM Records"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "123db5bc-f101-4d59-8342-e271cb00808b",
      "name": "Notify Sales Rep1",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3760,
        2464
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=<div style=\"font-family: Arial, Helvetica, sans-serif; max-width: 600px; margin: 0 auto; color: #1a1a1a;\">\n  <div style=\"background: #1F4E78; padding: 20px 24px; border-radius: 6px 6px 0 0;\">\n    <h2 style=\"color: #ffffff; margin: 0; font-size: 20px;\">\ud83d\udd0e New Lead Researched</h2>\n    <p style=\"color: #d6e4f0; margin: 4px 0 0; font-size: 14px;\">{{ $('Build CRM Record1').item.json.companyName }}</p>\n  </div>\n\n  <div style=\"border: 1px solid #e0e0e0; border-top: none; padding: 20px 24px;\">\n\n    <h3 style=\"font-size: 15px; color: #1F4E78; margin: 0 0 8px;\">Contact</h3>\n    <table style=\"width: 100%; border-collapse: collapse; font-size: 14px; margin-bottom: 20px;\">\n      <tr><td style=\"padding: 4px 0; color: #666; width: 120px;\">Name</td><td style=\"padding: 4px 0;\"><strong>{{ $('Build CRM Record1').item.json.contactName }}</strong></td></tr>\n      <tr><td style=\"padding: 4px 0; color: #666;\">Job Title</td><td style=\"padding: 4px 0;\">{{ $('Build CRM Record1').item.json.jobTitle }}</td></tr>\n      <tr><td style=\"padding: 4px 0; color: #666;\">Email</td><td style=\"padding: 4px 0;\"><a href=\"mailto:{{ $('Build CRM Record1').item.json.contactEmail }}\" style=\"color: #1F4E78;\">{{ $('Build CRM Record1').item.json.contactEmail }}</a></td></tr>\n      <tr><td style=\"padding: 4px 0; color: #666;\">Website</td><td style=\"padding: 4px 0;\"><a href=\"{{ $('Build CRM Record1').item.json.companyWebsite }}\" style=\"color: #1F4E78;\">{{ $('Build CRM Record1').item.json.companyWebsite }}</a></td></tr>\n      <tr><td style=\"padding: 4px 0; color: #666; vertical-align: top;\">Interest</td><td style=\"padding: 4px 0;\">{{ $('Build CRM Record1').item.json.interest }}</td></tr>\n    </table>\n\n    <h3 style=\"font-size: 15px; color: #1F4E78; margin: 0 0 8px;\">Company Research</h3>\n    <table style=\"width: 100%; border-collapse: collapse; font-size: 14px; margin-bottom: 20px;\">\n      <tr><td style=\"padding: 4px 0; color: #666; width: 120px;\">LinkedIn</td><td style=\"padding: 4px 0;\"><a href=\"{{ $('Build CRM Record1').item.json.linkedinUrl }}\" style=\"color: #1F4E78;\">{{ $('Build CRM Record1').item.json.linkedinUrl }}</a></td></tr>\n      <tr><td style=\"padding: 4px 0; color: #666;\">Company Size</td><td style=\"padding: 4px 0;\">{{ $('Build CRM Record1').item.json.companySize }}</td></tr>\n      <tr><td style=\"padding: 4px 0; color: #666;\">Funding</td><td style=\"padding: 4px 0;\">{{ $('Build CRM Record1').item.json.estimatedFunding }}</td></tr>\n      <tr><td style=\"padding: 4px 0; color: #666;\">Tech Stack</td><td style=\"padding: 4px 0;\">{{ $('Build CRM Record1').item.json.techStack || 'Not found' }}</td></tr>\n      <tr><td style=\"padding: 4px 0; color: #666;\">Recent News</td><td style=\"padding: 4px 0;\">{{ $('Build CRM Record1').item.json.recentNews || 'Not found' }}</td></tr>\n      <tr><td style=\"padding: 4px 0; color: #666;\">Competitors</td><td style=\"padding: 4px 0;\">{{ $('Build CRM Record1').item.json.competitors || 'Not found' }}</td></tr>\n    </table>\n\n    <h3 style=\"font-size: 15px; color: #1F4E78; margin: 0 0 8px;\">Drafted Outreach</h3>\n    <div style=\"background: #f7f9fb; border-left: 3px solid #1F4E78; padding: 12px 16px; font-size: 14px;\">\n      <p style=\"margin: 0 0 8px;\"><strong>Subject:</strong> {{ $('Build CRM Record1').item.json.outreachSubject }}</p>\n      <p style=\"margin: 0; white-space: pre-line;\">{{ $('Build CRM Record1').item.json.outreachBody }}</p>\n    </div>\n\n  </div>\n\n  <p style=\"font-size: 12px; color: #999; margin-top: 16px;\">This email was sent automatically with n8n.</p>\n</div>",
        "options": {},
        "subject": "=New Lead Researched: {{ $('Build CRM Record1').item.json.companyName }}"
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "0b425b95-630b-4a7a-a0a0-e075cc948790",
  "nodeGroups": [],
  "connections": {
    "Build CRM Record1": {
      "main": [
        [
          {
            "node": "Create CRM Record1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On Workflow Error": {
      "main": [
        [
          {
            "node": "Slack \u2013 Post Workflow Error Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create CRM Record1": {
      "main": [
        [
          {
            "node": "Notify Sales Rep1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Research Analyst1": {
      "main": [
        [
          {
            "node": "Parse Research Data1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack \u2013 Post AI Research Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Research Data1": {
      "main": [
        [
          {
            "node": "AI Outreach Generator1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Website Visitor Form1": {
      "main": [
        [
          {
            "node": "Normalize Visitor Data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Outreach Generator1": {
      "main": [
        [
          {
            "node": "Build CRM Record1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack \u2013 Post AI Outreach Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine Search Results1": {
      "main": [
        [
          {
            "node": "AI Research Analyst1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Visitor Data1": {
      "main": [
        [
          {
            "node": "SerpApi - Company Overview Search1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SerpApi - LinkedIn Search1": {
      "main": [
        [
          {
            "node": "Combine Search Results1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack \u2013 Post AI Outreach Error": {
      "main": [
        [
          {
            "node": "SerpApi - Company Overview Search1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack \u2013 Post AI Research Error": {
      "main": [
        [
          {
            "node": "SerpApi - Company Overview Search1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SerpApi - Company Overview Search1": {
      "main": [
        [
          {
            "node": "SerpApi - LinkedIn Search1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This workflow captures website visitor form submissions, researches the visitor’s company using SerpApi, extracts structured insights and drafts a personalized outreach email with OpenAI, logs the enriched lead to Google Sheets, and emails the sales team via Gmail, with Slack…

Source: https://n8n.io/workflows/17684/ — 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

Consultants, agencies, freelancers, and professional service firms who need to create customized proposals and contracts quickly and efficiently.

Google Sheets Trigger, OpenAI, Google Docs +5
AI & RAG

Analyze incoming support requests, classify intent and priority with AI, create Jira tickets, assign the correct team, send Slack notifications, and track SLA deadlines. Supports Gmail, WhatsApp, form

Gmail Trigger, HTTP Request, Form Trigger +4
AI & RAG

Complete AI-powered sales system Automates lead capture, qualification, and follow-up from multiple channels. AI INTELLIGENCE:

Gmail Trigger, Google Sheets, OpenAI +3
AI & RAG

This workflow accepts construction work permit requests via webhook, logs them to Google Sheets, uses OpenAI (gpt-4o-mini) to detect conflicts against active permits, routes the request to a superviso

Error Trigger, Slack, Google Sheets +2
AI & RAG

This workflow is an AI-powered lighting and look development pipeline designed for VFX production. It transforms a single lighting brief into multiple high-quality cinematic lighting references using

Form Trigger, HTTP Request, Google Drive +4