Skip to main content

Production-ready Django WhatsApp Cloud Platform — Inbox, Campaigns, Templates, Analytics

Project description

django-meta-whatsapp

A production-ready Django WhatsApp Cloud Platform you can drop into any Django project.

Features

  • Inbox — Real-time chat interface with media, location pins, reply threading, message status ticks
  • Contacts — CSV import/export, tagging, opt-out management
  • Templates — Create, edit, push to Meta, sync from Meta
  • Campaigns — Bulk messaging with pluggable audience system, CSV support, scheduled sends
  • Analytics — Delivery/read tracking, 30-day trend chart
  • Webhooks — Automatic inbound message sync, status updates, reaction handling
  • REST APIs — Send text, location, template; list chats/campaigns (API-key auth)
  • Django Admin — Full admin panel for all models
  • Multi-account — One Django project, multiple WhatsApp Business Accounts
  • Signals — Hook into message received/sent and campaign completed events
  • Celery support — Optional background campaign processing

Installation

pip install django-meta-whatsapp
# or from source:
pip install -e .

Also install django-tailwind-cli (no Node required):

pip install django-tailwind-cli

Quick Setup

1. settings.py

INSTALLED_APPS = [
    ...
    "django_tailwind_cli",
    "django_meta_whatsapp",
]

# Single-account shortcut (alternative: use WhatsAppAccount model in dashboard)
WHATSAPP = {
    "ACCESS_TOKEN": "your_meta_access_token",
    "PHONE_NUMBER_ID": "your_phone_number_id",
    "WABA_ID": "your_waba_id",            # needed for template sync
    "VERIFY_TOKEN": "your_verify_token",  # for webhook verification
    "LOGIN_URL": "/accounts/login/",      # redirect for unauthenticated users
}

2. urls.py

from django.urls import path, include

urlpatterns += [
    path("whatsapp/", include("django_meta_whatsapp.urls")),
]

3. Migrate

python manage.py migrate

4. Tailwind CSS

python manage.py tailwind build

Open http://yoursite/whatsapp/ — done.


Optional Dashboard Configuration

You can customize the look and feel of the WhatsApp Dashboard directly from your settings.py. All of these settings are optional!

# settings.py

# Replace the text name in the sidebar (default: "WhatsApp")
META_WHATSAPP_DASHBOARD_NAME = "My Custom App"

# Change the Lucide icon used in the sidebar (default: "message-circle")
META_WHATSAPP_DASHBOARD_ICON = "building-2"

# Or, use a complete custom image logo instead of the icon
META_WHATSAPP_DASHBOARD_LOGO = "/static/logo.png"

# Change the primary accent color of the entire dashboard! (Provide an HSL triplet)
META_WHATSAPP_ACCENT_COLOR = "142, 72%, 45%"   # Emerald green

Multi-Account Support

Add accounts in the Settings → Accounts dashboard. Each account has its own:

  • Access Token
  • Phone Number ID
  • WABA ID
  • Verify Token

The webhook endpoint (/whatsapp/webhook/) auto-routes to the correct account by phone_number_id.


Pluggable Audience System

The package never assumes your user model. You control who receives campaigns.

Option 1: Named audience providers

# myapp/whatsapp_audiences.py
from myapp.models import Customer

def vip_customers():
    return Customer.objects.filter(total_orders__gt=10)

def inactive_users():
    return Customer.objects.filter(is_active=False)
# settings.py
WHATSAPP = {
    ...
    "PHONE_FIELD": "mobile",      # field on your model that holds the phone number
    "NAME_FIELD": "full_name",    # field for the display name
    "AUDIENCES": {
        "VIP Customers": "myapp.whatsapp_audiences.vip_customers",
        "Inactive Users": "myapp.whatsapp_audiences.inactive_users",
    },
}

The campaign form will show these as audience choices.

Option 2: Full campaign resolver

# settings.py
WHATSAPP = {
    ...
    "CAMPAIGN_RESOLVER": "myapp.whatsapp_audiences.resolve_campaign",
}
# myapp/whatsapp_audiences.py
def resolve_campaign(campaign):
    """
    Return list of dicts: [{"phone": "919...", "name": "...", "params": {...}}, ...]
    """
    if campaign.audience_type == "vip":
        qs = Customer.objects.filter(total_orders__gt=10)
        return [{"phone": c.mobile, "name": c.full_name, "params": {}} for c in qs]
    return []

Option 3: Built-in WhatsAppContact list

Set audience_type = "contacts" — sends to all non-opted-out WhatsAppContact records.

Option 4: CSV Upload

Set audience_type = "csv" and upload a CSV with phone, name columns in the campaign form.


Sending Messages Programmatically

from django_meta_whatsapp.utils import (
    send_text_message,
    send_location_message,
    send_template_message,
    send_media_message,
    upload_media,
    build_template_components,
)

# Text
send_text_message("919876543210", "Hello from Django!")

# Location pin
send_location_message(
    "919876543210",
    latitude=24.5854,
    longitude=73.7125,
    name="Udaipur Office",
    address="Hiran Magri, Udaipur, Rajasthan",
)

# Template with variables
components = build_template_components(body_params=["Rakesh", "ORD-1234"])
send_template_message("919876543210", "order_confirmation", components=components)

# Media
with open("invoice.pdf", "rb") as f:
    media_id = upload_media(f, "application/pdf")
send_media_message("919876543210", media_id, "document", filename="invoice.pdf")

Signals

from django.dispatch import receiver
from django_meta_whatsapp.signals import (
    whatsapp_message_received,
    whatsapp_message_sent,
    whatsapp_campaign_completed,
)

@receiver(whatsapp_message_received)
def on_inbound(sender, message, **kwargs):
    print(f"New message from {message.phone_number}: {message.message_body}")

@receiver(whatsapp_campaign_completed)
def on_campaign_done(sender, campaign, sent, failed, **kwargs):
    print(f"Campaign '{campaign.name}' finished: {sent} sent, {failed} failed")

Celery (optional)

# settings.py
WHATSAPP_USE_CELERY = True

Campaigns will be queued as Celery tasks instead of running synchronously.


REST API

All endpoints require X-API-Key header (create keys in Settings → API Keys).

Method Endpoint Description
POST /whatsapp/api/send-message/ Send text message
POST /whatsapp/api/send-location/ Send location pin
POST /whatsapp/api/send-template/ Send approved template
GET /whatsapp/api/chats/ List recent conversations
GET /whatsapp/api/campaigns/ List campaigns

Send text

POST /whatsapp/api/send-message/
X-API-Key: your-key
Content-Type: application/json

{"phone": "919876543210", "message": "Hello!"}

Send location

POST /whatsapp/api/send-location/
X-API-Key: your-key
Content-Type: application/json

{
  "phone": "919876543210",
  "latitude": 24.5854,
  "longitude": 73.7125,
  "name": "Our Store",
  "address": "Udaipur, Rajasthan"
}

Send template

POST /whatsapp/api/send-template/
X-API-Key: your-key
Content-Type: application/json

{
  "phone": "919876543210",
  "template_name": "order_confirmation",
  "language": "en",
  "body_params": ["Rakesh", "ORD-1234"]
}

Webhook Configuration

Set your Meta webhook URL to:

https://yourdomain.com/whatsapp/webhook/

The verify token is either:

  1. The verify_token field on a WhatsAppAccount (multi-account)
  2. WHATSAPP["VERIFY_TOKEN"] in settings (single-account)

Management Commands

# Sync templates from Meta
python manage.py wa_sync_templates

# Sync for a specific account
python manage.py wa_sync_templates --account-id 1

Models Reference

Model Purpose
WhatsAppAccount Multi-account credentials
WhatsAppContact Contact directory
WhatsAppConversation Grouped chat threads
WhatsAppMessage Individual messages (text, media, location, etc.)
WhatsAppTemplate Meta-approved message templates
WhatsAppCampaign Bulk send campaigns
WhatsAppCampaignRecipient Per-recipient status tracking
WhatsAppMedia Uploaded media library
WhatsAppWebhookLog Raw webhook event logs
WhatsAppAPIKey REST API authentication keys

Environment Variables (alternative to settings.py)

META_WA_ACCESS_TOKEN=EAAx...
META_WA_PHONE_NUMBER_ID=1234567890
META_WABA_ID=9876543210
META_WA_VERIFY_TOKEN=my_secret_verify_token

License

MIT

Developer

Created by Rahul Baberwal.

Repository: https://github.com/rahul-baberwal/django-meta-whatsapp/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_meta_whatsapp-1.0.1.tar.gz (68.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_meta_whatsapp-1.0.1-py3-none-any.whl (82.6 kB view details)

Uploaded Python 3

File details

Details for the file django_meta_whatsapp-1.0.1.tar.gz.

File metadata

  • Download URL: django_meta_whatsapp-1.0.1.tar.gz
  • Upload date:
  • Size: 68.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_meta_whatsapp-1.0.1.tar.gz
Algorithm Hash digest
SHA256 e49c8e93f970edf7948a11d3119eb5d3e1d37fd24f24bbc15f866e97b964cc3a
MD5 2d71263857a92675a1aeaaac7f218970
BLAKE2b-256 6a508f28738607999f56f49ce55554b6a52466e00a4dc6a7d2db3366d7dfbb23

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_meta_whatsapp-1.0.1.tar.gz:

Publisher: publish.yml on rahul-baberwal/django-meta-whatsapp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_meta_whatsapp-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_meta_whatsapp-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e1128719479ef060a54974f25fcabd014c5625bb19991468a34c3a34bbaca8b5
MD5 0be3974cc01eb0f86134c711384d9580
BLAKE2b-256 d042414a9116bb77ea16a04872f6a1875766f86d3225b0bc1c04bd760d388597

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_meta_whatsapp-1.0.1-py3-none-any.whl:

Publisher: publish.yml on rahul-baberwal/django-meta-whatsapp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page