PrismWA — WhatsApp Cloud API Console
A shared inbox and visual flow builder for WhatsApp Business teams — with real-time messaging, role-based access, idempotent webhook processing, and a no-code automation engine built on top of Meta's Cloud API.
Platform
Web
Duration
Ongoing
12+
Flow node types
<10s
Webhook-to-inbox latency
0
Duplicate messages processed
Project overview
PrismWA demonstrates that building a production-grade WhatsApp console on Meta's Cloud API requires solving a distinct class of infrastructure problems that are invisible until you operate at real scale — idempotent webhook processing, typing indicator sequencing, coexistence echo deduplication, and encrypted data exchange are all problems that only surface in production.
Platform
Web
Duration
Ongoing
Type
SaaS & Messaging
Stack
10 technologies
The challenge
WhatsApp Business teams managing high-volume conversations face a common set of problems: no unified inbox for collaborative handling, no automation without code, and a complex webhook integration that is fragile to duplicate delivery and race conditions. Existing tools are either too expensive, too locked-in, or don't expose the full power of Meta's Cloud API
No open-source, self-hostable WhatsApp shared inbox with RBAC
WhatsApp webhooks are delivered multiple times by Meta — requiring idempotent processing logic to prevent duplicate records
Building automation on top of WhatsApp requires significant backend engineering — templates, interactive messages, flow forms
Teams needed real-time inbox updates without polling
Native WhatsApp Flows (Meta's interactive form feature) had no management UI or server-side data exchange implementation
Human handoff between bots and agents had no standardized mechanism
What we set out to do
- 01
Build a multi-tenant WhatsApp console with workspace isolation and four-tier RBAC (OWNER, ADMIN, AGENT, ANALYST)
- 02
Implement idempotent, async webhook processing that guarantees zero duplicate messages regardless of Meta retry behavior
- 03
Create a visual no-code flow builder with 12+ node types for message automation
- 04
Deliver real-time inbox updates via Socket.io with conversation-level room isolation
- 05
Support Meta's native WhatsApp Flows with encrypted server-side data exchange and submission handling
- 06
Ship a self-hostable, open-source product with full documentation
How we solved it
Idempotent Webhook Processing Pipeline
Every webhook from Meta is hashed into an idempotency key and inserted into a `webhook_events` table with a unique constraint. Duplicate deliveries (which Meta sends regularly on retries) hit a duplicate key error and return 200 immediately — no processing, no duplicate records. A BullMQ cron job claims and processes unprocessed events in batches of 50 every 10 seconds, decoupled from the HTTP response cycle.
Key decision
Claim-based async processing over synchronous webhook handlers
Result
Zero duplicate messages in the inbox, regardless of Meta's retry behavior
Visual No-Code Flow Builder
Built a drag-and-drop automation builder using React Flow with 12+ custom node types — including SendMessage, SendTemplate, Condition (JMESPath expressions), HttpRequest, AnythingLlm (LLM integration), AssignAgent (round-robin), Delay, SendWaFlow, ExecuteFunction, SetVariable, and End. The flow engine executes graphs deterministically with guardrails: max 50 steps per run, same-node repeat limit of 3, and a human handoff flag that halts all automation when an agent takes over.
Key decision
Graph stored as JSON in `flow_versions.graph_json`; deterministic step-by-step execution with per-step audit trail
Result
Teams configure multi-step conversational automation without writing code
Real-Time Shared Inbox with Socket.io
Built a Socket.io gateway with workspace-level and conversation-level room isolation. Agents join conversation rooms on open and receive live message, status, and typing events without polling. JWT authentication is validated on the WebSocket handshake — not just HTTP. React Query on the frontend invalidates server state in response to socket events, keeping the inbox consistent.
Key decision
Room-per-conversation isolation with workspace broadcast for new conversation events
Result
Sub-second inbox refresh for all connected agents on the same workspace
Native WhatsApp Flows with Encrypted Data Exchange
Implemented full support for Meta's native WhatsApp Flows — interactive multi-screen form experiences inside WhatsApp. PrismWA manages flow definitions, handles encrypted data exchange requests from Meta (RSA decryption of incoming payloads, AES-GCM encryption of responses), stores form submissions, downloads media uploads (photos, documents), and forwards submissions to external APIs with configurable field mapping.
Key decision
Serverless JS functions (WA Flow Functions) for dynamic field population — user-authored code executed server-side with configurable timeoutsFull Meta Flows lifecycle handled inside PrismWA with no external tooling needed
Result
Full Meta Flows lifecycle handled inside PrismWA with no external tooling needed
Measurable impact
12+
Flow node types
<10s
Webhook-to-inbox latency
0
Duplicate messages processed
4
RBAC roles enforced across 100+ API endpoints
100+
REST API endpoints across 21 domain controllers
18
Database models with workspace-scoped multi-tenancy
Tech stack
What we learned
PrismWA demonstrates that building a production-grade WhatsApp console on Meta's Cloud API requires solving a distinct class of infrastructure problems that are invisible until you operate at real scale — idempotent webhook processing, typing indicator sequencing, coexistence echo deduplication, and encrypted data exchange are all problems that only surface in production.
- 01
Idempotency is not optional for webhook-driven systems — Meta retries aggressively, and a missing unique constraint creates a cascade of downstream data integrity issues
- 02
The 1:1 workspace-to-number model pays architectural dividends everywhere — flows, webhook routing, and socket rooms all become simpler when multi-number filtering is eliminated by design
- 03
WhatsApp's typing indicator requires a protocol-specific two-call sequence — treating it like a simple API call breaks the UX; treating it as fire-and-forget (with a deliberate internal delay) makes it work reliably
- 04
Native WhatsApp Flows are powerful but operationally complex — encryption key management, submission media downloads, and external forwarding all need to be solved together for the feature to be production-ready
More case studies
Replacing Exotel with a Self-Hosted Voice AI Gateway — 60% Cost Reduction at 500K Calls/Day
View case study Mobile AppBuilding a Real-Time Taxi Booking App with Live Maps
View case study AI & VoiceBuilding a Multilingual Voice AI Pipeline with Bhashini for Public Welfare Surveys
View case studyReady to build something that matters?
We solve problems that don't have Stack Overflow answers. Let's talk.
Book a Discovery Call