A full-stack WhatsApp Web-style chat application built for real-time business messaging using the Meta Cloud API for WhatsApp Business.
It features a responsive WhatsApp-inspired interface, secure authentication, message threading, media ingestion, webhook diagnostics, and a powerful admin dashboard.
- Overview
- Documentation
- Architecture
- Installation
- Environment Configuration
- Run Commands
- Project Structure
- Database Schema
- Media System
- Diagnostics & Debugging
- UI & Design Audit
- Common Issues
- Quality Assurance
- License
ChatSphere is a React + Node.js application that replicates WhatsApp Web UX with full backend control and integration to Meta Cloud API for WhatsApp Business.
It supports real-time messaging, conversation management, archiving, role-based access, and secure signed media delivery.
Key Features
- WhatsApp Web-style dual-panel UI
- Real-time WebSocket updates
- Reply-to message support
- Role-based authentication (Admin / User)
- Integrated webhook listener & diagnostics
- Signed media delivery & thumbnail generation
- PostgreSQL via Drizzle ORM
- Docker-ready for deployment
- Cloudflare Tunnel compatible for public SSL access
See docs/INDEX.md for the full documentation set.
- Stack: React + TypeScript + Vite + Tailwind CSS + shadcn/ui (Radix)
- State: TanStack Query for server state; local UI state for interactions
- Live updates: WebSocket hook + query invalidation
- Key Components:
ConversationListβ search, archive, pinningMessageThreadβ infinite scroll, skeletonsMessageBubbleβ dynamic layout & reply threadingMessageInputβ emoji picker, file upload
- Stack: Node.js + Express + TypeScript + WebSocket (ws) + Drizzle ORM
- Endpoints: REST CRUD for conversations, messages, users, settings
- Realtime: WebSocket at
/wsbroadcasting incoming/outgoing events - Webhook:
/webhook/metafor Meta signature-verified message intake - Auth: Session-based via Passport.js (scrypt password hashing)
- DB: PostgreSQL (local or Neon serverless)
Ensure the following are installed:
Node.js >= 18
PostgreSQL
GitOptional: run PostgreSQL via Docker
docker run --name whatsapp-db -e POSTGRES_PASSWORD=yourpassword -e POSTGRES_DB=whatsapp_chat -p 5432:5432 -d postgresgit clone https://github.com/yourusername/chatsphere.git
cd chatsphere
npm installpsql -U postgres
CREATE DATABASE whatsapp_chat;
CREATE USER whatsapp_user WITH PASSWORD 'securepassword';
GRANT ALL PRIVILEGES ON DATABASE whatsapp_chat TO whatsapp_user;
\q
npm run db:pushRun this Node script:
npm run seed:adminnpm run devVisit: http://localhost:8080
Create .env in the project root:
DATABASE_URL=postgresql://postgres:yourpassword@localhost:5432/whatsapp_chat
SESSION_SECRET=your-secret
FILES_SIGNING_SECRET=your-file-secret
META_PHONE_NUMBER_ID=your_meta_phone_number_id
META_TOKEN=your_meta_access_token
META_VERIFY_TOKEN=your_verify_token
META_APP_SECRET=your_meta_app_secret
NODE_ENV=development
PORT=8080Optional Media Config
MEDIA_SIGNED_URL_TTL_SECONDS=900
MEDIA_MAX_ORIGINAL_BYTES=25000000
MEDIA_THUMBNAIL_MAX_WIDTH=512
MEDIA_THUMBNAIL_MAX_HEIGHT=512
MEDIA_STORAGE_ROOT=uploads| Command | Description |
|---|---|
npm run dev |
Run in development mode |
npm run build |
Build production bundles |
npm run start |
Start production server |
npm run db:push |
Sync schema with DB |
npm run check |
TypeScript validation |
npm run seed:admin |
Create admin user |
chatsphere/
βββ client/
β βββ src/
β βββ components/
β βββ pages/
β βββ lib/
βββ server/
β βββ index.ts
β βββ auth.ts
β βββ routes.ts
β βββ providers/
β βββ storage.ts
βββ shared/
β βββ schema.ts
βββ uploads/
β βββ incoming/
β βββ outbound/
βββ .env
βββ package.json
βββ vite.config.ts
| Table | Fields |
|---|---|
users |
id, username, password, role |
whatsapp_instances |
id, name, token, phone_number_id, active |
conversations |
id, phone, displayName, archived, lastAt |
messages |
id, conversationId, direction, body, media, status, createdAt |
sessions |
id, userId, expiresAt |
One-to-many relation: conversation β messages
Drizzle ORM migrations handle schema consistency.
- Webhook Intake β
/webhook/metaverifies Meta signature and writes pending message withmessages.mediametadata. - Ingestion Queue β downloads media from Graph API, applies size limits, saves to
uploads/incoming/original. - Thumbnailing β via
sharp; saved touploads/incoming/thumbnails. - Persistence β database updates with media metadata and rebroadcasts via WebSocket.
- Delivery β
/media/*endpoint serves signed URLs (TTL 15 min).
Operator uploads stored under uploads/outbound/original, re-signed before sending to WhatsApp.
- Requires
FILES_SIGNING_SECRET - Graph URLs are never exposed β only signed local URLs.
Accessible via the user dropdown β Webhook Diagnostics
- Launch app and sign in as Admin.
- Navigate to
/diagnostics. - Test system status, send test messages, or debug webhook payloads.
GET /api/webhook/status/{instanceId}
POST /api/test-message
POST /webhook/debug/{instanceId}β
Webhook verified
π¬ Processing message from: +1234567890
πΎ Message saved: msg_456
π‘ Broadcast complete in 45ms
- Responsive split-pane desktop / single-pane mobile layout
- Consistent global actions (theme toggle, account menu)
- Message bubbles redesigned with balanced padding and typography
- Unified attachment previews (image, doc, pdf)
- Improved focus/hover states and accessibility feedback
- Mobile layout prioritizes reachable controls and single-pane thread navigation
| Problem | Solution |
|---|---|
| Instance not found | Verify instance exists and active |
| Invalid signature | Check META_APP_SECRET and webhook signature |
| Database connection failed | Verify DATABASE_URL and service is running |
| No messages showing | Check WebSocket connection |
| Port in use | `lsof -ti:8080 |
Before release, validate all media and messaging flows:
- Send inbound images, PDFs, and DOCX/XLSX/TXT/ZIP files
- Confirm thumbnail rendering and accessibility
- Verify expired URLs regenerate correctly
- Test mobile responsiveness β€420px
- Run through diagnostic tool for each instance
This project is released under the MIT License.
Feel free to fork, modify, and contribute.