In most of the Gulf and Levant, WhatsApp isn't a support channel — it's the front desk. Customers ask prices, book appointments, and choose between competitors based on who answers first. Which makes the default setup remarkable: a human checking a phone between tasks, going silent at 8pm.
This post walks through the architecture of a self-hosted AI receptionist on a normal WhatsApp number — what the pieces are, why each exists, and the failure modes to design around. At the end there's a one-click version if you'd rather skip the assembly.
The architecture
Four services:
WhatsApp ⇄ Evolution API → webhook → n8n workflow → LLM (Claude/GPT)
↑ │
└── send reply ──────────┘
Postgres (sessions, messages) · Redis (instance cache)
- Evolution API (9k★) speaks the WhatsApp Web protocol — you pair it with a QR scan like WhatsApp Web, and it exposes a REST API + webhooks for messages.
- n8n hosts the receptionist logic as a visual workflow: filter → route → LLM call → reply.
- Postgres + a small volume persist the session, so redeploys don't ask you to re-scan the QR code.
- The LLM is yours — an Anthropic or OpenAI key, with the business context in the system prompt.
The routing logic that makes it a receptionist (not a toy)
The naive version — "forward every message to an LLM" — fails in production within a day. The workflow needs four branches:
1. Ignore what should be ignored. Group messages, your own outgoing messages, non-text payloads. Skipping this floods your LLM bill and spams groups.
2. Human handoff, on a keyword. When a customer types "human" (or your word of choice), the bot acknowledges, stops replying in that thread, and notifies your team. An AI that traps customers in bot-loop hell costs more goodwill than it saves labor.
3. Office-hours awareness. Out of hours, an instant "we're closed, here's when we open, leave your message" beats an AI improvising commitments at 3am.
4. Only then, the LLM. With a system prompt carrying the business's real facts (services, prices, policies, tone), a length cap, and instructions to offer the handoff word when unsure. Bilingual businesses: prompt it to answer in the customer's language — Arabic in, Arabic out.
Deployment failure modes to design around
- Session loss. If WhatsApp auth lives only in the container, every redeploy needs a QR re-scan. Persist sessions in Postgres and a volume.
- Version drift. Pin images by digest. (If you use Evolution API specifically: stay on the v2.3.x line — v2.4.0+ requires a license activation.)
- The unofficial-client caveat, honestly: this rides the WhatsApp Web protocol, not the official Business API. Meta can restrict accounts that spam. Use a dedicated number, answer inbound rather than broadcasting, and use the official API for regulated workloads.
The one-click version
We packaged this exact architecture — Evolution API (pinned v2.3.7), n8n with the four-branch receptionist workflow pre-loaded and auto-activated, Postgres, Redis, session persistence — as an open-source (MIT) Railway template:
- Deploy: https://railway.com/deploy/whatsapp-ai-receptionist?referralCode=qxxcuG
- Source + workflow JSON: https://github.com/Kjudeh/whatsapp-ai-receptionist
Deploy, paste an LLM key, scan one QR code, and message your own number.
And if you'd rather have it done for you — installed on your number, persona tuned to your business in Arabic and English, live in 48 hours, optionally managed — that's what we do at Bubbles Studio.
Questions welcome in the comments — and the repo takes issues and PRs.
Top comments (0)