Build your Industrial Grade n8n WhatsApp Lead Agent: Beginner Friendly

Fetaured image for industrial grade whatsapp lead agent
workflow screenshot

The word “n8n Automation” is trending since last year (to be precise), people are building countless ‘n8n workflow templates’ to automate their repetative tasks, So today I’m gonna teach you how to build a WhatsApp lead agent using meta whatsapp cloud API, slack, postgresql database. I will mention the features & functions of this workflow in later section and let me remind you that this blog is for those who don’t just want to copy the workflow but understand it too, I have uploaded the n8n workflow template in JSON file at the end of this blog, you can just download it and use it but i prefer you to build this workflow node by node yourself for self-improvment (instructions provided).

Well hello guy’s my name is…(i prefer you call me by my nickname) ‘axiomcompute’ & let’s start this interesting session,

Industrial Grade WhatsApp Lead Agent: Features

The features of this lead Agentic AI is as follows:-

Agentic AI

Intelligent systems that autonomously plan, make decisions, and take action to achieve specific goals with minimal human supervision

  1. Real Time Whatsapp Message Handling:- This one run 24/7 without human intervention, recieve messages almost instantly.
  2. Data Extraction:- It extract phone number, name, message string automatically.
  3. Phone Number Formater:- Since this workflow is made specifically for india, that’s why i’ve added this which just formats the number from any format into +9198xxxxxxxx, the reason being it ensure databse consistency & prevents duplicates.
  4. Database:- I have added a real database instead of google sheets to keep things professional which stores name, number, message, category, intent, timestamp.
  5. Duplicate Lead prevention:- An important feature offcourse.
  6. Lead Classification by AI:- Future ready feature and quite usefull indeed for example, this one classify the messages belongs to sales, support, spam, product_question.
  7. Lead Intent Detection:- Yet another useful feature using AI, this one classifies the user intent to buy, info, pricing, greeting….
  8. Smart Reply Routing:- Simply put, this one reply the user’s in real time based on their intent for example let’s say you wanna enquire about pricing’s so the bot will reply you with pricings related answers not support flow.
  9. WhatsApp Template Reply:- this one is simply a template based first message.
  10. Data Logging:- This one’s quite useful too, it stores message history, user message text, AI classification results, AI intent results, each with timestamp.
  11. Bot Safety Features:- I thought this one is kinda important to prevent errors/API-draining/workflow-breakage/number-format-inconsistency.
  12. Scalable:- This on is on Enterprise level workflow template so it’s bound to be scalable.
  13. Modular Structure:- This one is designed to expand easily i.e. follow-up flows, AI memory, CRM Integration, Broadcasting, Human handover etc..

That’s it, these are the basic core foundations. Hope you enjoy the building journey with me ahead!

Industrial Grade WhatsApp Lead Agent: Basic Node knowledge

Since Im gonna explain you ‘how to build industrial grade whatsapp lead agent on n8n’ and you will be building this yourself So it’s very crucial for you to atleast have a grasp over the basic core nodes which is gonna be used in this workflow,

  • Webhook Node:- This one is the first and absolutely important node for our workflow, without it the workflow won’t start, this node is for receiving incoming WhatsApp messages from Meta Cloud API.
webhook node

E.g. The underlying algorithm should be like this, when someone send’s the message to your WhatsApp number then that number will then get pulled by WhatsApp Meta Cloud API to this node through a feature called webhook (we don’t need to delve deeper) you could think that webhook acts as bridge to transfer data from one point to another over Internet, In our case the raw data should looks like this,

{
  "entry": [{
    "changes": [{
      "value": {
        "messages": [{
          "from": "919876543210",
          "profile": { "name": "John" },
          "text": { "body": "hello" }
        }]
      }
    }]
  }]
}

as you can see this is the example skeletal structure of JSON data.

  • Code Node (formerly Function node):– It simply transform the RAW DATA in clean data (Human readable data) by using javascript code, It acts as a container in which you can write code in javascript or python to manipulate data.
javascript code node

E.g.

const body = items[0].json.entry[0].changes[0].value;
const msg = body.messages ? body.messages[0] : null;

function normalize(num) {
  if (num.startsWith('+')) return num;
  if (num.startsWith('91')) return '+' + num;
  return '+91' + num;
}

return [{
  json: {
    wa_number: normalize(msg.from),
    wa_name: msg.profile ? msg.profile.name : 'Unknown',
    wa_text: msg.text ? msg.text.body : ''
  }
}];

This code here simply acts a engine so when we input Raw Data it processes tha data & outputs that Data into a more cleaner data (precise fields) then transfers ahead.

{
  "wa_number": "+919876543210",
  "wa_name": "John",
  "wa_text": "hello"
}

This is the output of the data from 1st point, rest assured as you won’t have to deal with code’s even if you are a non-developer reading this.

  • Postgresql Node:- This is our database node which is very crucial, the leads will be stored here, updated here etc..
postgresql node
  • OpenAI Node:– This is AI Layer node which detect intent’s and classify data into different categories.
open AI node to message a model
  • HTTP Request Node:- Simply, this node is almost like an all-rounder node to talk over internet in n8n, weather you have to send, receive, post, get requests over internet this node is excellent choice beacuse of it’s flexibility. The work of this node in our workflow is to send message from your whatsapp number.
HTTP Request node

This nodes are the foundation of our workflow template.

Now we will go step-by-step over on how to build this workflow

Industrial Grade WhatsApp Lead Agent: Helping you build node by node

Its gonna be quite the long session as there are around 27 nodes, let’s get to know each node:

Node 1: Whatsapp webhook

As stated earlier, Its the entry point of entire workflow.

Node 2: Is Valid Message?

WhatsApp send many webhook events through Meta API, not just messages. So, to ensure that only messages pass through this node & is adopted to filter out these before doing any processes.

{
  "parameters": {
    "conditions": {
      "boolean": [
        {
          "value1": "={{ $json.entry && $json.entry[0].changes[0].value.messages }}",
          "value2": true
        }
      ]
    }
  },
  "name": "Is Valid Message?",
  "type": "n8n-nodes-base.if",
  "typeVersion": 1,
  "position": [460, 400]
}

In this particular Raw JSON code you can see that there are 2 values namely, value 1 & 2, the value 1 contains this expression {{$json.entry && $json.entry[0].changes[0].value.messages}} this code checks if the message’s exist in previous node’s output or not. If true then the data will flow from TRUE branch if Not the workflow will stop.

Node 3: Parse & Normalize Message

As name suggests here the messages gets normalized, the data send from Whatsapp is deeply nested an inconsistant so this node extracts relvent fields, normalize phone numbers to E.164 format (+919876543210), handle all message types, create a clean structure for downstream nodes.

{
  "wa_number": "+919876543210",
  "wa_name": "John Doe",
  "wa_id": "wamid.xxx",
  "message_text": "I want to buy your product",
  "message_type": "text",
  "media_id": null,
  "location_data": null,
  "timestamp": "2024-01-15T10:30:00Z",
  "business_phone_id": "123456789",
  "is_duplicate": false,
  "lead_id": null,
  "conversation_context": []
}

Here is the example of cleaned format output which will be fowarded to the next node.

Node 4: Find Existing lead

Before creating a new lead in Database we must check if this phone number already exists.

Internal settings,

{
  "parameters": {
    "operation": "executeQuery",
    "query": "SELECT id, wa_number, wa_name, lead_status, lead_score, lead_category, intent, conversation_count, last_message_at, assigned_to, tags, created_at FROM whatsapp_leads WHERE wa_number = $1 ORDER BY created_at DESC LIMIT 1;",
    "options": {},
    "queryParams": "={{ [$json.wa_number] }}"
  },
  "name": "Find Existing Lead",
  "type": "n8n-nodes-base.postgres",
  "typeVersion": 2.5,
  "position": [940, 300]
}

Node 5: Lead Exists?

If previous node outputs some data then lead does not exists, In this case a new record will be created. In opposite case the existing lead will be updated.

{{ $json.length > 0 }}

This value checks arrays length, is array is empty means no lead found and vice versa.

Node 6: Merge Existing Lead

If the lead already exists, this node combines the new data in existing data inside the database.

Node:7 Create New Lead

As the name suggests, this node is to fill the database with new lead’s details.

Node 8: Format New Lead

The INSERT query returns database result format. So, we need to merge it with original message data to match the structure from “Merge Existing Lead (Node 6)”.

Node 9: Merge Lead Data

This is Convergence point, for both branches (cluster of parallel nodes).

Note:- Merge node simply merge the data of two or more parallel node into one.

Node 10: Log Message

After merge every message (conversation history, audit trail, analytics, context for AI Analysis) get’s logged here.

Node 11: Get Conversation Context

This node here is before AI analysis which is to help AI node give context. Knowing previous messages helps determine: Is this a follow-up question? Has sentiment changed? What was discussed before? this node limits 5 messages (enough context without overwhelming AI).

Node 12: Build Context

Prepares AI input because raw database results needs formating for AI, So this converts structured data into readable conversation format.

Example Output,

Customer: Hi, I'm interested in your product
Agent: Hello! Thanks for reaching out. What would you like to know?
Customer: What's the pricing?
Agent: Our plans start at $99/month. Would you like details?
Customer: Yes, I want to buy the premium plan

Node 13: AI lead Analyzer

After context is built this node here which is the brain of the workflow analyzes the message and return structured classification.

Node 14: Process AI Analysis

This node processes Raw AI output which includes Parse JSON (handle errors), Calculate lead score adjustments, Determine lead temperature, Decide if human handoff needed.

Since sometimes add markdown we clean it and handle failures gracefully example output

// Intent scoring
const intentScores = {
  buy: 30,      // Highest value - ready to purchase
  demo: 20,     // High interest
  pricing: 15,  // Evaluating
  info: 5,      // Exploring
  followup: 10, // Engaged
  complaint: -5, // Negative signal
  greeting: 0,  // Neutral
  other: 0
};
scoreAdjustment += intentScores[analysis.intent] || 0;

Since “Buy” intent is 6x more valuable than “info” based on sales funnel position.

// Lead temperature
let temperature = 'cold';
if (newScore >= 70) temperature = 'hot';
else if (newScore >= 40) temperature = 'warm';

/* 0-39: Cold (needs nurturing)
40-69: Warm (showing interest)
70-100: Hot (ready to close) */

// Human handoff detection
const needsHuman = 
  analysis.sentiment === 'frustrated' ||
  analysis.category === 'support' ||
  analysis.urgency >= 4 ||
  newScore >= 80;

Human handoff detection is because Frustrated customers → Escalate immediately, Support issues → Need human touch, Urgency 4-5 → Time-sensitive, Score 80+ → High-value, don’t risk losing them.

Node 15: Update Lead Analytics

This node saves the AI insights to database, since AI analysis needs to be saved for CRM visibility, Future context, Reporting/analytics, sales team dashboard.

Node 16: Needs Human?

I thought that I should add this node for human escalation, it escalates Hot lead messages to sales team having score over 70.

If the lead is not Hot, the data flow will skip alert and go directly to routing.

Node 17: Alert Sales Team

In case TRUE from previous node- this node then becomes active and immediately notifies sales team within seconds about the Hot lead. example message in md,

### Message Structure
```
🔥 *High-Priority Lead Alert*

*Name:* John Doe
*Phone:* +919876543210
*Score:* 85/100 (hot)

*Message:* I want to buy the enterprise plan today

*Analysis:*
- Category: sales
- Intent: buy
- Urgency: 5/5
- Sentiment: positive

*Reason for escalation:* Hot lead ready to buy

Node 18: Route by Intent

After branching – It Determines response type,

  • Buy intent → Move fast
  • confirm order Pricing → Provide options
  • Demo → Schedule meeting
  • Support → Acknowledge
  • escalate Greeting → Welcome message
OutputConditionPurpose
Buy Intentintent === ‘buy’Fast track sales
Pricingintent === ‘pricing’Send pricing info
Demo Requestintent === ‘demo’Offer calender
Supportcategory === ‘support’Acknowledge issue
Greetingintent === ‘greeting’Welcome message
DefaultFallbackGeneric helpful response

Node 19: Generate Response

After Routing – This node is converging point of the 6 routes. based on intent, it selects and personalize the response template.

Node 20: Add Time Context

You must have already gussed it, this node have a context of real business hours, weekends, returning vs new customers, so its reposnses should vary.

Node 21: Send WhatsApp Reply

The core node, this node actually sends the crafted messages through API calls to WhatsApp, i have used HTTP node here for flexibilty as the real whatsapp node has visible limitations.

Node 22: Log Outbound Message

Its sole function is to log (what we replied) what we sent,

FieldValueWhy
direction‘outbound’Distinguishes from inbound
wa_message_idAPI response or generatedLinks to WhatsApp deivery tracking
response_templateTemplate nameAnalytics on which response used

Node 23: Is New Hot Lead?

Final analytics action, Hot leads that are new deserve special tracking. Existing hot leads already triggered this before.

Condition breakdown – $json.lead_temperature === ‘hot’ && !$json.is_duplicate , must be hot >= 70, must be first message (is duplicate = false).

Identifies acquisition channel effectiveness. “How many hot leads from WhatsApp this week?”

Node 24: Log Hot Lead Event

It is for event-based analytics. seperate from lead table for: time-series analysis, funnel tracking, attribution. Event data sored example,

{
  "score": 85,
  "intent": "buy",
  "category": "sales"
}

Node 25: End – Success

End of the workflow. Explicit endpoint for clear workflow visualization, execution logging, success metrics.

Why NoOp (No Operation)?

  • Does nothing, by design
  • Serves as visual endpoint
  • Can be replaced with webhook response if needed

Node 26: End – No Message

This one is similar to Node 25, celan handeling of status updates, read receipts, typing indicators.

Node 27: Error Handler

The last and crucial node, Any node failure/silent failure triggers this.

How It Works

  1. Any node fails → Triggers error workflow
  2. Error message captured
  3. Can be extended to: Send Slack alert, Log to error table, Retry logic

Final Note

I have covered all the nodes and given you a basic understanding of what each does, below i have attached the download link of the workflow in JSON format which you can simply download and import on n8n but there is a twist here i simply do not want you to have everything for free that’s why i have purposefully broken the workflow (Difficulty level — moderate) you have to fix this workflow yourself before you could use it.

Consider it as my payment.

Download the workflow from here.

Now, If you find it difficult to Re-build, you can either comment me, or contact me directly i will give you the complete working workflow template version ASAP.

Important:- I have pasted the SQL QUERY command below which will help you create Tables in Database!

-- WhatsApp Leads Table
CREATE TABLE whatsapp_leads (
    id SERIAL PRIMARY KEY,
    wa_number VARCHAR(20) NOT NULL UNIQUE,
    wa_name VARCHAR(255),
    first_message TEXT,
    message_type VARCHAR(50) DEFAULT 'text',
    
    -- Lead scoring & classification
    lead_status VARCHAR(50) DEFAULT 'new',
    lead_score INTEGER DEFAULT 10,
    lead_temperature VARCHAR(20) DEFAULT 'cold',
    lead_category VARCHAR(50),
    intent VARCHAR(50),
    sentiment VARCHAR(20),
    urgency INTEGER DEFAULT 2,
    keywords JSONB DEFAULT '[]',
    
    -- Engagement tracking
    conversation_count INTEGER DEFAULT 0,
    last_message_at TIMESTAMP WITH TIME ZONE,
    first_response_at TIMESTAMP WITH TIME ZONE,
    
    -- Assignment
    assigned_to VARCHAR(255),
    tags TEXT[],
    notes TEXT,
    
    -- Source tracking
    source_channel VARCHAR(50) DEFAULT 'whatsapp',
    source_campaign VARCHAR(255),
    
    -- Timestamps
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    converted_at TIMESTAMP WITH TIME ZONE
);

-- Message History Table
CREATE TABLE whatsapp_messages (
    id SERIAL PRIMARY KEY,
    lead_id INTEGER REFERENCES whatsapp_leads(id),
    wa_message_id VARCHAR(255),
    direction VARCHAR(10) NOT NULL, -- 'inbound' or 'outbound'
    message_type VARCHAR(50) DEFAULT 'text',
    content TEXT,
    media_id VARCHAR(255),
    location_data JSONB,
    response_template VARCHAR(100),
    delivered_at TIMESTAMP WITH TIME ZONE,
    read_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Lead Events Table (for analytics)
CREATE TABLE lead_events (
    id SERIAL PRIMARY KEY,
    lead_id INTEGER REFERENCES whatsapp_leads(id),
    event_type VARCHAR(100) NOT NULL,
    event_data JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Indexes for performance
CREATE INDEX idx_leads_wa_number ON whatsapp_leads(wa_number);
CREATE INDEX idx_leads_status ON whatsapp_leads(lead_status);
CREATE INDEX idx_leads_temperature ON whatsapp_leads(lead_temperature);
CREATE INDEX idx_leads_score ON whatsapp_leads(lead_score DESC);
CREATE INDEX idx_messages_lead_id ON whatsapp_messages(lead_id);
CREATE INDEX idx_messages_created ON whatsapp_messages(created_at DESC);
CREATE INDEX idx_events_lead_id ON lead_events(lead_id);
CREATE INDEX idx_events_type ON lead_events(event_type);

Now, If you do not know how to setup a Database, then stay tuned as that will be our next topic.

Leave a Reply

Your email address will not be published. Required fields are marked *