AutomationFlowsAI & RAG › Automate B2b Sales Research & Email Personalization with Sona and Gpt-4

Automate B2b Sales Research & Email Personalization with Sona and Gpt-4

BySona Labs @sona on n8n.io

Automatically research B2B leads and generate personalized outreach emails by reading prospects from Google Sheets, enriching with company data from Sona Enrich, analyzing insights with AI, and creating custom emails — so you can scale personalized outreach to target accounts.

Event trigger★★★★☆ complexityAI-powered23 nodesGoogle SheetsHTTP RequestOpenAI ChatOutput Parser StructuredAgent
AI & RAG Trigger: Event Nodes: 23 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → 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": "ccTRcJaItqjBf82B",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Sona-Powered AI Sales Research & Personalized Email Automation",
  "tags": [],
  "nodes": [
    {
      "id": "12456840-0516-48f1-8a13-ba5a949293e7",
      "name": "Read Leads from Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -720,
        800
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1626340606,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_YOUR_AWS_SECRET_KEY_HERE#gid=1626340606",
          "cachedResultName": "AI-Powered Lead Research & Personalized Email Generation with Groq & Google Sheets"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1qUir1c-_ScMnoYVoQ0W41nsv5IpLW6rjK8HUNqvNnAg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_YOUR_AWS_SECRET_KEY_HERE?usp=drivesdk",
          "cachedResultName": "example"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "b89e6abb-e250-456e-9286-de459be1ce46",
      "name": "Loop Over Leads",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -304,
        800
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "a4503a84-53f0-4994-8b94-b6c55ea64f13",
      "name": "Update Sheet with Results",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        432,
        1280
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $('Loop Over Leads').first().json.Email }}",
            "Email Body": "={{ $json['Email Body'] }}",
            "Key Insight": "={{ $json['Key Insight'] }}",
            "Pain Points": "={{ $('Company Research AI').first().json.output.pain_points.join('\\n\\n') }}",
            "Sent Status": "={{ $json['Sent Status'] }}",
            "Email Subject": "={{ $json['Email Subject'] }}",
            "Generated Date": "={{ $json['Generated Date'] }}",
            "Research Status": "Completed",
            "Send Email Link": "={{ $json['Send Email Link'] }}"
          },
          "schema": [
            {
              "id": "Website Domain",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Website Domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Company Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Contact Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Industry",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Industry",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Research Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Research Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pain Points",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Pain Points",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Key Insight",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Key Insight",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Subject",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email Subject",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Body",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email Body",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Send Email Link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Send Email Link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Generated Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Generated Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sent Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sent Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1626340606,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_YOUR_AWS_SECRET_KEY_HERE#gid=1626340606",
          "cachedResultName": "AI-Powered Lead Research & Personalized Email Generation with Groq & Google Sheets"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1qUir1c-_ScMnoYVoQ0W41nsv5IpLW6rjK8HUNqvNnAg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_YOUR_AWS_SECRET_KEY_HERE?usp=drivesdk",
          "cachedResultName": "example"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "18628bd8-50ea-4177-8024-a0999aac9619",
      "name": "Sona Company Search",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        496,
        832
      ],
      "parameters": {
        "url": "https://api2.sonalabs.com/resource/companies/search",
        "method": "POST",
        "options": {
          "timeout": 50000,
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 3000
            }
          },
          "response": {
            "response": {
              "neverError": true
            }
          }
        },
        "jsonBody": "={\n    \"filters\": [\n        {\n            \"field\": \"website\",\n            \"operator\": \"contains\",\n            \"value\": \"{{ $json['Website Domain'] ? $json['Website Domain'].replace(/^https?:\\/\\//, '').replace(/\\.(com|net|org|io|co|ai|us|uk)\\/.*$/, '').replace(/\\.(com|net|org|io|co|ai|us|uk)$/, '') : $json.Email.replace(/^.*@/, '').replace(/\\.(com|net|org|io|co|ai|us|uk).*$/, '') }}\"\n        }\n    ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Accept",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": false
    },
    {
      "id": "de8386c3-c092-43d4-8f71-f3f6bcd8b35f",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        880,
        832
      ],
      "parameters": {
        "jsCode": "// Helper function to extract core company name from domain\nfunction extractCompanyName(domain) {\n  return domain\n    .replace(/^https?:\\/\\//, '')  // Remove protocol\n    .replace(/^www\\./, '')         // Remove www\n    .replace(/\\/$/, '')            // Remove trailing slash\n    .replace(/\\.(com|net|org|io|co|ai|us|uk|biz|info|be)\\/.*$/, '')  // Remove extension + path\n    .replace(/\\.(com|net|org|io|co|ai|us|uk|biz|info|be)$/, '')      // Remove extension\n    .toLowerCase();\n}\n\n// Get the loop domain and extract company name\nconst loopDomain = $('Loop Over Leads').first().json['Website Domain'];\nconst loopCompanyName = extractCompanyName(loopDomain);\n\n// Get the list from the API response\nconst list = $input.first().json.data.list;\n\n// TIER 1: Exact domain match (with any TLD)\nconst exactMatch = list.find(item => {\n  const itemCompanyName = extractCompanyName(item.website);\n  return itemCompanyName === loopCompanyName;\n});\n\nif (exactMatch) {\n  return exactMatch;\n}\n\n// TIER 2: Check if company name appears in the 'name' field\nconst nameMatch = list.find(item => {\n  if (!item.name) return false;\n  const itemNameClean = item.name.toLowerCase().replace(/[^a-z0-9]/g, '');\n  const loopNameClean = loopCompanyName.replace(/[^a-z0-9]/g, '');\n  return itemNameClean === loopNameClean || \n         itemNameClean.includes(loopNameClean) ||\n         loopNameClean.includes(itemNameClean);\n});\n\nif (nameMatch) {\n  return nameMatch;\n}\n\n// TIER 3: Check LinkedIn URL (often most reliable)\nconst linkedinMatch = list.find(item => {\n  if (!item.linkedinUrl) return false;\n  const linkedinName = item.linkedinUrl\n    .replace('linkedin.com/company/', '')\n    .replace(/[^a-z0-9]/g, '')\n    .toLowerCase();\n  const loopNameClean = loopCompanyName.replace(/[^a-z0-9]/g, '');\n  \n  return linkedinName === loopNameClean;\n});\n\nif (linkedinMatch) {\n  return linkedinMatch;\n}\n\n// TIER 4: Partial match with strict rules (must start with same name)\nconst partialMatch = list.find(item => {\n  const itemCompanyName = extractCompanyName(item.website);\n  \n  // Only match if one STARTS with the other (not just contains)\n  return itemCompanyName.startsWith(loopCompanyName) || \n         loopCompanyName.startsWith(itemCompanyName);\n});\n\nif (partialMatch) {\n  return partialMatch;\n}\n\n// TIER 5: No match found, return first item as fallback\nreturn list[0];"
      },
      "typeVersion": 2
    },
    {
      "id": "2b0c1d96-ec26-44d3-98f2-06d124b1e3aa",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -928,
        1392
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "14163380-7a5f-4d1e-9229-1822d921c87d",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -640,
        1376
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"pain_points\": [\"pain point 1\", \"pain point 2\", \"pain point 3\"],\n  \"growth_opportunities\": [\"opportunity 1\", \"opportunity 2\"],\n  \"personalization_hooks\": [\"hook 1\", \"hook 2\", \"hook 3\"],\n  \"recommended_tone\": \"consultative/direct/educational\",\n  \"key_value_proposition\": \"one sentence value prop\",\n  \"suggested_cta\": \"specific call to action\",\n  \"fit_score\": \"High/Medium/Low\",\n  \"risk_factors\": [\"risk 1\", \"risk 2\"],\n  \"one_liner_insight\": \"A compelling one-sentence insight about this company that could open an email\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "3181095c-d81c-46b1-acfd-dbbc499491ef",
      "name": "Company Research AI",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -928,
        1248
      ],
      "parameters": {
        "text": "=Analyze the following company data and provide a comprehensive sales research report:\n\nCOMPANY DATA:\n---\nName: {{ $json.name }}\nWebsite: {{ $json.website }}\nIndustry: {{ $json.industry }}\nFounded: {{ $json.founded }}\nEmployee Count: {{ $json.employeesRange }}\nLocation: {{ $json.city }}, {{ $json.state }}, {{ $json.country }}\nEstimated Revenue: {{ $json.estimatedAnnualRevenue }}\nCompany Type: {{ $json.type }}\n\nDescription: {{ $json.description }}\n\nTechnology Stack: {{ $json.tech ? $json.tech.join(', ') : 'Not available' }}\n\nTech Categories: {{ $json.techCategories ? $json.techCategories.join(', ') : 'Not available' }}\n\nFounder(s): {{ $json.founderIdentifiers ? $json.founderIdentifiers.join(', ') : 'Not available' }}\n\nSocial Media Presence:\n- LinkedIn: {{ $json.linkedinUrl }}\n- Twitter: {{ $json.twitterUrl }}\n- Facebook: {{ $json.facebookUrl }}\n- YouTube: {{ $json.youtubeUrl }}\n---\n\nBased on this data, provide the following analysis in a structured format:\n\n1. PAIN POINTS & CHALLENGES (3-5 specific issues):\n   - Identify concrete business challenges this company likely faces based on their industry, size, tech stack, and business model\n   - Focus on problems that are actionable and relevant to sales/marketing automation solutions\n   - Consider their technology stack limitations or gaps\n\n2. GROWTH OPPORTUNITIES (2-3 opportunities):\n   - Where could they improve their operations?\n   - What market trends are they positioned to capitalize on?\n   - What gaps in their current tech stack could they fill?\n\n3. PERSONALIZATION HOOKS (3-4 talking points):\n   - Specific details from their description, tech stack, or background that can be referenced in outreach\n   - Recent company milestones or achievements (infer from founding year, growth stage)\n   - Unique aspects of their business model or positioning\n\n4. RECOMMENDED APPROACH:\n   - What tone should the outreach take? (consultative, direct, educational, etc.)\n   - What value proposition would resonate most?\n   - What CTA (call-to-action) would work best?\n\n5. RISK FACTORS:\n   - Any red flags or concerns? (outdated tech, very small team, potential budget constraints)\n   - Likelihood of being a good fit (High/Medium/Low)\n\nFORMAT YOUR RESPONSE AS JSON:\n{\n  \"pain_points\": [\"pain point 1\", \"pain point 2\", \"pain point 3\"],\n  \"growth_opportunities\": [\"opportunity 1\", \"opportunity 2\"],\n  \"personalization_hooks\": [\"hook 1\", \"hook 2\", \"hook 3\"],\n  \"recommended_tone\": \"consultative/direct/educational\",\n  \"key_value_proposition\": \"one sentence value prop\",\n  \"suggested_cta\": \"specific call to action\",\n  \"fit_score\": \"High/Medium/Low\",\n  \"risk_factors\": [\"risk 1\", \"risk 2\"],\n  \"one_liner_insight\": \"A compelling one-sentence insight about this company that could open an email\"\n}\n\nReturn ONLY valid JSON with no additional text or markdown formatting.",
        "options": {
          "systemMessage": "=You are an expert B2B sales research analyst specializing in identifying business pain points, growth opportunities, and personalized outreach strategies. Your goal is to analyze company data and provide actionable insights that sales teams can use to craft highly personalized cold emails."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "4e8718ee-a06c-4f6f-b1df-73ab9e5e2116",
      "name": "Generate Personalized Email",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -400,
        1216
      ],
      "parameters": {
        "text": "=Write a personalized cold email using the following information:\n\nLEAD INFORMATION:\n---\nContact Name: {{ $('Loop Over Leads').first().json['Contact Name'] }}\nEmail: {{ $('Loop Over Leads').first().json.Email }}\nCompany: {{ $('Loop Over Leads').first().json['Company Name'] }}\n---\n\nRESEARCH INSIGHTS:\n---\nKey Insight: {{ $json.output.one_liner_insight }}\n\nPain Points Identified:\n{{ $json.output.pain_points.map((point, i) => `${i + 1}. ${point}`).join('\\n') }}\nGrowth Opportunities:\n{{ $json.output.growth_opportunities.map((opp, i) => `${i + 1}. ${opp}`).join('\\n') }}\n\nPersonalization Hooks:\n{{ $json.output.personalization_hooks.map((hook, i) => `- ${hook}`).join('\\n') }}\n\nRecommended Tone: {{ $json.output.recommended_tone }}\nValue Proposition: {{ $json.output.key_value_proposition }}\nSuggested CTA: {{ $json.output.suggested_cta }}\nFit Score: {{ $json.output.fit_score }}\n---\n\nEMAIL REQUIREMENTS:\n1. Subject line should be curiosity-driven and reference something specific about their company (max 8 words)\n2. Opening line must use one of the personalization hooks to show you've done research\n3. Reference ONE specific pain point (the most relevant one) that resonates with their situation\n4. Connect that pain point to a tangible outcome or result (use numbers/data if possible)\n5. Keep the value proposition clear but not salesy - focus on their benefit, not your product features\n6. Include the suggested CTA naturally without being pushy\n7. Close with a low-friction ask that respects their time\n8. Total length: 120-150 words maximum (excluding subject line)\n9. Tone: Professional but conversational, consultative not salesy\n10. Sign off as: \"Best regards, [Your Name]\"\n\nAVOID:\n\u274c Generic phrases like \"I hope this email finds you well\"\n\u274c Talking about yourself or your company too much\n\u274c Multiple questions in one email\n\u274c Aggressive sales language or hype\n\u274c Long paragraphs (keep to 2-3 sentences max per paragraph)\n\u274c Mentioning pricing or packages\n\nFORMAT YOUR RESPONSE AS JSON:\n{\n  \"subject_line\": \"Your subject line here\",\n  \"email_body\": \"Complete email body text here with proper line breaks\",\n  \"key_personalization_used\": \"Which specific hook or insight you emphasized\",\n  \"primary_pain_point_addressed\": \"The main pain point you focused on\"\n}\n\nReturn ONLY valid JSON with no additional text, markdown formatting, or code blocks.",
        "options": {
          "systemMessage": "=You are an expert B2B cold email copywriter specializing in personalized, high-converting sales outreach. Your emails are concise (under 150 words), consultative, and focused on providing immediate value. You avoid generic templates and instead craft messages that demonstrate genuine research and understanding of the prospect's business. Your goal is to spark curiosity and secure a meeting, not to sell immediately."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "fdbb9b2d-ab5d-4c61-81e8-3b6a1330f6f9",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -400,
        1376
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "4a307bf9-bad9-4e54-b776-bf1d93df5fcb",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -208,
        1376
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"subject_line\": \"Your subject line here\",\n  \"email_body\": \"Complete email body text here with proper line breaks\",\n  \"key_personalization_used\": \"Which specific hook or insight you emphasized\",\n  \"primary_pain_point_addressed\": \"The main pain point you focused on\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "2e9e2d23-c0a6-40c3-9b09-64b7e17b45de",
      "name": "Format Results",
      "type": "n8n-nodes-base.code",
      "position": [
        128,
        1264
      ],
      "parameters": {
        "jsCode": "const emailData = $input.first().json.output;\nconst researchData = $('Company Research AI').first().json.output;\nconst leadData = $('Loop Over Leads').first().json;\n\n// Create Gmail compose link\nconst subject = encodeURIComponent(emailData.subject_line);\nconst body = encodeURIComponent(emailData.email_body);\nconst gmailLink = `https://mail.google.com/mail/?view=cm&fs=1&to=${leadData.Email}&su=${subject}&body=${body}`;\n\nreturn {\n  'Website Domain': leadData['Website Domain'],\n  'Company Name': leadData['Company Name'],\n  'Contact Name': leadData['Contact Name'],\n  'Email': leadData.Email,\n  'Industry': leadData.Industry,\n  'Research Status': 'Completed',\n  'Pain Points': researchData.pain_points.join('; '),\n  'Key Insight': researchData.one_liner_insight,\n  'Email Subject': emailData.subject_line,\n  'Email Body': emailData.email_body,\n  'Send Email Link': gmailLink,\n  'Generated Date': new Date().toISOString().split('T')[0],\n  'Sent Status': 'Not Sent'\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "97c391fa-48a5-450a-8cbd-6608a9dc8159",
      "name": "Update Row Status",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        208,
        832
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $('Loop Over Leads').first().json.Email }}",
            "Research Status": "Pending"
          },
          "schema": [
            {
              "id": "Website Domain",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Website Domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Company Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Contact Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Industry",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Industry",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Research Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Research Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pain Points",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Pain Points",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Key Insight",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Key Insight",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Subject",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Email Subject",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Body",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Email Body",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Send Email Link",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Send Email Link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Generated Date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Generated Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sent Status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Sent Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1626340606,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_YOUR_AWS_SECRET_KEY_HERE#gid=1626340606",
          "cachedResultName": "AI-Powered Lead Research & Personalized Email Generation with Groq & Google Sheets"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1qUir1c-_ScMnoYVoQ0W41nsv5IpLW6rjK8HUNqvNnAg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_YOUR_AWS_SECRET_KEY_HERE?usp=drivesdk",
          "cachedResultName": "example"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "b17dc3a2-e691-4498-addc-896c6b597b2a",
      "name": "End",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -160,
        672
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "114bd988-c8f8-465a-b339-5b30fa08c594",
      "name": "Start",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -912,
        800
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3efd1590-66f3-4628-af64-db9d3ed7593a",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        704,
        1328
      ],
      "parameters": {
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "13a9ed8c-80e5-476c-9761-501100802458",
      "name": "Filter",
      "type": "n8n-nodes-base.filter",
      "position": [
        -528,
        800
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "feb448b1-89cd-4252-b8c6-b4b753475a27",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json['Research Status'] }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c1a9241a-c1e1-4100-8f99-c299f2cf02a6",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -976,
        544
      ],
      "parameters": {
        "color": 7,
        "width": 992,
        "height": 464,
        "content": "# Step 1: Data Input & Filtering\n\nWhat happens here:\n- Reads all leads from Google Sheets\n- Filters out already-processed leads\n- Prepares leads for sequential batch processing"
      },
      "typeVersion": 1
    },
    {
      "id": "c9baf228-d7a0-426a-8bd5-05749cba9530",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        32,
        544
      ],
      "parameters": {
        "color": 4,
        "width": 992,
        "height": 464,
        "content": "## Step 2: Company Data Enrichment\n\nWhat happens here:\n- Updates status to \"Pending\" in Google Sheets\n- Searches Sona database for company information\n- Smart matching algorithm finds best company match\n- Retrieves: industry, tech stack, revenue, employee count, social links"
      },
      "typeVersion": 1
    },
    {
      "id": "0e88ebb9-9002-4b61-a97d-70357e57bcf4",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -976,
        1024
      ],
      "parameters": {
        "color": 2,
        "width": 480,
        "height": 480,
        "content": "## Step 3: AI Company Research & Analysis\n\nWhat happens here:\n- Analyzes company data using GPT-4.1-mini\n- Identifies pain points, growth opportunities, and personalization hooks\n- Determines fit score and generates one-liner insight"
      },
      "typeVersion": 1
    },
    {
      "id": "5927161b-1c06-4ccc-aa6a-937237f27032",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -480,
        1024
      ],
      "parameters": {
        "color": 3,
        "width": 496,
        "height": 480,
        "content": "## Step 4: Personalized Email Generation\n\nWhat happens here:\n- Crafts personalized cold email using research insights\n- Creates subject line (max 8 words) and email body (120-150 words)\n- Focuses on one main pain point with tangible outcomes"
      },
      "typeVersion": 1
    },
    {
      "id": "3cb44595-3d38-41b8-bddf-9fb2c04327d9",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        32,
        1024
      ],
      "parameters": {
        "color": 5,
        "width": 992,
        "height": 480,
        "content": "## Step 5: Data Output & Sync to Google Sheets\n\nWhat happens here:\n- Formats all research and email data\n- Creates Gmail compose link with pre-filled content\n- Updates sheet with results and sets status to \"Completed\"\n- Waits 2 seconds before processing next lead"
      },
      "typeVersion": 1
    },
    {
      "id": "184b5dd4-8a56-4ba4-9de3-db053864c1cb",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1664,
        528
      ],
      "parameters": {
        "width": 672,
        "height": 1296,
        "content": "# AI-Powered Lead Research & Personalized Email Generation\n\n## \u2705 Setup Requirements\n\n### 1. Google Sheets Setup\nCreate a sheet with these columns:\n- `Website Domain`, `Company Name`, `Contact Name`, `Email`, `Industry`\n- `Research Status` (leave empty for new leads)\n- Auto-populated: `Pain Points`, `Key Insight`, `Email Subject`, `Email Body`, `Send Email Link`, `Generated Date`, `Sent Status`\n\n### 2. Sona API Key\n- Get your key from [sonalabs.com](https://sonalabs.com)\n- Provides company data: industry, tech stack, revenue, employees, social profiles\n- Add to n8n HTTP Request node header: `x-api-key: YOUR_KEY`\n\n### 3. OpenAI API Key\n- Get from [platform.openai.com](https://platform.openai.com)\n- Uses GPT-4.1-mini for company research and email generation\n- Add OpenAI credentials in n8n\n\n### 4. Google Sheets API\n- Enable in Google Cloud Console\n- Set up OAuth2 with spreadsheets permission\n- Add your spreadsheet ID to workflow\n\n---\n\n## \ud83c\udfaf How It Works\n\n- **Step 1:** Reads unprocessed leads from Google Sheets (empty \"Research Status\")\n\n- **Step 2:** Searches Sona database for company intel using 5-tier smart matching algorithm\n\n- **Step 3:** GPT-4.1-mini analyzes data to identify pain points, growth opportunities, and personalization hooks\n\n- **Step 4:** AI generates 120-150 word personalized email with curiosity-driven subject line (max 8 words)\n\n- **Step 5:** Updates sheet with research, email copy, and Gmail compose link. Waits 2 seconds, then loops to next lead\n\n---\n\n## \ud83d\udcca Output\n\n#### **Result:** Enriched Google Sheet with AI-researched pain points, personalized emails, and one-click Gmail send links for each lead.\n\n#### **Processing Time:** 30-60 seconds per lead\n\n---"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "1220c546-baca-4bae-a971-5c1c3d006d7e",
  "connections": {
    "Code": {
      "main": [
        [
          {
            "node": "Company Research AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Loop Over Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start": {
      "main": [
        [
          {
            "node": "Read Leads from Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter": {
      "main": [
        [
          {
            "node": "Loop Over Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Results": {
      "main": [
        [
          {
            "node": "Update Sheet with Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Leads": {
      "main": [
        [
          {
            "node": "End",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Row Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Company Research AI",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Update Row Status": {
      "main": [
        [
          {
            "node": "Sona Company Search",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Personalized Email",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Company Research AI": {
      "main": [
        [
          {
            "node": "Generate Personalized Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sona Company Search": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Company Research AI",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "Generate Personalized Email",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Update Sheet with Results": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Personalized Email": {
      "main": [
        [
          {
            "node": "Format Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Leads from Google Sheets": {
      "main": [
        [
          {
            "node": "Filter",
            "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

Automatically research B2B leads and generate personalized outreach emails by reading prospects from Google Sheets, enriching with company data from Sona Enrich, analyzing insights with AI, and creating custom emails — so you can scale personalized outreach to target accounts.

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

🎯 Create viral TikToks, Shorts, Reels, podcasts, and ASMR videos in minutes — all on autopilot.

OpenAI, HTTP Request, Form Trigger +7
AI & RAG

Generate AI viral videos with NanoBanana & VEO3, shared on socials via Blotato 2. Uses @blotato/n8n-nodes-blotato, googleSheets, lmChatOpenAi, toolThink. Event-driven trigger; 94 nodes.

@Blotato/N8N Nodes Blotato, Google Sheets, OpenAI Chat +9
AI & RAG

This template is designed for marketers, content creators, and e-commerce brands who want to automate the creation of professional ad videos at scale. It’s ideal for teams looking to generate consiste

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

Digistars - Scrape & Crawl. Uses httpRequest, n8n-nodes-firecrawl-scraper, googleSheets, lmChatOpenAi. Event-driven trigger; 63 nodes.

HTTP Request, N8N Nodes Firecrawl Scraper, Google Sheets +5
AI & RAG

This comprehensive n8n workflow automates the entire Meta (Facebook/Instagram) advertising process, from asset analysis to ad creation. It combines AI-powered content analysis with automated ad deploy

Facebook Graph Api, HTTP Request, Google Drive +5