Building an Automated WhatsApp Chatbot with n8n and Database Storage
Building a basic auto-reply bot on WhatsApp is relatively easy, but as anyone in customer operations will tell you, a bot without memory is a liability.
If a customer provides their order number in the first message and the bot asks for it again in the third, the experience transitions from helpful automation to operational friction.
To solve this, you need state management.
In this guide, we will walk through building an automated WhatsApp chatbot with n8n and database storage. By the end, you will have a workflow that:
- Recognizes returning users
- Stores conversation history
- Knows exactly when to escalate a high-priority issue to a human agent
The Problem: Why Your WhatsApp Bot Needs a Database
Most low-code WhatsApp integrations operate on a "fire and forget" model:
- A webhook receives a message
- An LLM or rules generate a response
- The message is sent
The problem? The next message from the same user starts from zero.
From a customer operations perspective, this creates several risks:
-
Context Loss Users must repeat information, increasing Average Handling Time (AHT) when a human steps in
-
Looping Errors Without state tracking, bots can get stuck in infinite loops
-
Lack of Personalization You cannot differentiate users (e.g., "Gold Member") without stored data
By adding a persistent layer—like PostgreSQL or MySQL—you transform a simple responder into a stateful support system.
Prerequisites
Before starting, ensure you have:
-
n8n Instance (self-hosted or cloud)
-
WhatsApp API Access
- Official Meta API, or
- A developer-friendly alternative like WASenderApi
-
Database (PostgreSQL or Supabase recommended)
-
Webhook URL (public endpoint from n8n)
Step 1: Designing the Database Schema
We need to store:
- User sessions (state tracking)
- Message logs (audit + debugging)
Run the following SQL:
CREATE TABLE whatsapp_sessions (
phone_number VARCHAR(20) PRIMARY KEY,
current_state VARCHAR(50) DEFAULT 'START',
last_interaction TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
user_data JSONB
);
CREATE TABLE message_logs (
id SERIAL PRIMARY KEY,
phone_number VARCHAR(20),
direction VARCHAR(10), -- 'inbound' or 'outbound'
message_body TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Key concept:
current_state controls the entire flow (e.g., START, AWAITING_ORDER_ID, ESCALATED).
Step 2: Creating the n8n Entry Point
Start with a Webhook Node:
- Method:
POST - Use production URL when live
If using WASenderApi, configure its dashboard to send incoming messages to this webhook.
First Logic Gate: Identify the User
Add a PostgreSQL Node (SELECT):
SELECT * FROM whatsapp_sessions
WHERE phone_number = '{{ $json.from }}';
Then use an If Node:
- No result → Create new session
- Result exists → Route based on state
Step 3: Implementing State-Based Routing
This is the core intelligence layer.
Use a Switch Node based on current_state:
-
START → Send welcome message → Update state to
MENU_SELECTED -
AWAITING_ORDER_ID → Validate input → Fetch order from ERP / Shopify
-
HUMAN_HANDOFF → Pause bot responses → Notify support team
Step 4: Sending Responses via WhatsApp
Use an HTTP Request Node.
Example payload for WASenderApi:
{
"method": "POST",
"url": "https://www.wasenderapi.com/api/send-message",
"headers": {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
"body": {
"to": "{{ $node[\"Webhook\"].json[\"remoteJid\"] }}",
"text": "I've found your order! It is currently out for delivery."
}
}
Note: WASenderApi enables fast setup via session-based connections. Always follow WhatsApp anti-spam policies.
Handling Edge Cases and Escalations
1. “I Don’t Understand” Counter
Store failure_count inside user_data:
- If ≥ 3 → escalate to human
2. Time-Based Reset
If last_interaction > 2 hours:
- Reset
current_state→START
3. Media Handling
If message type ≠ text:
- Route to human review queue
Troubleshooting Common Issues
-
Webhook Timeouts Respond immediately (200 OK), process async using n8n workflows
-
JSON Formatting Errors Ensure proper escaping of strings
-
Database Limits Use connection pooling (e.g., PgBouncer) under high load
FAQ
Can I build this without a database?
Yes, using n8n static data or JSON files. However, this is unreliable beyond small scale.
Is WASenderApi safe?
It uses session-based connections. Follow WhatsApp usage policies to minimize risk.
How do I notify my team?
Use Slack or Teams nodes in the escalation branch. Send:
- Phone number
- Chat context
Does this work with the official API?
Yes. Only the HTTP request node changes—the architecture remains identical.
Conclusion and Next Steps
Building an automated WhatsApp chatbot with n8n and database storage transforms your system from reactive to stateful and scalable.
Instead of answering repetitive queries, you manage exceptions and escalations only.
Next Steps
- Set up your PostgreSQL tables
- Build a basic “Hello World” n8n workflow
- Add logging to
message_logs - Incrementally implement state logic
By focusing on state management, you are not just building a bot—you are building a reliable operational system.