The repository ships a sanitized example workflow file atDocumentation 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.
workflows/atencion-whatsapp-principal.example.json. It is delivered deactivated and with no credentials assigned, so it can be safely imported into any n8n instance for review before it handles real traffic. The workflow has two independent branches: a main message-processing pipeline triggered by Chatwoot webhook events, and a scheduled data-sync branch that keeps bd_clientes up to date from a Google Drive XLSX file. Both branches share the same credential set and environment variable configuration defined in .env.example.
Required credentials
Before importing and activating the workflow, the following six credential types must exist in your n8n instance:- OpenAI — for audio transcription (Whisper) and response generation (chat completions).
- PostgreSQL — pointing specifically to the
agentdatabase, notn8norchatwoot. - Redis — for Human Handoff key lookups and message buffer list operations.
- WhatsApp Business Cloud — for sending reply messages via the Graph API.
- HTTP Header Auth — for authenticating media downloads from the WhatsApp Graph API. The token must not be written directly into any workflow node or exported JSON.
- Google Drive OAuth2 — for reading the XLSX sync file identified by
GOOGLE_DRIVE_SOURCE_FILE_ID.
Main workflow flowchart
Message flow walkthrough
Webhook trigger from Chatwoot. Every message event — inbound from a customer or outbound from a human agent — arrives at n8n through a Chatwoot webhook. The webhook carries a structured payload that includes the message direction, content type, sender phone number, account ID, and conversation ID. Incoming vs. outgoing detection (msg_from_client node). The first decision point checks whether the event represents a message arriving from a customer (incoming) or a message sent by an agent through Chatwoot (outgoing). Only incoming messages proceed into the AI processing pipeline. If the message is outgoing, n8n treats it as evidence of human agent activity and activates the Human Handoff state for that conversation.
Human Handoff check in Redis. For every incoming message that passes the direction check, n8n queries Redis for the Human Handoff key associated with that conversation. If the key exists and holds the value true, the AI pipeline is bypassed entirely and the execution ends — the human agent remains in control. If no key is found, processing continues.
Text vs. audio branch. The workflow splits on message content type. Text messages are normalized (trimmed, lowercased where appropriate) and passed directly to the buffer. Audio messages are first downloaded from the WhatsApp Cloud API using the HTTP Header Auth credential, then sent to OpenAI’s Whisper API for transcription, and the resulting text enters the same buffer path as a regular text message.
Redis buffer and message grouping. Normalized message text is pushed onto a Redis list keyed by the conversation (currently keyed by the sender’s phone number; the recommended format is buffer:<account_id>:<conversation_id>). A short grouping window allows rapid successive messages from the same customer to accumulate before the workflow reads the full list and processes all of them together. This prevents the AI from responding to “hello” before the customer has finished typing their full question.
Business hours check (America/Mexico_City, Mon–Fri 08:00–16:59). After grouping, the workflow evaluates whether the current time falls within the defined business hours window. If the message arrives outside of business hours, the workflow sends a pre-configured informational message to the customer explaining availability and ends the execution without invoking the AI. Public holidays are not modeled and must be handled operationally.
AI agent processing. Within business hours, the grouped message text is passed to the AI agent node. The agent maintains a context window of the last 10 messages. When it detects a service folio in the customer’s message, it queries the bd_clientes table in PostgreSQL to retrieve the corresponding client record. The agent’s system prompt instructs it never to invent prices, results, or payment statuses — it may only report what is present in the database. When a pricing-related question is answered, the agent returns a special image key rather than embedding prices in text.
Reply delivery via WhatsApp Cloud API. The workflow inspects the AI agent’s output. Plain text responses are sent directly as WhatsApp text messages. Image key responses are mapped to the corresponding image URLs defined in the .env environment variables (PRICE_IMAGE_PACKAGE_1_URL, PRICE_IMAGE_PACKAGE_2_URL, PRICE_IMAGE_ANALYSIS_URL) and sent as image messages through the WhatsApp Cloud API.
Important rules
Loop prevention
Loop prevention
msg_from_client node is the primary guard against infinite loops. Because Chatwoot emits webhook events for both incoming and outgoing messages, a naive workflow would trigger the AI on its own replies. The node strictly filters to incoming direction only. Outgoing messages instead trigger the Human Handoff activation path, which is also the mechanism that pauses the AI when a human agent responds from Chatwoot.Audio downloads via HTTP Header Auth
Audio downloads via HTTP Header Auth
Buffer key format
Buffer key format
Google Drive sync
The workflow file contains a second, independently scheduled branch dedicated to keepingbd_clientes current. The sync runs in four steps:
- Detect changes — the branch polls the Google Drive file identified by
GOOGLE_DRIVE_SOURCE_FILE_IDand checks whether it has been modified since the last sync. - Download the file — if a change is detected, the XLSX file is downloaded using the Google Drive OAuth2 credential.
- Extract rows — all data rows are extracted from the spreadsheet, with the first row treated as the header.
- Upsert into
bd_clientes— each row is inserted into PostgreSQL usingON CONFLICT (folio) DO UPDATE, so existing records are updated in place and new folios are inserted without duplication.
| XLSX Column | PostgreSQL Field |
|---|---|
Folio | folio |
Razon_Social | razon_social |
Telefono | telefono |
Correo | correo |
Materia_Prima | materia_prima |
Estatus_Pago | estatus_pago |
Aplica_Convenio | aplica_convenio |
Safe import checklist
Import the JSON
workflows/atencion-whatsapp-principal.example.json through the n8n interface. Confirm it appears in the workflow list in a deactivated state before proceeding.Verify deactivated status
Assign each credential manually
Review variables and URLs
$env.*) used in the workflow. If your n8n version or configuration restricts $env access, replace those references with n8n-managed credentials or workflow variables.Replace business content
Execute each branch with test data
Activate only after completing tests
Known risks
Exported workflow contains business logic and content
Exported workflow contains business logic and content
Webhook depends on Chatwoot payload structure
Webhook depends on Chatwoot payload structure
.env.example. If Chatwoot is upgraded and its webhook payload structure changes, affected nodes may fail silently or with incorrect data extractions. Review payload structure after every Chatwoot upgrade.Graph API version must be updated intentionally
Graph API version must be updated intentionally
WHATSAPP_GRAPH_API_VERSION environment variable pins the Meta Graph API version used for sending messages and downloading media. Meta deprecates older API versions on a published schedule. Upgrading the version requires testing against a non-production number because request and response formats may differ between versions.Environment variable access depends on n8n configuration
Environment variable access depends on n8n configuration
$env.* variables require the N8N_BLOCK_ENV_ACCESS_IN_NODE setting to be disabled. Some n8n hosting configurations or newer versions may restrict environment variable access from within nodes. If this occurs, replace all $env.* references with n8n-managed credentials or variables configured through the n8n interface.No global error-handling workflow
No global error-handling workflow
Buffer collisions under concurrent load
Buffer collisions under concurrent load
buffer:<account_id>:<conversation_id> format eliminates this risk but requires workflow changes and concurrent-load testing before deployment.