Skip to content

guilhermejansen/whatsapp-flows-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

69 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

WhatsApp Flows Server

License: MIT Node.js Version TypeScript Docker Docker Pulls GitHub Actions Semantic Release

Production-ready Node.js server for WhatsApp Flows with automated CI/CD, multi-arch Docker support, and DDD architecture

Features β€’ Quick Start β€’ Documentation β€’ Architecture β€’ Contributing


πŸ“– Overview

WhatsApp Flow Server is a robust, production-ready TypeScript server that implements the WhatsApp Flows API using Domain-Driven Design (DDD) principles. It provides a complete solution for handling WhatsApp Flow interactions with built-in encryption, webhook processing, and comprehensive CI/CD automation.

🎯 What Problem Does It Solve?

WhatsApp Flows enable rich, interactive experiences within WhatsApp, but implementing them requires:

  • Complex encryption (RSA-2048 + AES-128-GCM with mandatory IV flip)
  • Dual endpoint architecture (Flow Data API + Webhooks)
  • Strict performance requirements (<3s response time)
  • Secure key management and Meta API integration
  • Production-ready infrastructure with monitoring and scaling

This server solves all these challenges with:

  • βœ… Pre-configured encryption with IV flip pattern
  • βœ… Dual endpoint architecture out-of-the-box
  • βœ… Automatic database migrations
  • βœ… Multi-architecture Docker support (AMD64 + ARM64)
  • βœ… Complete CI/CD pipeline with semantic versioning
  • βœ… Production-ready with health checks and logging

✨ Features

Core Capabilities

  • πŸ—οΈ Domain-Driven Design - Clean architecture with separated layers (Domain, Application, Infrastructure)
  • πŸ” WhatsApp Flow Encryption - Complete RSA-2048 + AES-128-GCM implementation with mandatory IV flip
  • πŸ”„ Dual Endpoint System - Flow Data API + Webhook receiver with signature validation
  • πŸ“Š PostgreSQL Storage - Persistent storage for Flows, Sessions, and Responses
  • βœ… Schema Validation - Type-safe with Zod v4
  • πŸ“ Structured Logging - Winston with rotation and multiple transports

DevOps & Deployment

  • 🐳 Multi-Arch Docker - Native support for AMD64 (Intel/AMD) and ARM64 (Apple Silicon, AWS Graviton)
  • πŸš€ Automated CI/CD - GitHub Actions with semantic release and Docker Hub publishing
  • πŸ“¦ Conventional Commits - Automated versioning and changelog generation
  • πŸ”„ Auto Migrations - Database migrations run automatically on container startup
  • πŸ’ͺ Production Ready - Health checks, monitoring, and graceful shutdown

Developer Experience

  • πŸ› οΈ TypeScript 5.9 - Full type safety with strict mode
  • 🎨 Modern Stack - Express 5.x, PostgreSQL 18, Node.js 20+
  • πŸ”§ Developer Tools - ESLint, Prettier, Husky, Commitlint
  • πŸ“– Comprehensive Docs - Complete guides for setup, deployment, and troubleshooting
  • πŸ§ͺ Testing Ready - Structure prepared for unit and integration tests

πŸ›οΈ Architecture

System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        WhatsApp Platform                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚                                      β”‚
             β”‚ Encrypted Flow Data                  β”‚ Webhook Events
             β”‚ (RSA-2048 + AES-128-GCM)            β”‚ (nfm_reply)
             β–Ό                                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Flow Endpoint (Data API)  β”‚      β”‚   Webhook Endpoint       β”‚
β”‚   POST /flows/endpoint/:id  β”‚      β”‚   POST /webhooks/whatsappβ”‚
β”‚                             β”‚      β”‚                          β”‚
β”‚   - Decrypt request         β”‚      β”‚   - Validate signature   β”‚
β”‚   - Process action          β”‚      β”‚   - Parse response_json  β”‚
β”‚   - Return encrypted data   β”‚      β”‚   - Forward to callback  β”‚
β”‚   - < 3s response time      β”‚      β”‚   - Store in database    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚                                β”‚
               β”‚                                β”‚
               β–Ό                                β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         Application Layer                        β”‚
β”‚                                                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ HandleFlowRequest    β”‚        β”‚ ProcessWebhook          β”‚   β”‚
β”‚  β”‚ UseCase              β”‚        β”‚ UseCase                 β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚             β”‚                                 β”‚                 β”‚
β”‚             β–Ό                                 β–Ό                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚              Domain Layer (Business Logic)              β”‚   β”‚
β”‚  β”‚                                                          β”‚   β”‚
β”‚  β”‚  β€’ FlowEngine - Navigation and data exchange           β”‚   β”‚
β”‚  β”‚  β€’ Flow - Immutable Flow templates                     β”‚   β”‚
β”‚  β”‚  β€’ FlowSession - User session tracking                 β”‚   β”‚
β”‚  β”‚  β€’ FlowResponse - Completed Flow data                  β”‚   β”‚
β”‚  β”‚  β€’ EncryptionService - RSA/AES with IV flip            β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                             β”‚                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Infrastructure Layer                          β”‚
β”‚                                                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   PostgreSQL     β”‚  β”‚   Express HTTP  β”‚  β”‚   Axios HTTP  β”‚  β”‚
β”‚  β”‚   Repositories   β”‚  β”‚   Server        β”‚  β”‚   Client      β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                  β”‚
β”‚  Database Tables:                                               β”‚
β”‚  β€’ flows - Flow JSON templates                                 β”‚
β”‚  β€’ flow_sessions - Active/completed sessions                   β”‚
β”‚  β€’ flow_responses - Completed Flow data                        β”‚
β”‚  β€’ webhook_events - Webhook audit trail                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Flow Interaction Sequence

User                WhatsApp          Flow Server         Database        Your System
  β”‚                    β”‚                    β”‚                 β”‚                β”‚
  β”‚ Click Flow Button  β”‚                    β”‚                 β”‚                β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                    β”‚                 β”‚                β”‚
  β”‚                    β”‚                    β”‚                 β”‚                β”‚
  β”‚                    β”‚ POST /flows/endpoint (INIT)          β”‚                β”‚
  β”‚                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                 β”‚                β”‚
  β”‚                    β”‚                    β”‚ Create Session  β”‚                β”‚
  β”‚                    β”‚                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                β”‚
  β”‚                    β”‚                    β”‚ Return INIT     β”‚                β”‚
  β”‚                    β”‚<────────────────────                 β”‚                β”‚
  β”‚                    β”‚                    β”‚                 β”‚                β”‚
  β”‚  Display Screen 1  β”‚                    β”‚                 β”‚                β”‚
  β”‚<────────────────────                    β”‚                 β”‚                β”‚
  β”‚                    β”‚                    β”‚                 β”‚                β”‚
  β”‚ Fill & Submit      β”‚                    β”‚                 β”‚                β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                    β”‚                 β”‚                β”‚
  β”‚                    β”‚ POST /flows/endpoint (data_exchange) β”‚                β”‚
  β”‚                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                 β”‚                β”‚
  β”‚                    β”‚                    β”‚ Update Session  β”‚                β”‚
  β”‚                    β”‚                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                β”‚
  β”‚                    β”‚                    β”‚ Return Screen 2 β”‚                β”‚
  β”‚                    β”‚<────────────────────                 β”‚                β”‚
  β”‚                    β”‚                    β”‚                 β”‚                β”‚
  β”‚  Display Screen 2  β”‚                    β”‚                 β”‚                β”‚
  β”‚<────────────────────                    β”‚                 β”‚                β”‚
  β”‚                    β”‚                    β”‚                 β”‚                β”‚
  β”‚ Complete Flow      β”‚                    β”‚                 β”‚                β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                    β”‚                 β”‚                β”‚
  β”‚                    β”‚ POST /flows/endpoint (complete)      β”‚                β”‚
  β”‚                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                 β”‚                β”‚
  β”‚                    β”‚                    β”‚ Mark Complete   β”‚                β”‚
  β”‚                    β”‚                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                β”‚
  β”‚                    β”‚                    β”‚                 β”‚                β”‚
  β”‚                    β”‚ POST /webhooks/whatsapp (nfm_reply)  β”‚                β”‚
  β”‚                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                 β”‚                β”‚
  β”‚                    β”‚                    β”‚ Store Response  β”‚                β”‚
  β”‚                    β”‚                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚                β”‚
  β”‚                    β”‚                    β”‚ Forward Data    β”‚                β”‚
  β”‚                    β”‚                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€>β”‚
  β”‚                    β”‚                    β”‚                 β”‚                β”‚
  β”‚  "Thank you!"      β”‚                    β”‚                 β”‚                β”‚
  β”‚<────────────────────                    β”‚                 β”‚                β”‚

Encryption Flow (IV Flip Pattern)

WhatsApp Request                    Server Response
     β”‚                                    β”‚
     β”‚  Encrypted with:                  β”‚  Encrypted with:
     β”‚  β€’ AES key encrypted by RSA       β”‚  β€’ FLIPPED IV ⚠️
     β”‚  β€’ Normal IV                      β”‚  β€’ Same AES key
     β”‚                                   β”‚
     β–Ό                                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Decrypt AES Keyβ”‚              β”‚ Flip IV Buffer β”‚
β”‚ with RSA       β”‚              β”‚ (reverse bytes)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                                β”‚
        β–Ό                                β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Decrypt Payloadβ”‚              β”‚ Encrypt Payloadβ”‚
β”‚ with AES       β”‚              β”‚ with AES       β”‚
β”‚ (normal IV)    β”‚              β”‚ (flipped IV)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                                β”‚
        β–Ό                                β–Ό
   Flow Data                      Encrypted Response

πŸš€ Quick Start

Prerequisites

  • Node.js >= 20.0.0
  • Docker & Docker Compose (recommended) or PostgreSQL 18+
  • WhatsApp Business Account with Flows enabled
  • Meta Developer Account for API credentials

Option 1: Docker (Recommended)

# 1. Clone the repository
git clone https://github.com/guilhermejansen/whatsapp-flows-server.git
cd whatsapp-flows-server

# 2. Configure environment
cp .env.docker.example .env
nano .env  # Edit with your credentials

# 3. Start services
docker-compose up -d

# 4. Generate encryption keys
docker-compose exec app npm run generate-keys
# Copy output to .env

# 5. Restart application
docker-compose restart app

# 6. Register public key with Meta
docker-compose exec app npm run register-key

# 7. Verify health
curl http://localhost:3000/health

Your server is now running! πŸŽ‰

Configure WhatsApp Manager:

  • Flow Endpoint: https://your-domain.com/flows/endpoint/csat-feedback
  • Webhook URL: https://your-domain.com/webhooks/whatsapp

Option 2: Local Development

# 1. Clone and install
git clone https://github.com/guilhermejansen/whatsapp-flows-server.git
cd whatsapp-flows-server
npm install

# 2. Setup PostgreSQL
createdb whatsapp_flows
npm run migrate

# 3. Generate keys
npm run generate-keys
# Copy output to .env

# 4. Configure environment
cp .env.example .env
nano .env  # Edit with your credentials

# 5. Register public key
npm run register-key

# 6. Start development server
npm run dev

πŸ“¦ Docker Deployment

Multi-Architecture Support

Pre-built images available for AMD64 (Intel/AMD) and ARM64 (Apple Silicon, AWS Graviton):

# Pull latest version
docker pull setupautomatizado/whatsapp-flows-server:latest

# Or specific version
docker pull setupautomatizado/whatsapp-flows-server:1.0.0

Production Deployment

1. Server Setup

# Create directory
mkdir -p ~/whatsapp-flows-server-production
cd ~/whatsapp-flows-server-production

# Download compose file
curl -O https://raw.githubusercontent.com/guilhermejansen/whatsapp-flows-server/main/docker-compose.yml

# Configure environment
curl -O https://raw.githubusercontent.com/guilhermejansen/whatsapp-flows-server/main/.env.docker.example
cp .env.docker.example .env
nano .env

2. SSL Setup (Nginx + Let's Encrypt)

# Install Nginx + Certbot
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx -y

# Configure Nginx
sudo nano /etc/nginx/sites-available/whatsapp-flows-server

Nginx Configuration:

server {
    listen 443 ssl http2;
    server_name your-domain.com;

    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WhatsApp requires < 3s response
        proxy_connect_timeout 2s;
        proxy_send_timeout 2s;
        proxy_read_timeout 2s;
    }
}
# Enable site
sudo ln -s /etc/nginx/sites-available/whatsapp-flows-server /etc/nginx/sites-enabled/
sudo nginx -t

# Get SSL certificate
sudo certbot --nginx -d your-domain.com

# Restart Nginx
sudo systemctl restart nginx

3. Start Application

# Start services
docker-compose up -d

# Generate keys
docker-compose exec app npm run generate-keys
# Add keys to .env

# Restart
docker-compose restart app

# Register public key
docker-compose exec app npm run register-key

# Verify
curl https://your-domain.com/health

Available Commands

# View logs
docker-compose logs -f app

# Shell access
docker-compose exec app sh

# Database access
docker-compose exec postgres psql -U whatsapp_flow -d whatsapp_flows

# Run migrations manually
docker-compose exec app npm run migrate

# Backup database
docker-compose exec postgres pg_dump -U whatsapp_flow whatsapp_flows > backup.sql

# Stop services
docker-compose down

πŸ”§ Configuration

Environment Variables

Variable Description Required Example
NODE_ENV Environment mode βœ… production
PORT Server port βœ… 3000
DATABASE_URL PostgreSQL connection string βœ… postgresql://user:pass@localhost:5432/db
PRIVATE_KEY RSA private key (PEM format) βœ… -----BEGIN RSA PRIVATE KEY-----\n...
PUBLIC_KEY RSA public key (PEM format) βœ… -----BEGIN PUBLIC KEY-----\n...
META_APP_SECRET Meta app secret βœ… your_app_secret
META_VERIFY_TOKEN Webhook verify token βœ… your_verify_token
META_ACCESS_TOKEN WhatsApp API access token βœ… EAAB...
CALLBACK_WEBHOOK_URL Your callback URL for completed flows βœ… https://yourapi.com/webhook
DEFAULT_FLOW_NAME Default flow when not specified ⚠️ csat-feedback
FLOW_ENDPOINT_TIMEOUT Max response time (< 3000ms) ⚠️ 2500
CORS_ORIGINS Allowed CORS origins ⚠️ https://app.com
API_TOKEN API authentication token ⚠️ Generated with openssl rand -hex 32

Legend: βœ… Required | ⚠️ Recommended

Key Generation

# Generate RSA-2048 key pair
npm run generate-keys

# Validate keys
npm run validate-keys

# Register public key with Meta
npm run register-key

πŸ” Security

Encryption Implementation

This server implements WhatsApp's mandatory IV flip pattern for encryption:

// Decryption (incoming from WhatsApp) - Normal IV
const iv = Buffer.from(initialVector, 'base64');
const decipher = crypto.createDecipheriv('aes-128-gcm', aesKey, iv);

// Encryption (outgoing to WhatsApp) - FLIPPED IV ⚠️
const iv = Buffer.from(initialVector, 'base64');
const flippedIV = Buffer.from(iv).reverse(); // Must reverse!
const cipher = crypto.createCipheriv('aes-128-gcm', aesKey, flippedIV);

Critical: If IV is not flipped, WhatsApp returns error 421.

Security Best Practices

  • βœ… Never commit private keys to Git
  • βœ… Use environment variables for all secrets
  • βœ… Rotate tokens every 3-6 months
  • βœ… Enable HTTPS in production (required by WhatsApp)
  • βœ… Validate webhooks with X-Hub-Signature-256
  • βœ… Run as non-root user in Docker
  • βœ… Keep dependencies updated via Dependabot

See SECURITY.md for vulnerability reporting.


πŸ›£οΈ API Reference

Flow Endpoint (Data API)

Endpoint: POST /flows/endpoint/:flowName

Handles encrypted interactions during Flow execution.

Actions:

  • ping - Health check
  • INIT - Initialize Flow session
  • data_exchange - Process user input and navigate
  • navigate - Explicit screen navigation
  • complete - Mark Flow as completed

Headers:

Content-Type: application/json

Example Request (INIT):

{
  "version": "3.0",
  "action": "INIT",
  "flow_token": "unique_token_123",
  "encrypted_flow_data": "...",
  "encrypted_aes_key": "...",
  "initial_vector": "..."
}

Response: Encrypted Flow data with next screen

Webhook Endpoint

Endpoint: POST /webhooks/whatsapp

Receives nfm_reply events when user completes Flow.

Headers:

Content-Type: application/json
X-Hub-Signature-256: sha256=...

Example Payload:

{
  "entry": [{
    "changes": [{
      "value": {
        "messages": [{
          "type": "interactive",
          "interactive": {
            "type": "nfm_reply",
            "nfm_reply": {
              "response_json": "{\"flow_token\":\"...\",\"data\":...}",
              "name": "flow_name"
            }
          }
        }]
      }
    }]
  }]
}

Important: response_json is a string, must be parsed with JSON.parse().

Health Check

Endpoint: GET /health

Response:

{
  "status": "ok",
  "timestamp": "2025-01-27T12:00:00.000Z",
  "version": "1.0.0",
  "uptime": 3600,
  "database": "connected"
}

Swagger Documentation

Interactive API docs available at /docs when server is running.


πŸ“š Documentation

Official WhatsApp Flows Resources


πŸ§ͺ Development

Project Structure

whatsapp-flow/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ domain/              # Business entities and rules
β”‚   β”‚   β”œβ”€β”€ flows/           # Flow, FlowSession entities
β”‚   β”‚   β”œβ”€β”€ encryption/      # Encryption services
β”‚   β”‚   └── webhooks/        # Webhook events
β”‚   β”œβ”€β”€ application/         # Use cases (business logic)
β”‚   β”‚   β”œβ”€β”€ dtos/            # Data Transfer Objects
β”‚   β”‚   └── use-cases/       # HandleFlowRequest, ProcessWebhook
β”‚   β”œβ”€β”€ infrastructure/      # External implementations
β”‚   β”‚   β”œβ”€β”€ database/        # PostgreSQL repositories
β”‚   β”‚   β”œβ”€β”€ http/            # Express server & routes
β”‚   β”‚   └── security/        # Encryption implementation
β”‚   β”œβ”€β”€ shared/              # Common utilities
β”‚   └── main.ts              # Application entry point
β”œβ”€β”€ scripts/                 # Utility scripts
β”‚   β”œβ”€β”€ migrations/          # SQL migration files
β”‚   β”œβ”€β”€ generate-keys.ts     # RSA key generator
β”‚   └── seed-*.ts            # Database seeders
β”œβ”€β”€ .github/                 # CI/CD workflows
β”œβ”€β”€ docker-compose.yml       # Docker orchestration
β”œβ”€β”€ Dockerfile              # Multi-arch container
└── tsconfig.json           # TypeScript configuration

Available Scripts

# Development
npm run dev              # Start with watch mode
npm run build            # Build TypeScript
npm start                # Start production server

# Database
npm run migrate          # Run migrations

# Encryption
npm run generate-keys    # Generate RSA keys
npm run validate-keys    # Validate configuration
npm run register-key     # Register public key with Meta

# Code Quality
npm run lint             # Run ESLint
npm run format           # Format with Prettier
npm run format:check     # Check formatting

# Git
npm run commit           # Interactive commit helper (Conventional Commits)

Database Migrations

Migrations run automatically on container startup. To run manually:

# Local
npm run migrate

# Docker
docker-compose exec app npm run migrate

Adding New Flows

Method 1: Via API

curl -X POST http://localhost:3000/api/flows \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-flow",
    "version": "7.2",
    "flow_json": {"version":"7.2","screens":[...]},
    "description": "My custom flow"
  }'

Configure in WhatsApp Manager:

https://your-domain.com/flows/endpoint/my-flow

πŸš€ CI/CD Pipeline

Automated Workflows

This project includes complete CI/CD automation:

Continuous Integration (on every push/PR)

  • βœ… ESLint validation
  • βœ… Prettier format check
  • βœ… TypeScript compilation check
  • βœ… Application build test
  • βœ… Security audit (npm audit)

Semantic Release (on merge to main)

  • βœ… Analyze commits (Conventional Commits)
  • βœ… Calculate next version (major/minor/patch)
  • βœ… Generate CHANGELOG.md
  • βœ… Create GitHub Release
  • βœ… Build multi-arch Docker image (AMD64 + ARM64)
  • βœ… Publish to Docker Hub with semantic tags

Conventional Commits

# Patch version (1.0.0 β†’ 1.0.1)
git commit -m "fix: resolve webhook signature validation"

# Minor version (1.0.0 β†’ 1.1.0)
git commit -m "feat: add support for multiple flows"

# Major version (1.0.0 β†’ 2.0.0)
git commit -m "feat!: migrate to PostgreSQL 18

BREAKING CHANGE: Database volume path changed"

# No release
git commit -m "docs: update README"
git commit -m "chore: update dependencies"

GitHub Secrets Required

For automated Docker publishing:

DOCKER_USERNAME = your_dockerhub_username
DOCKER_TOKEN = your_dockerhub_token

🀝 Contributing

Contributions are welcome! Please follow these guidelines:

Getting Started

  1. Fork the repository
  2. Clone your fork: git clone https://github.com/YOUR_USERNAME/whatsapp-flow.git
  3. Create a branch: git checkout -b feat/amazing-feature
  4. Install dependencies: npm install
  5. Make your changes
  6. Test thoroughly
  7. Commit using Conventional Commits: git commit -m "feat: add amazing feature"
  8. Push to your fork: git push origin feat/amazing-feature
  9. Open a Pull Request

Code Standards

  • βœ… Follow TypeScript strict mode
  • βœ… Use Conventional Commits format
  • βœ… Pass all CI checks (lint, format, typecheck, build)
  • βœ… Add tests for new features
  • βœ… Update documentation as needed
  • βœ… Follow DDD architecture patterns

Pull Request Process

  1. Ensure CI passes (lint, format, typecheck, build)
  2. Update README.md if adding features
  3. Request review from maintainers
  4. Address review comments
  5. Squash commits before merge (if requested)

πŸ“Š Technology Stack

Category Technology Version
Runtime Node.js β‰₯ 20.0.0
Language TypeScript 5.9
Framework Express 5.x
Database PostgreSQL 18
Encryption Node RSA + Crypto Native
Validation Zod 4.x
Logging Winston 3.x
Container Docker Multi-arch
CI/CD GitHub Actions Latest
Versioning Semantic Release 23.x

πŸ“ˆ Performance

  • ⚑ Response Time: < 3s (WhatsApp requirement)
  • ⚑ Default Timeout: 2.5s (configurable)
  • πŸ“¦ Docker Image: ~150MB (multi-stage build)
  • πŸ”„ Startup Time: ~5-10s (includes migrations)
  • πŸ’Ύ Memory Usage: ~50-100MB (base)

πŸ› Troubleshooting

Common Issues

1. "Failed to decrypt AES key"

# Regenerate keys
npm run generate-keys

# Test encryption
npm run test-encryption

# Verify .env has correct format (with \n)

2. "Webhook signature validation failed"

# Verify META_APP_SECRET matches Meta dashboard
# Check webhook payload is valid JSON
# Ensure X-Hub-Signature-256 header is present

3. "Database connection refused"

# Check PostgreSQL is running
docker-compose ps

# Verify DATABASE_URL in .env
# Check network connectivity

4. "Migrations failed"

# Run manually with logs
docker-compose exec app npm run migrate

# Check database permissions
# Verify SQL syntax in migration files

5. "WhatsApp error 421"

# Verify IV flip is implemented
# Check encryption format (RSA-2048 + AES-128-GCM)
# Ensure public key is registered with Meta
npm run register-key

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

TL;DR: You can use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of this software. Just include the original copyright notice.


πŸ‘₯ Authors & Contributors

Guilherme Jansen - Initial work & Maintainer

Contributors Wall

List of contributors

Want to join the board? Check the contributing guide and open your first PR!

Special Thanks

  • Meta/WhatsApp team for the Flows API
  • DDD community for architectural patterns
  • Open source contributors

🌟 Star History

If this project helped you, please consider giving it a ⭐ on GitHub!

Star History Chart


πŸ“ž Support

Community Support

  • πŸ› Bug Reports: GitHub Issues
  • πŸ’‘ Feature Requests: GitHub Discussions
  • πŸ“– Documentation: Check docs in repository
  • πŸ’¬ Questions: Open a discussion

Professional Support

For enterprise support, custom integrations, or consulting:


πŸ—ΊοΈ Roadmap

  • Unit and integration tests
  • GraphQL API option
  • Admin dashboard (Flow management UI)
  • Multi-tenancy support
  • Flow analytics and metrics
  • Flow template marketplace
  • Kubernetes deployment guides
  • Horizontal scaling documentation
  • Rate limiting per Flow
  • Webhook retry mechanism

Made with ❀️ by Guilherme Jansen

⬆ Back to Top

About

WhatsApp Flow Server

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors