12 KiB
WhatsApp Campaign Manager
A production-quality monorepo application for managing WhatsApp marketing campaigns with full compliance guardrails, contact management, and multi-provider messaging support.
🚀 Features
Contact Management
- Import from Multiple Sources: Excel (.xlsx), CSV, and Google Contacts
- Phone Number Normalization: Automatic E.164 format conversion
- Tag & Segment: Organize contacts with tags and lists
- Opt-in Management: Track opt-in status for compliance
- DND List: Global do-not-disturb blacklist
Campaign Management
- Template System: Create reusable message templates with variables ({{first_name}}, etc.)
- WhatsApp Templates: Support for approved WhatsApp Business templates
- Preview Recipients: See eligible contacts before sending
- Real-time Tracking: Monitor delivery statuses (sent, delivered, read, failed)
- Batch Processing: Automatic batching with rate limiting
Compliance & Safety
- ✅ Opt-in Enforcement: Only send to opted-in contacts
- ✅ DND List: Global blacklist that blocks all sends
- ✅ Rate Limiting: Per-minute and daily limits
- ✅ Template Enforcement: Approved templates required for cold outreach
- ✅ Conversation Window: Free-form messages only when window is open
- ✅ Audit Logging: Every send attempt is logged
- ✅ No Unofficial Automation: Uses official WhatsApp Cloud API only
Technical Features
- Provider Abstraction: Easy switching between WhatsApp providers
- Mock Provider: Local testing without external API calls
- WhatsApp Cloud API: Production-ready Meta integration
- Webhook Handler: Automatic status updates from provider
- Background Jobs: Async processing with retry logic
- JWT Authentication: Secure user sessions
- Role-Based Access: Admin and user roles
🏗️ Architecture
/whats-sender/
├── backend/ # FastAPI Python backend
│ ├── app/
│ │ ├── api/ # REST API endpoints
│ │ ├── core/ # Config, security, dependencies
│ │ ├── db/ # Database connection
│ │ ├── models/ # SQLAlchemy models
│ │ ├── schemas/ # Pydantic schemas
│ │ ├── services/ # Business logic
│ │ ├── providers/ # WhatsApp provider abstraction
│ │ ├── utils/ # Helper functions
│ │ └── main.py # FastAPI app
│ ├── alembic/ # Database migrations
│ ├── tests/ # Unit tests
│ └── requirements.txt
├── frontend/ # React + Vite frontend
│ ├── src/
│ │ ├── api/ # API client
│ │ ├── components/ # Reusable UI components
│ │ ├── contexts/ # React contexts
│ │ ├── pages/ # Page components
│ │ ├── styles/ # CSS
│ │ └── App.jsx
│ └── package.json
├── docker-compose.yml # Docker orchestration
└── README.md
📋 Prerequisites
For WhatsApp Cloud API (Production)
- Facebook Business Account: Create at business.facebook.com
- WhatsApp Business API Access: Apply through Meta
- Phone Number: Verified business phone number
- Access Token: Long-lived access token from Facebook
- Template Approval: Pre-approve message templates in Business Manager
For Google Contacts Import
- Google Cloud Project: Create at console.cloud.google.com
- Enable People API: In APIs & Services
- OAuth 2.0 Credentials: Create Web Application credentials
- Authorized Redirect URI: Add
http://localhost:8000/api/imports/google/callback
For Local Development
- Docker & Docker Compose
- OR: Python 3.11+, Node.js 18+, PostgreSQL 15+
🚀 Quick Start
1. Clone and Configure
cd whats-sender
# Backend environment
cp backend/.env.example backend/.env
# Edit backend/.env with your credentials
# Frontend environment
cp frontend/.env.example frontend/.env
2. Start with Docker Compose
docker-compose up -d
Services will be available at:
- Frontend: http://localhost:5173
- Backend API: http://localhost:8000
- API Docs: http://localhost:8000/docs
- PostgreSQL: localhost:5432
3. Initialize Database
# Run migrations
docker-compose exec backend alembic upgrade head
4. Create First User
Visit http://localhost:5173/register and create an account.
⚙️ Configuration
Backend Environment Variables
# Database
DATABASE_URL=postgresql://whatssender:whatssender123@postgres:5432/whatssender
# JWT Authentication
JWT_SECRET=your-secret-key-min-32-chars
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=10080 # 7 days
# CORS
CORS_ORIGINS=http://localhost:3000,http://localhost:5173
# Google OAuth (Optional)
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://localhost:8000/api/imports/google/callback
# Generate: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
GOOGLE_TOKEN_ENCRYPTION_KEY=your-fernet-key-base64
# WhatsApp Provider
WHATSAPP_PROVIDER=mock # or "cloud" for production
WHATSAPP_CLOUD_ACCESS_TOKEN=your-meta-access-token
WHATSAPP_CLOUD_PHONE_NUMBER_ID=your-phone-number-id
WHATSAPP_WEBHOOK_VERIFY_TOKEN=your-random-token
# Rate Limiting
MAX_MESSAGES_PER_MINUTE=20
BATCH_SIZE=10
DAILY_LIMIT_PER_CAMPAIGN=1000
Frontend Environment Variables
VITE_API_URL=http://localhost:8000
📱 WhatsApp Cloud API Setup
1. Get Access Token
- Go to developers.facebook.com
- Create/Select your App
- Add WhatsApp product
- Go to API Setup → Get a token
- Copy the Permanent Access Token (generate from temporary token)
2. Get Phone Number ID
In the same API Setup page, copy your Phone Number ID.
3. Register Webhook
- Go to Configuration → Webhooks
- Click "Edit"
- Callback URL:
https://your-domain.com/api/webhooks/whatsapp - Verify Token: Same as
WHATSAPP_WEBHOOK_VERIFY_TOKEN - Subscribe to:
messagesfield
4. Create Message Templates
- Go to WhatsApp Manager → Message Templates
- Create templates following Meta guidelines
- Wait for approval (usually 24-48 hours)
- Use template name in app's
provider_template_namefield
🔧 Development
Backend Development
cd backend
# Install dependencies
pip install -r requirements.txt
# Create .env file
cp .env.example .env
# Run migrations
alembic upgrade head
# Start server
uvicorn app.main:app --reload
# Run tests
pytest
Frontend Development
cd frontend
# Install dependencies
npm install
# Start dev server
npm run dev
# Build for production
npm run build
Running Workers
The worker processes background jobs (campaign sending). For development:
# Manual trigger (call this endpoint periodically)
curl -X POST http://localhost:8000/api/workers/tick
For production, set up a cron job:
*/1 * * * * curl -X POST http://localhost:8000/api/workers/tick
Or use Celery (advanced):
# Install celery and redis
pip install celery redis
# Start worker
celery -A app.workers worker --loglevel=info
📊 Usage Guide
1. Import Contacts
Excel/CSV Import:
- Prepare file with columns:
phone,first_name,last_name,email,opted_in - Go to Imports page
- Upload file
- Review summary
Google Contacts:
- Click "Connect Google Account"
- Authorize access
- Click "Sync Contacts"
2. Create Lists
- Go to Lists page
- Click "Create List"
- Add contacts to list from Contacts page
3. Create Templates
- Go to Templates page
- Click "Create Template"
- Use
{{first_name}},{{last_name}}, etc. for personalization - For WhatsApp templates: Check "Approved WhatsApp Template" and enter template name from Business Manager
4. Create Campaign
- Go to Campaigns page
- Click "Create Campaign"
- Select template and list
- Preview recipients
- Click "Send"
5. Monitor Campaign
- Click on campaign name
- See recipient statuses in real-time
- Webhook updates statuses automatically
🔒 Compliance Best Practices
Before Sending
- ✅ Verify all contacts have opted in OR use approved templates
- ✅ Check DND list is up to date
- ✅ Review daily/rate limits
- ✅ Test with MockProvider first
Message Guidelines
- Use approved templates for first contact
- Free-form messages only for existing conversations
- Personalize with variables
- Keep messages professional
- Include opt-out instructions
Data Privacy
- Store only necessary contact info
- Respect DND requests immediately
- Encrypt sensitive data (tokens, etc.)
- Log all activities for audit
- Comply with GDPR/local regulations
🧪 Testing
Unit Tests
cd backend
pytest tests/
Testing with MockProvider
Set WHATSAPP_PROVIDER=mock in .env. This simulates sending without external calls.
Integration Testing
- Create test contacts with your own phone
- Mark them as opted-in
- Create small test campaign
- Verify messages arrive
🚨 Troubleshooting
"Invalid phone number" errors
- Ensure phones are in E.164 format (+1234567890)
- Check country code is valid
- Use phone normalization in imports
"Template not found" errors
- Verify template is approved in Business Manager
- Check
provider_template_namematches exactly - Wait 24-48h after template submission
"Rate limit exceeded"
- Check
MAX_MESSAGES_PER_MINUTEsetting - Review daily limit in
DAILY_LIMIT_PER_CAMPAIGN - Stagger campaigns over time
Webhook not receiving updates
- Verify callback URL is publicly accessible (use ngrok for local testing)
- Check verify token matches
- Review webhook logs in Meta Developer Portal
📈 Production Deployment
Recommended Stack
- Backend: Deploy on Railway, Render, or AWS ECS
- Frontend: Vercel, Netlify, or Cloudflare Pages
- Database: Managed PostgreSQL (AWS RDS, Render, etc.)
- Workers: Background tasks on same platform or Celery with Redis
- Domain: Custom domain with SSL
Security Checklist
- Change all default passwords
- Use strong JWT_SECRET (32+ chars)
- Enable HTTPS only
- Set proper CORS origins
- Rotate access tokens regularly
- Monitor rate limits
- Set up error tracking (Sentry)
- Enable database backups
- Review logs regularly
Scaling Considerations
- Use connection pooling for database
- Add Redis for caching and Celery
- Horizontal scaling for API servers
- CDN for frontend assets
- Monitor provider rate limits
- Consider multiple WhatsApp numbers for higher volume
💰 Pricing Notes
WhatsApp Cloud API Pricing (Meta)
- Conversations: Charged per 24-hour conversation window
- Business-Initiated: Higher cost (~$0.01-0.10 per conversation, varies by country)
- User-Initiated: Free or lower cost
- Template Messages: Count as business-initiated
- Free Tier: 1,000 conversations/month
Always check current pricing at developers.facebook.com/docs/whatsapp/pricing
🤝 Contributing
This is a production template. Customize for your needs:
- Add custom fields to Contact model
- Implement additional providers (Twilio, MessageBird, etc.)
- Add more analytics and reporting
- Enhance UI/UX
- Add A/B testing for templates
- Implement scheduled campaigns
- Add webhook retry logic
📄 License
MIT License - Feel free to use for commercial or personal projects.
⚠️ Disclaimer
This software is provided as-is. Users are responsible for:
- Complying with WhatsApp Business Terms of Service
- Following local marketing/spam regulations (CAN-SPAM, GDPR, etc.)
- Obtaining proper consent from contacts
- Maintaining data security and privacy
- Using official WhatsApp APIs only
The developers are not liable for misuse or violations of terms of service.
🆘 Support
For issues:
- Check this README
- Review API documentation at
/docs - Check error logs
- Review Meta WhatsApp documentation
- Test with MockProvider first
Built with ❤️ for compliant marketing automation