Skip to content

Repository files navigation

Exotel WhatsApp Dockerized App

Open-source, dockerized reference implementation to manage Exotel WhatsApp Business APIs with a REST backend and admin UI.

Disclaimer: This is an unofficial community project and is not affiliated with, endorsed by, or maintained by Exotel.

Built with Codex app and love from Bengaluru.

Features

  • REST API for auth, credential management, messaging, templates, onboarding links, and webhooks.
  • React admin UI for day-to-day operations (send tests, manage templates, view webhooks).
  • Queue-based sending with BullMQ + Redis; Prometheus metrics and health endpoints.
  • Docker-first: dev and prod compose files, multi-stage Dockerfiles for API and UI.

Stack

  • API: Node.js + TypeScript (Express), Prisma + PostgreSQL, Redis + BullMQ for queues
  • UI: React + Vite single-page app
  • Infra: Docker / docker-compose, optional Caddy reverse proxy

Prerequisites

  • Node.js 20+
  • npm
  • Docker and Docker Compose
  • Access to Exotel WhatsApp Business API credentials (api_key, api_token, subdomain, sid)

Quickstart (dev)

npm install
npm -w apps/api run prisma:generate
npm -w apps/api run prisma:migrate -- --name init
npm -w apps/api run prisma:seed
docker compose -f docker-compose.dev.yml up --build

Access:

Seed admin user

Use one of these commands to create the default admin user (admin@example.com / changeme):

Local npm run:

npm -w apps/api run prisma:seed

Docker (dev compose):

docker compose -f docker-compose.dev.yml run --rm api npm run prisma:seed

If the user already exists, the seed is safe to run again.

Configure environment

Copy apps/api/.env.example to .env in the same folder and set:

  • DATABASE_URL (e.g., postgresql://postgres:postgres@db:5432/exotel_whatsapp)
  • REDIS_URL
  • JWT_SECRET
  • EXOTEL_REGION (e.g., api.exotel.com or api.in.exotel.com)
  • EXOTEL_WEBHOOK_SECRET (optional, enables HMAC validation for incoming webhooks)

Provision Exotel credentials

Use the UI (Credentials page) or call POST /api/v1/credentials with label, apiKey, apiToken, subdomain, sid, region. All messaging/template/onboarding calls use these credentials. For template APIs against Exotel, also provide wabaId per request.

Production (compose)

docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml up -d
  • API exposed on port 4000
  • UI exposed on port 8080 via reverse proxy (Caddy)

GitHub Pages landing page

  • Source files: docs/index.html, docs/coverage.html, docs/openapi.yaml, docs/styles.css, docs/app.js, docs/CNAME
  • Deployment workflow: .github/workflows/pages.yml
  • Live URL: https://vinodspattar.in/Exotel-WhatsApp/
  • Coverage matrix URL: https://vinodspattar.in/Exotel-WhatsApp/coverage.html
  • Static OpenAPI URL: https://vinodspattar.in/Exotel-WhatsApp/openapi.yaml
  • In repository settings, set Pages source to GitHub Actions once.

API Surface (v1)

  • POST /api/v1/auth/login – email/password login
  • POST /api/v1/auth/refresh
  • GET/POST /api/v1/credentials
  • GET /api/v1/messages, GET /api/v1/messages/:id, POST /api/v1/messages (single or bulk), POST /api/v1/messages/:id/cancel
  • GET /api/v1/templates (local cache) or GET /api/v1/templates?remote=true&credentialId=...&wabaId=... for live Exotel list; POST /api/v1/templates; PUT /api/v1/templates/:id; DELETE /api/v1/templates; POST /api/v1/templates/upload-sample
  • GET /api/v1/onboarding-links, POST /api/v1/onboarding-links, GET /api/v1/onboarding-links/validate?token=...
  • POST /api/v1/webhooks/exotel, GET /api/v1/webhooks/logs
  • Health: /healthz, /readyz, metrics at /metrics
  • OpenAPI: /docs/openapi.yaml (file at apps/api/openapi.yml)

Coverage vs Exotel docs

Background Worker

  • Queue send-messages (BullMQ) sends outbound messages via Exotel.
  • Run with node dist/worker.js (already wired in compose).

Directory layout

  • apps/api – Express API, Prisma schema, queue worker, Dockerfile
  • apps/ui – React + Vite admin UI, Dockerfile
  • docker-compose.dev.yml – dev stack
  • docker-compose.prod.yml – prod stack + Caddy
  • deploy/Caddyfile – reverse proxy config

Testing

  • Placeholder vitest setup. Add unit tests for Exotel client, auth, queue handlers, and integration tests with Testcontainers.

Notes

  • Template, onboarding, and message sends are forwarded to Exotel; failures are returned as API errors and persisted in message/audit state.
  • Redis is recommended; without it, queue/rate-limit features will not work.

Contributing

  • Fork and clone, then create a feature branch (git checkout -b feature/xyz).
  • Keep changes lint-clean: npm run lint; add tests where possible (npm run test).
  • Ensure Prisma schema changes include migrations and regenerate client.
  • Submit PRs with a brief summary, testing notes, and screenshots for UI changes.
  • Respect the seed credentials; avoid committing real Exotel secrets.

License

MIT (see package.json).

About

Open-source, dockerized reference implementation to manage Exotel WhatsApp Business APIs with a REST backend and admin UI.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages