Skip to main content
Skip to article

#n8n: Build a WhatsApp Lead Pipeline with Auto-Qualify

16 min read

Two PM. "Interested in your product." Six PM. You see it. Too late. They already bought from a competitor who replied in 5 minutes.

You're not slow. Your process is slow.

Manual WhatsApp lead handling: check messages → copy to CRM → type reply. Every hour of delay = 10% conversion drop. Twenty-four hours? Lead is dead.

The fix: n8n webhook automation that captures every WhatsApp inquiry via MoltFlow webhooks, qualifies with keyword matching or AI (GPT-4o "interested|pricing|demo"), pushes to CRM (Google Sheets, HubSpot, Salesforce—500+ integrations), sends personalized auto-reply in under 10 seconds, notifies sales via Slack/email.

Zero backend server. Zero custom code. Connect n8n to MoltFlow, import the workflow template from this guide, configure your CRM credentials. Runs forever.

What You're Building

By the end of this guide, you'll have a lead pipeline that:

  1. Captures every WhatsApp message in real-time
  2. Parses contact info (phone, name, message content)
  3. Qualifies the lead using keyword matching or AI
  4. Adds qualified leads to your CRM automatically
  5. Responds with a personalized auto-reply within seconds
  6. Notifies your sales team via Slack or email

The entire flow takes under 10 seconds. Your leads get instant confirmation. Your sales team gets hot leads delivered to their inbox. You stop losing deals to slow follow-up.

Why WhatsApp Leads Are Different

Email leads are cold. Someone filled out a form, maybe weeks ago. They're browsing 5 other options.

WhatsApp leads are hot. They're on their phone right now, actively looking for a solution. They want an answer immediately.

The difference in conversion rate is massive — 30-40% for WhatsApp vs 2-5% for email forms. But only if you respond fast.

That's why automation matters. You can't compete with "respond within 5 minutes" by hand. You need a system.

Prerequisites

Before you start building, make sure you have:

  • MoltFlow account with an active WhatsApp session (sign up here)
  • n8n instance (self-hosted or n8n.cloud) — installation guide
  • MoltFlow API key (Dashboard → Settings → API Keys)
  • CRM or spreadsheet to store leads (we'll use Google Sheets for this example)

If you haven't connected MoltFlow to n8n yet, start with Connect MoltFlow to n8n: WhatsApp Automation Without Code — it covers the authentication setup.

Step 1: Set Up MoltFlow Webhook

First, you need MoltFlow to forward incoming WhatsApp messages to your n8n workflow.

Create the Webhook in MoltFlow

  1. Go to MoltFlow Dashboard → Webhooks
  2. Click "Create Webhook"
  3. URL: Your n8n webhook endpoint (we'll create this in the next step)
  4. Events: Select message (incoming messages only)
  5. Sessions: Choose the session(s) to monitor (or leave blank for all sessions)

Save the webhook. You'll activate it after setting up the n8n workflow.

Get Your n8n Webhook URL

In n8n, create a new workflow and add a Webhook node.

Settings:

  • HTTP Method: POST
  • Path: whatsapp-leads (or whatever you want)
  • Response Mode: Last Node

Activate the workflow (even though it's not complete yet). n8n will give you a webhook URL like:

text
https://your-n8n.com/webhook/whatsapp-leads

Copy this URL and paste it into the MoltFlow webhook configuration from step 1.

Step 2: Parse Incoming Message

When MoltFlow forwards a message to your webhook, it sends JSON data like this:

json
{
  "event": "message",
  "session": "my-session",
  "payload": {
    "id": "msg_abc123",
    "from": "[email protected]",
    "fromName": "John Doe",
    "body": "Hi, I'm interested in your pricing for the Business plan",
    "timestamp": "2026-01-30T14:35:00Z",
    "type": "chat"
  }
}

You need to extract the useful fields and format them for your CRM.

Add a Set Node

After the Webhook node, add a Set node named "Parse Lead Data".

Configure these fields:

Field NameValueExpression
phone={{ $json.payload.from.split('@')[0] }}Extracts phone number
name={{ $json.payload.fromName || 'Unknown' }}Uses contact name or fallback
message={{ $json.payload.body }}The actual message text
timestamp={{ $json.payload.timestamp }}When message arrived
session={{ $json.session }}Which WhatsApp session
messageId={{ $json.payload.id }}Unique message ID

The phone expression removes the @c.us suffix so you get a clean phone number like 16505551234.

Step 3: Qualify the Lead

Not every WhatsApp message is a lead. Someone might send "thanks" or "ok" — you don't want those in your CRM.

You need qualification logic. There are two approaches: keyword matching (simple) or AI analysis (advanced).

Option A: Keyword Matching (Recommended for Most)

Use an If node to check for qualifying keywords.

Condition:

javascript
{{ $json.message.toLowerCase().match(/(interested|pricing|demo|quote|buy|purchase|sign up|trial)/gi) }}

This regular expression checks if the message contains common buying-intent keywords. Adjust the keywords based on your business.

What happens:

  • True path: Lead is qualified → continue to CRM
  • False path: Not a lead → send polite response and end

Option B: AI Qualification (Advanced)

For more sophisticated qualification, use n8n's Code node with an AI API call.

Here's an example using OpenAI to analyze message intent:

javascript
// Get message from previous node
const message = $input.first().json.message;

// Call OpenAI API (you'll need OpenAI credentials in n8n)
const response = await fetch('https://api.openai.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_OPENAI_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model: 'gpt-4',
    messages: [
      {
        role: 'system',
        content: 'You are a lead qualification assistant. Analyze WhatsApp messages and determine if they indicate buying intent. Return only "qualified" or "unqualified".'
      },
      {
        role: 'user',
        content: message
      }
    ],
    max_tokens: 10
  })
});

const data = await response.json();
const qualification = data.choices[0].message.content.toLowerCase();

return {
  isQualified: qualification.includes('qualified'),
  aiAnalysis: qualification
};

Connect this Code node output to an If node that checks {{ $json.isQualified }}.

For this guide, we'll stick with keyword matching — it's faster, cheaper, and works 90% of the time.

Step 4: Add Lead to CRM

Now that you've got a qualified lead, push it to your CRM.

I'll show you Google Sheets (simplest), but the same pattern works for HubSpot, Salesforce, Airtable, or any CRM with an n8n integration.

Set Up Google Sheets

Create a new Google Sheet with these columns:

TimestampPhoneNameMessageSessionStatusMessage ID

Share the sheet with your n8n Google service account (you'll set this up in n8n credentials).

Add Google Sheets Node

After the If node's true path (qualified leads), add a Google Sheets node.

Operation: Append Row

Spreadsheet ID: Your Google Sheet ID (from the URL)

Sheet Name: Sheet1 (or whatever you named it)

Columns to Send:

  • Timestamp: ={{ $json.timestamp }}
  • Phone: ={{ $json.phone }}
  • Name: ={{ $json.name }}
  • Message: ={{ $json.message }}
  • Session: ={{ $json.session }}
  • Status: new
  • Message ID: ={{ $json.messageId }}

Now every qualified lead gets logged automatically. Your sales team can access the sheet in real-time.

Alternative: CRM Integration

If you're using HubSpot, add a HubSpot node instead:

Resource: Contact

Operation: Create or Update

Email: ={{ $json.phone }}@whatsapp.placeholder (HubSpot requires email; use phone as identifier)

Properties:

  • First Name: ={{ $json.name }}
  • Phone: ={{ $json.phone }}
  • Lead Source: WhatsApp
  • Lead Status: New

For Salesforce or other CRMs, use their respective n8n nodes. The pattern is the same: map your parsed fields to CRM fields.

Step 5: Send Auto-Reply

Your lead is in the CRM. Now acknowledge their message so they don't wander off.

Add HTTP Request Node

After the Google Sheets node, add an HTTP Request node to send a WhatsApp message via MoltFlow.

Authentication: Header Auth

  • Name: X-API-Key
  • Value: Your MoltFlow API key

Request:

  • Method: POST
  • URL: https://apiv2.waiflow.app/api/v2/sessions/{{ $json.session }}/messages
  • Body (JSON):
json
{
  "chatId": "={{ $json.phone }}@c.us",
  "text": "Hi {{ $json.name }}! 👋\n\nThanks for reaching out. I got your message about our pricing. Our team will review your inquiry and get back to you within 2 hours.\n\nIn the meantime, check out our plans here: https://molt.waiflow.app/pricing\n\nQuestions? Just reply to this message!"
}

Personalization tips:

  • Use {{ $json.name }} to address them by name
  • Reference specific keywords from their message: {{ $json.message }}
  • Include a clear next step (link to pricing, calendar booking, etc.)
  • Set expectations for response time (2 hours, 24 hours, etc.)

Handle Non-Qualified Messages

What about messages that didn't pass qualification?

After the If node's false path, add another HTTP Request node with a polite generic response:

json
{
  "chatId": "={{ $json.phone }}@c.us",
  "text": "Thanks for your message! If you need help, please visit https://molt.waiflow.app/support or reply with a specific question."
}

This keeps you from ignoring non-sales messages entirely.

Step 6: Notify Your Sales Team

Leads in a spreadsheet don't get followed up. You need to notify your team immediately.

Option 1: Slack Notification

Add a Slack node after the Google Sheets node.

Channel: #sales (or wherever your team hangs out)

Message:

text
🔥 New WhatsApp Lead!

*Name:* {{ $json.name }}
*Phone:* {{ $json.phone }}
*Message:* {{ $json.message }}
*Time:* {{ $json.timestamp }}

Auto-reply sent. Follow up within 2 hours!

[View in CRM](link-to-your-crm)

Option 2: Email Notification

If your team prefers email, use the Send Email node instead.

To: [email protected]

Subject: New WhatsApp Lead: {{ $json.name }}

Body:

html
<h2>New Lead from WhatsApp</h2>

<p><strong>Name:</strong> {{ $json.name }}<br>
<strong>Phone:</strong> {{ $json.phone }}<br>
<strong>Message:</strong> {{ $json.message }}<br>
<strong>Received:</strong> {{ $json.timestamp }}</p>

<p>Auto-reply sent. Please follow up within 2 hours for best conversion rate.</p>

Complete Workflow JSON

Here's the full n8n workflow you can import. Copy this JSON and paste it into n8n's import function:

json
{
  "name": "WhatsApp Lead Pipeline - MoltFlow",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "whatsapp-leads",
        "responseMode": "lastNode",
        "options": {}
      },
      "name": "Webhook - Incoming WhatsApp",
      "type": "n8n-nodes-base.webhook",
      "position": [250, 300],
      "webhookId": "your-webhook-id"
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "phone",
              "value": "={{ $json.payload.from.split('@')[0] }}"
            },
            {
              "name": "name",
              "value": "={{ $json.payload.fromName || 'Unknown' }}"
            },
            {
              "name": "message",
              "value": "={{ $json.payload.body }}"
            },
            {
              "name": "timestamp",
              "value": "={{ $json.payload.timestamp }}"
            },
            {
              "name": "session",
              "value": "={{ $json.session }}"
            },
            {
              "name": "messageId",
              "value": "={{ $json.payload.id }}"
            }
          ]
        }
      },
      "name": "Parse Lead Data",
      "type": "n8n-nodes-base.set",
      "position": [450, 300]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.message.toLowerCase() }}",
              "operation": "regex",
              "value2": "(interested|pricing|demo|quote|buy|purchase|sign up|trial)"
            }
          ]
        }
      },
      "name": "Qualify Lead",
      "type": "n8n-nodes-base.if",
      "position": [650, 300]
    },
    {
      "parameters": {
        "operation": "append",
        "sheetId": "YOUR_SHEET_ID",
        "range": "Sheet1",
        "options": {
          "values": [
            "={{ $json.timestamp }}",
            "={{ $json.phone }}",
            "={{ $json.name }}",
            "={{ $json.message }}",
            "={{ $json.session }}",
            "new",
            "={{ $json.messageId }}"
          ]
        }
      },
      "name": "Add to Google Sheets CRM",
      "type": "n8n-nodes-base.googleSheets",
      "position": [850, 250],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "https://apiv2.waiflow.app/api/v2/sessions/={{ $json.session }}/messages",
        "options": {
          "bodyContentType": "json"
        },
        "bodyParametersJson": "={\n  \"chatId\": \"{{ $json.phone }}@c.us\",\n  \"text\": \"Hi {{ $json.name }}! 👋\\n\\nThanks for reaching out. I got your message about our pricing. Our team will review your inquiry and get back to you within 2 hours.\\n\\nIn the meantime, check out our plans here: https://molt.waiflow.app/pricing\\n\\nQuestions? Just reply to this message!\"\n}"
      },
      "name": "Send Auto-Reply (Qualified)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [1050, 250],
      "credentials": {
        "httpHeaderAuth": {
          "name": "MoltFlow API"
        }
      }
    },
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "https://apiv2.waiflow.app/api/v2/sessions/={{ $json.session }}/messages",
        "options": {
          "bodyContentType": "json"
        },
        "bodyParametersJson": "={\n  \"chatId\": \"{{ $json.phone }}@c.us\",\n  \"text\": \"Thanks for your message! If you need help, please visit https://molt.waiflow.app/support or reply with a specific question.\"\n}"
      },
      "name": "Send Auto-Reply (Not Qualified)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [850, 350],
      "credentials": {
        "httpHeaderAuth": {
          "name": "MoltFlow API"
        }
      }
    },
    {
      "parameters": {
        "channel": "#sales",
        "text": "🔥 New WhatsApp Lead!\n\n*Name:* {{ $json.name }}\n*Phone:* {{ $json.phone }}\n*Message:* {{ $json.message }}\n*Time:* {{ $json.timestamp }}\n\nAuto-reply sent. Follow up within 2 hours!",
        "otherOptions": {}
      },
      "name": "Notify Sales Team",
      "type": "n8n-nodes-base.slack",
      "position": [1050, 150],
      "credentials": {
        "slackApi": {
          "name": "Slack account"
        }
      }
    }
  ],
  "connections": {
    "Webhook - Incoming WhatsApp": {
      "main": [
        [
          {
            "node": "Parse Lead Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Lead Data": {
      "main": [
        [
          {
            "node": "Qualify Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Qualify Lead": {
      "main": [
        [
          {
            "node": "Add to Google Sheets CRM",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Auto-Reply (Not Qualified)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add to Google Sheets CRM": {
      "main": [
        [
          {
            "node": "Send Auto-Reply (Qualified)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Notify Sales Team",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Before importing:

  1. Replace YOUR_SHEET_ID with your actual Google Sheet ID
  2. Make sure you've added MoltFlow API credentials to n8n as "MoltFlow API"
  3. Configure Slack or email credentials if using notifications

Testing Your Pipeline

Before going live, test the entire flow:

1. Test with curl

Send a fake webhook payload to your n8n webhook:

bash
curl -X POST https://your-n8n.com/webhook/whatsapp-leads \
  -H "Content-Type: application/json" \
  -d '{
    "event": "message",
    "session": "my-session",
    "payload": {
      "id": "msg_test123",
      "from": "[email protected]",
      "fromName": "Test Lead",
      "body": "Hi, I am interested in your pricing",
      "timestamp": "2026-01-30T15:00:00Z",
      "type": "chat"
    }
  }'

Expected results:

  • Lead appears in Google Sheets
  • Auto-reply sent to test phone number
  • Slack notification (or email) received
  • n8n execution shows all green checkmarks

2. Test with Real WhatsApp Message

Send a test message to your MoltFlow WhatsApp number containing a qualifying keyword like "pricing" or "demo".

Check:

  • Lead captured in spreadsheet
  • Auto-reply received on WhatsApp
  • Sales team notified
  • Lead marked as "new" status

3. Test Non-Qualified Message

Send a message like "thanks" or "ok" that shouldn't qualify.

Check:

  • Lead NOT added to spreadsheet
  • Generic auto-reply received
  • No sales notification sent

Advanced: AI Lead Enrichment

Once you've got the basic pipeline working, you can enhance it with AI-powered lead enrichment.

Add Lead Scoring

Use a Code node after qualification to score leads based on message content:

javascript
const message = $input.first().json.message.toLowerCase();
let score = 0;

// High-intent keywords
if (message.includes('buy') || message.includes('purchase')) score += 50;
if (message.includes('demo') || message.includes('trial')) score += 40;
if (message.includes('pricing') || message.includes('quote')) score += 30;
if (message.includes('interested')) score += 20;

// Urgency indicators
if (message.includes('asap') || message.includes('today')) score += 20;
if (message.includes('soon') || message.includes('this week')) score += 10;

// Question marks indicate engagement
const questions = (message.match(/\?/g) || []).length;
score += questions * 5;

return {
  leadScore: score,
  priority: score >= 60 ? 'high' : score >= 30 ? 'medium' : 'low'
};

Add the leadScore and priority fields to your CRM. Your sales team can prioritize high-scoring leads.

Extract Contact Info with AI

Use OpenAI's function calling to extract structured data from messages:

javascript
const message = $input.first().json.message;

const response = await fetch('https://api.openai.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_OPENAI_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model: 'gpt-4',
    messages: [
      {
        role: 'user',
        content: `Extract contact information and intent from this WhatsApp message: "${message}"`
      }
    ],
    functions: [
      {
        name: 'extractLeadInfo',
        description: 'Extract lead information from message',
        parameters: {
          type: 'object',
          properties: {
            email: { type: 'string', description: 'Email address if mentioned' },
            company: { type: 'string', description: 'Company name if mentioned' },
            intent: { type: 'string', enum: ['demo', 'pricing', 'support', 'general'] },
            urgency: { type: 'string', enum: ['high', 'medium', 'low'] }
          }
        }
      }
    ],
    function_call: { name: 'extractLeadInfo' }
  })
});

const data = await response.json();
const extracted = JSON.parse(data.choices[0].message.function_call.arguments);

return extracted;

Now you've got email, company name, intent, and urgency automatically extracted. Push all of this to your CRM for richer lead profiles.

Troubleshooting Common Issues

Leads Not Appearing in Spreadsheet

Check:

  • Google Sheets credentials properly configured in n8n
  • Sheet ID is correct (from URL: docs.google.com/spreadsheets/d/{SHEET_ID}/edit)
  • Service account has edit access to the sheet
  • Column names match exactly (case-sensitive)

Debug: Run the workflow manually in n8n and check the Google Sheets node output for errors.

Auto-Reply Not Sending

Check:

  • MoltFlow API key is valid (test in Dashboard → API Keys)
  • Session name in URL matches your actual session: /sessions/{YOUR_SESSION}/messages
  • Session status is "WORKING" (not "STOPPED" or "QR_CODE")
  • chatId format is correct: {phone}@c.us for individuals

Debug: Check the HTTP Request node response. MoltFlow returns error details in the response body.

Duplicate Leads

Problem: Same lead appears multiple times if they send multiple messages.

Solution: Add deduplication logic with an If node that checks if phone number already exists in your CRM.

For Google Sheets, use a Lookup operation before appending:

javascript
// In Code node
const phone = $input.first().json.phone;
const sheet = $node["Add to Google Sheets CRM"].json;

// Check if phone exists in column B (Phone column)
const exists = sheet.some(row => row[1] === phone);

return { isDuplicate: exists };

Only append if {{ !$json.isDuplicate }}.

Webhook Not Receiving Messages

Check:

  • Webhook is activated in MoltFlow Dashboard
  • Webhook URL is correct (test with curl)
  • n8n workflow is active (not just saved)
  • Firewall allows incoming HTTPS on your n8n instance

Debug: Check MoltFlow Dashboard → Webhooks → Deliveries. You'll see HTTP status codes for each delivery attempt.

What's Next

You've built a complete lead pipeline. Every WhatsApp message gets captured, qualified, logged, and responded to automatically.

Connect MoltFlow to n8n first, then set up webhooks for lead capture, and use this guide's workflow template for qualification logic. Extend with REST API calls for advanced CRM integrations.

Ready to implement this? Follow our step-by-step guide: Connect MoltFlow to n8n for the foundational webhook setup, then use this guide's workflow template for lead pipeline automation.

Related workflows:

Advanced features:

  • Add appointment booking integration (Calendly, Google Calendar)
  • Build a follow-up sequence that re-engages cold leads after 48 hours
  • Integrate with your email marketing tool (Mailchimp, ConvertKit) for nurture sequences
  • Add sentiment analysis to prioritize angry or urgent messages

MoltFlow features to explore:

Ready to capture every lead? Start your free MoltFlow trial and import this workflow in 5 minutes.

Conclusion

Lead pipelines shouldn't require a development team.

With n8n + MoltFlow, you get the same automation that enterprise companies pay tens of thousands for — except you own it, you control it, and you can change it whenever you want.

Start with this workflow. Customize the qualification logic for your business. Adjust the auto-reply tone. Connect your actual CRM instead of Google Sheets.

Within a week, you'll wonder how you ever managed leads manually.

Questions? Drop them in the MoltFlow Discord. Want to see more n8n workflows? Check out the full blog.

Now stop losing leads. Automate your pipeline.

> Try MoltFlow Free — 100 messages/month

$ curl https://molt.waiflow.app/pricing

bash-5.2$ echo "End of post."_