The platform is built as a set of cooperating layers: a channel layer that connects to WhatsApp, an attention layer where human agents work, an orchestration layer that runs the decision logic, an intelligence layer that interprets and generates natural language, and a persistence layer that stores both durable business data and short-lived conversational state. All of these layers run in Docker containers on a single host, communicate over an isolated bridge network, and are exposed to the internet only through a Caddy reverse proxy that handles HTTPS automatically. This layered design means each component has a single, well-defined responsibility and can be updated independently.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DevMauricio03/n8n-whatsapp-ai-agent/llms.txt
Use this file to discover all available pages before exploring further.
System Overview
The diagram below shows how the components are connected at a high level. Messages travel from the WhatsApp customer to the Cloud API, into Chatwoot, through the Caddy proxy to n8n, and back out to WhatsApp. Supporting services — OpenAI, PostgreSQL, Redis, and Google Drive — are reached exclusively by n8n.Message Flow
Every inbound WhatsApp message follows the same path through the system. Understanding this flow makes it easier to diagnose failures, tune performance, and reason about where conversational state lives at any given moment.- Customer sends a message via the WhatsApp mobile or web client.
- WhatsApp Cloud API receives the message and forwards it to the Chatwoot webhook endpoint over HTTPS.
- Chatwoot stores the message, creates or updates the contact record, and assigns it to the WhatsApp inbox. It then emits a webhook event to n8n.
- Caddy receives the webhook POST on port 443, terminates TLS, and proxies the request to n8n on the internal network.
- n8n receives the webhook payload and begins the principal workflow.
- Redis human-handoff check — n8n queries Redis to determine whether a human agent currently holds the conversation. If the handoff flag is active, the workflow pauses and no automated reply is sent. The flag expires after a TTL of 30 minutes or can be cleared manually.
- Message type branch — if automation proceeds, the workflow branches on message type:
- Text messages are written to a Redis buffer. A short wait groups any follow-up messages sent within a few seconds into a single combined input before processing continues.
- Voice notes are first sent to OpenAI Whisper for transcription. The transcript is stored in Redis and then treated as a text message.
- Business-hours check — messages received outside the configured schedule are held until the next open window.
- OpenAI chat completion — n8n constructs a prompt that includes the customer’s message, the conversational memory retrieved from PostgreSQL, and a system prompt that references the business data stored in the
bd_clientestable. - PostgreSQL lookup — the workflow queries the
agentdatabase for product, pricing, or customer information relevant to the request. - Response generation — n8n produces either a text reply or selects a pre-configured media asset (image URL) based on the identified intent.
- Delivery — n8n calls the WhatsApp Cloud API directly to send the reply, and Chatwoot reflects the outbound message in the agent inbox.
- Customer receives the reply on WhatsApp.
Platform Layers
The table below maps each logical layer to the component that fulfils it and describes its responsibility within the system.| Layer | Component | Responsibility |
|---|---|---|
| Channel | WhatsApp Cloud API | Message ingestion and delivery to/from the customer |
| Attention | Chatwoot | Shared inbox, contact management, and human agent interface |
| Orchestration | n8n | Routing rules, workflow logic, and AI agent coordination |
| Intelligence | OpenAI | Text generation (GPT) and voice transcription (Whisper) |
| Persistence | PostgreSQL | Business data (bd_clientes), conversational memory, and n8n/Chatwoot internal data |
| Temporary state | Redis | Message buffer, human-handoff lock, and inter-node coordination |
| Data source | Google Drive | Spreadsheet that feeds the bd_clientes synchronisation workflow |
| Exposure | Caddy | Automatic HTTPS via ACME and reverse proxy to internal services |
Network and Exposure
All containers are members of a single Docker bridge network namedplatform_net. Only the Caddy container publishes ports to the host — and therefore to the internet:
| Port | Protocol | Purpose |
|---|---|---|
80 | TCP | HTTP-to-HTTPS redirect and ACME HTTP-01 challenge |
443 | TCP | HTTPS (TLS 1.2/1.3) |
443 | UDP | HTTP/3 (QUIC) when available |
expose rather than ports in the Compose configuration. This makes them reachable by other containers on platform_net but not from outside the host.
Design Decisions
The following four decisions were made consciously during the design of the platform. Understanding them helps you evaluate whether the architecture is appropriate for your context and how to adapt it safely. 1. Single PostgreSQL instance for three databases PostgreSQL hostsn8n, chatwoot, and agent in one container using a single superuser. This simplifies initial setup and reduces operational overhead on a VPS. In environments with higher security requirements, each application should use a dedicated PostgreSQL user with minimum necessary privileges. Creating separate users and granting fine-grained permissions is documented in docs/seguridad.md.
2. Redis as a lightweight state store, not a durable message queue
Redis is configured with password authentication and AOF persistence (--appendonly yes), which protects against data loss on a clean restart. However, Redis is not a substitute for a durable message queue such as RabbitMQ or Kafka. If the Redis container restarts unexpectedly during a high-volume period, buffered messages in flight may be lost. This trade-off is acceptable for the target deployment size.
3. Webhook contract dependency on Chatwoot
The n8n workflow parses the Chatwoot webhook payload directly. Any change to Chatwoot’s event schema — for example a field rename in a major version upgrade — will break the workflow until the affected nodes are updated. Always read Chatwoot release notes before upgrading and test the new version against the workflow in a staging environment.
4. Parametrised image versions
All Docker image tags are stored as environment variables (POSTGRES_IMAGE, N8N_IMAGE, etc.) rather than being hardcoded in the Compose file. This allows controlled, version-by-version upgrades without modifying the Compose template. Avoid using the latest tag in production: pin to a specific version or digest so that docker compose pull never introduces an unreviewed change.