Whatsapp Integration
A reusable Django app providing enterprise-grade WhatsApp Business API integration with message queuing, Celery task orchestration, Redis-based rate limiting (Lua token bucket), idempotency, and webhook handling.
Designed for production environments and multi-project reusability, this package provides a scalable way to send, track, and process WhatsApp messages across your Django applications.
✨ Features
- ✅ Reusable Django app – install once, integrate anywhere
- 🚀 Celery task orchestration – background message processing with exponential backoff
- 🧠 Idempotency & retry safety – prevents duplicate messages during failures
- 🔐 Secure webhook verification – HMAC validation and token-based verification
- 💬 Unified service API –
send_textandsend_templatewith optional components - 🧩 Redis Lua rate limiter – atomic token bucket algorithm for scalable throughput
- ⚙️ Configurable – all keys & tokens loaded from Django
settings.py - 🧱 PostgreSQL-optimized schema – indexed queries for performance
- 🧰 CI/CD & Docker ready – comes with workflows, Dockerfile, and docker-compose
- 📄 PDF Generator Tool – generate a full repo snapshot in a single PDF
🧩 Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ | Django App │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ whatsapp_integration │ │
│ │ ├── models.py ← WhatsAppMessage, WebhookEvent │ │
│ │ ├── services/ ← WhatsAppService abstraction │ │
│ │ ├── tasks.py ← Celery async workers │ │
│ │ ├── rate_limiter/ ← Redis Lua token bucket │ │
│ │ ├── views.py ← Webhook endpoints │ │
│ │ ├── commands.py ← Command + Event dispatcher │ │
│ │ └── utils.py ← Error classification, helpers │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
🛠 Installation
1️⃣ Install from PyPI (or locally)
pip install whatsapp_integration
⚙️ Configuration
- Add the app to your Django settings:
INSTALLED_APPS = [
...
"whatsapp_integration",
]
- Environment Variables / Settings
WHATSAPP_PHONE_NUMBER_ID = "1234567890"
WHATSAPP_ACCESS_TOKEN = "your_long_lived_graph_api_token"
WHATSAPP_VERIFY_TOKEN = "your_webhook_verify_token"
WHATSAPP_APP_SECRET = "facebook_app_secret" # optional but recommended
WHATSAPP_RATE_PER_SECOND = 1.5 # messages per second allowed
REDIS_URL = "redis://localhost:6379/0"
- Make migrations
python manage.py makemigrations
- migrate
python manage.py migrate
- Celery Setup
In your settings.py:
CELERY_BROKER_URL = "redis://localhost:6379/0"
CELERY_RESULT_BACKEND = "redis://localhost:6379/0"
Then in your project root:
celery -A your_project worker -l info
🔄 Sending Messages
Use the service directly or queue messages for asynchronous processing.
Example: Send text message immediately
from whatsapp_integration.services import whatsapp_service
whatsapp_service.default_whatsapp_service.send_text(
recipient="15551234567",
message="Hello from Django WhatsApp Integration!"
)
Example: Queue message for async send via Celery
from whatsapp_integration.models import WhatsAppMessage
from whatsapp_integration.tasks import send_whatsapp_message_task
msg = WhatsAppMessage.objects.create(
recipient="15551234567",
message_type="text",
payload={"body": "Queued message test"}
)
send_whatsapp_message_task.delay(str(msg.id))
📬 Handling Webhooks
Facebook/WhatsApp will send inbound messages or delivery updates to your webhook.
URL Mapping
Add to your root urls.py:
urlpatterns = [
...
path("api/v1/whatsapp/", include("whatsapp_integration.urls")),
]
This registers:
GET api/v1/whatsapp/webhook/verify/ → for verification handshake
POST api/v1/whatsapp/webhook/ → for inbound message events
Example verification response
GET api/v1/whatsapp/webhook/verify/?hub.mode=subscribe&hub.verify_token=YOUR_TOKEN&hub.challenge=CHALLENGE
Returns CHALLENGE if token matches.
🚦 Rate Limiting (Lua + Redis)
How it works
A token bucket algorithm written in Lua ensures you never exceed Meta’s rate limits:
Each message consumes a “token”.
Tokens regenerate over time according to WHATSAPP_RATE_PER_SECOND.
Fully atomic via Redis EVALSHA (no race conditions).
Lua script: lua_token_bucket.lua
Settings WHATSAPP_RATE_PER_SECOND = 1.0
🧠 Reliability & Idempotency
-
Each message is stored with a unique idempotency_key
-
Retries use the same key to avoid duplicate delivery
-
Failed messages persist for visibility and can be retried manually
Celery Task Behavior
- Exponential backoff retry (2^n seconds)
- acks_late=True to avoid loss on worker crash
- Max 8 retries before marking message as failed
🔐 Webhook Security
-
Optional HMAC verification (X-Hub-Signature-256)
-
Prevents spoofed or replayed requests
-
Use your Facebook App Secret for signing
🧩 Database Schema
WhatsAppMessage
| Field | Type | Notes |
|---|---|---|
| recipient | CharField |
phone number |
| message_type | text / template |
message category |
| payload | JSONField |
message body / components |
| status | queued / sent / failed / delivered |
lifecycle state |
| idempotency_key | UUID |
prevents duplicates |
| attempts | Integer |
number of retries |
| created_at | DateTime |
timestamp |
WhatsAppWebhookEvent
| Field | Type | Description |
|---|---|---|
| event_id | CharField |
deduplication key |
| payload | JSONField |
raw webhook payload |
| processed | Boolean |
flag to avoid re-handling |
Includes:
-
Webhook verification test
-
Event persistence test
(Extendable for rate limiter and Celery integration)
🧱 Deploying
Recommended environment:
-
PostgreSQL
-
Redis 7+
-
Gunicorn with 2–4 workers
-
Celery worker pool (concurrency >= 4)
-
Nginx reverse proxy for SSL termination
Production tips:
-
Use environment variables for tokens
-
Rotate access tokens periodically
-
Enable HTTPS and secure webhook secret
💡 Extending Functionality
-
Add custom event handlers via register_handler in commands.py
-
Extend rate limiter for per-tenant quotas
-
Plug in Prometheus metrics to monitor message throughput
-
Integrate with an internal analytics pipeline via Celery chains
🏗 Performance Best Practices
-
Use persistent Redis connection pools (max_connections=100)
-
Deploy Celery worker with concurrency matching CPU cores
-
Shard messages across multiple phone numbers if exceeding rate limits
-
Use DB connection pooling (e.g. pgBouncer)
-
Enable GZIP compression on webhook endpoints for large payloads
📜 License
MIT License © 2025 OFFSIDE INTEGRATED TECHNOLOGY (Somtochukwu Emmanuel)
🤝 Contributing
Fork this repo
Create a feature branch
git checkout -b feature/awesome
Commit changes
git commit -m 'Add awesome feature'
Push branch and open a PR 🎉
📞 Support
For enterprise inquiries, please contact offsideint@gmail.com
For bugs, open an issue on GitHub.
Built with ❤️ by OFFSIDE INTEGRATED TECHNOLOGY — because WhatsApp deserves enterprise-grade Django integration.
Release files for whatsapp-integration 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| whatsapp_integration-0.2.2.tar.gz | 16.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| whatsapp_integration-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.3 kB
Release files / whatsapp_integration-0.2.2.tar.gz
| Download URL | whatsapp_integration-0.2.2.tar.gz |
|---|---|
| Size | 16.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4ac70d21cd4957163bf9c7739a82f66db0a6e410d41f818b4c39e2c84c6240f4
|
|
BLAKE2b-256 checksum How to use checksums |
1e260de1e697a9368e0e4a5f031044b3eae08bf997cb2df7eb3ab3287a50d52f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|
Release files / whatsapp_integration-0.2.2-py3-none-any.whl
| Download URL | whatsapp_integration-0.2.2-py3-none-any.whl |
|---|---|
| Size | 17.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0754280e5290e35e7e4072cbfa2596dde198d091628644f36899033627c0040e
|
|
BLAKE2b-256 checksum How to use checksums |
34d8b09b3790f12c0630e5d6cefc48ec2c53a266a177b7e217005579f2e65ceb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|