WhatsApp bots built on n8n forget everything the moment a conversation ends. Every new message starts from scratch — the bot has no idea the user contacted you last week about a refund, or that they prefer responses in Spanish.
This guide shows you how to add persistent, per-user memory to a WhatsApp AI bot in n8n using retainr. The bot will remember every user's history across all conversations without any database setup.
What You Will Build
A WhatsApp AI assistant that:
- Receives WhatsApp messages via webhook
- Searches the user's memory history before generating a response
- Generates a context-aware AI reply
- Stores the conversation turn for future recall
- Replies via WhatsApp
Every user gets their own isolated memory namespace. The bot genuinely remembers them.
Prerequisites
- n8n instance (self-hosted or n8n Cloud)
- WhatsApp Business API access (via Meta or a provider like Twilio, 360dialog, or WATI)
- retainr account (free at retainr.dev/dashboard)
- OpenAI API key
Step 1: Install the retainr Community Node
In your n8n instance:
Settings → Community Nodes → Install → n8n-nodes-retainr
On n8n Cloud Starter and above, community nodes are available. If you are on n8n Cloud Free, use the HTTP Request node to call the retainr API directly — the same endpoints are available.
Step 2: Set Up the WhatsApp Webhook Trigger
Add a Webhook node as your workflow trigger:
- HTTP Method: POST
- Path:
/whatsapp-incoming(or any path you choose) - Authentication: None (WhatsApp sends a verification token you validate separately)
When a user sends a WhatsApp message, your webhook provider POSTs a payload like:
{
"from": "+14155238886",
"body": "What was the issue I reported last week?",
"timestamp": "1711425600"
}The from field (the user's phone number) will be your memory namespace. It uniquely identifies the user across all conversations.
Step 3: Search User Memory
Add a retainr: Search Memory node:
- Namespace:
={{ $json.from }}(the sender's phone number) - Query:
={{ $json.body }}(their current message) - Limit: 5
This performs a semantic search across everything you have ever stored for this phone number. The 5 most relevant past interactions come back as context.
If the user asks "what was the issue I reported last week?" — retainr finds the turn where they described their issue, even if the wording is different.
Step 4: Build the AI Prompt
Add an OpenAI node (or any AI node):
- Model: gpt-4o
- System prompt:
You are a helpful customer support assistant for [Company Name].
You have access to the conversation history for this user:
{{ $node["retainr_search"].json.results.map(r => r.content).join("\n---\n") }}
Use this history to provide context-aware responses. If no history is available, respond normally.
- User message:
={{ $json.body }}
The memory results inject directly into the system prompt. The AI now has full context from all previous interactions.
If the search returns no results (new user), the template string evaluates to an empty string — the AI responds normally. No special handling needed for first-time users.
Step 5: Store the Conversation Turn
Add a retainr: Store Memory node after the AI response:
- Namespace:
={{ $node["Webhook"].json.from }} - Content:
User: {{ $node["Webhook"].json.body }}
Assistant: {{ $json.choices[0].message.content }}
- TTL: 90 (days, optional — memories expire after 90 days if you want automatic cleanup)
This stores the full exchange. Next time this user contacts you, the relevant parts of this exchange will surface in the semantic search.
Step 6: Reply via WhatsApp
Add an HTTP Request node to send the reply back:
- Method: POST
- URL: Your WhatsApp provider's send message endpoint
- Headers:
Authorization: Bearer YOUR_WHATSAPP_TOKEN - Body:
{
"to": "{{ $node[\"Webhook\"].json.from }}",
"type": "text",
"text": {
"body": "{{ $node[\"OpenAI\"].json.choices[0].message.content }}"
}
}The Complete Workflow
The 6-node workflow:
Webhook Trigger
→ retainr: Search Memory (user's history)
→ OpenAI: Generate response (with memory context)
→ retainr: Store Memory (this exchange)
→ HTTP Request: Send WhatsApp reply
Total setup time: under 30 minutes including the WhatsApp webhook configuration.
Multi-Language Memory
If your users contact you in different languages, retainr handles this automatically. The semantic search is language-agnostic — a user who asked about a refund in Spanish last month will have that memory retrieved when they ask about it in English today.
Store memories in the language they were spoken. Retrieve them in any language.
Handling High Volume
For businesses with thousands of daily WhatsApp interactions:
- Set a TTL of 30-90 days to prevent memory bloat
- Use
namespace: wa:{phone_number}to distinguish WhatsApp users from other channels (email, Telegram) in the same retainr account - Limit search results to 3-5 for faster response times
WhatsApp has a 24-hour messaging window — you can only reply to users who messaged you in the last 24 hours without a pre-approved template. This is a Meta policy, not an n8n or retainr limitation.
Frequently Asked Questions
Does this work on n8n Cloud? Yes. Community nodes work on n8n Cloud Starter and above. On n8n Cloud Free, replace the retainr community nodes with HTTP Request nodes calling the retainr REST API directly.
How do I handle the WhatsApp webhook verification? Add an IF node before the main logic that checks for a hub.mode=subscribe query parameter and returns the hub.challenge value. This is the Meta webhook verification handshake.
Can I use this with Twilio or 360dialog? Yes. The workflow is identical — only the trigger webhook payload format and the send message HTTP call differ slightly. The retainr memory nodes are the same.
What if two users send messages at the same time? Each user has their own namespace in retainr. Concurrent requests do not interfere — the RLS policies at the database layer enforce isolation.
Add memory to other n8n workflows
Building with a different app? These guides cover the same pattern:
- n8n Telegram AI Memory — Long-term memory for Telegram bots
- n8n Slack AI Memory — Persistent memory for Slack bots
- n8n Discord AI Memory — Persistent memory for Discord bots
- n8n Gmail AI Memory — Per-sender memory for Gmail AI workflows
- n8n HubSpot AI Memory — CRM-aware AI memory for HubSpot
- n8n Zendesk AI Memory — AI memory for support ticket workflows
- n8n Airtable AI Memory — Persistent memory for Airtable workflows
Give your AI agents a real memory
Free plan includes 1,000 memory operations/month. No credit card required.
Start building your WhatsApp bot — free API key →