Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/rahul-baberwal/django-meta-whatsapp/llms.txt

Use this file to discover all available pages before exploring further.

The django_meta_whatsapp.utils module contains all low-level wrappers around the Meta WhatsApp Cloud API v22.0. Every function accepts an optional account (WhatsAppAccount instance) parameter; when omitted, credentials are read from the WHATSAPP Django settings dict.

Import

from django_meta_whatsapp.utils import (
    send_text_message,
    send_location_message,
    send_media_message,
    send_template_message,
    build_template_components,
    upload_media,
    sync_templates_from_meta,
    push_template_to_meta,
    delete_template_from_meta,
    resolve_audience,
    run_campaign,
    run_campaign_async,
    sync_catalog_products,
    send_single_product_message,
    send_multi_product_message,
    send_catalog_message,
    send_product_carousel_message,
    send_catalog_link_message,
    block_users,
    unblock_users,
    get_blocked_users,
    sync_blocked_users_from_meta,
    create_signup,
    update_signup,
    disable_signup,
    list_signups,
    get_signup,
)

Messaging Functions

send_text_message

send_text_message(phone_number, text, reply_message_id=None, account=None) -> dict
Sends a plain text WhatsApp message.
ParameterTypeDescription
phone_numberstrRecipient phone with or without + and country code. 10-digit numbers default to +91 (India).
textstrMessage body string.
reply_message_idstr | NoneOptional Meta message ID to reply to (sets context.message_id).
accountWhatsAppAccount | NoneOptional account instance; uses WHATSAPP settings if None.
Returns: Meta API response dict. The sent message WAMID is at response["messages"][0]["id"].
from django_meta_whatsapp.utils import send_text_message

resp = send_text_message("919876543210", "Hello!")
print(resp["messages"][0]["id"])  # wamid.ABC123

send_location_message

send_location_message(
    phone_number,
    latitude,
    longitude,
    name='',
    address='',
    reply_message_id=None,
    account=None,
) -> dict
Sends a location pin message.
ParameterTypeDescription
phone_numberstrRecipient phone number.
latitudefloatDecimal degrees latitude.
longitudefloatDecimal degrees longitude.
namestrOptional location label shown in chat.
addressstrOptional address text shown below the pin.
reply_message_idstr | NoneOptional Meta message ID to reply to.
accountWhatsAppAccount | NoneOptional account instance.
Returns: Meta API response dict.
from django_meta_whatsapp.utils import send_location_message

send_location_message(
    "919876543210",
    latitude=28.6139,
    longitude=77.2090,
    name="New Delhi Office",
    address="Connaught Place, New Delhi",
)

upload_media

upload_media(file_obj, mime_type, account=None) -> str
Uploads a file to Meta and returns the media_id string.
ParameterTypeDescription
file_objfile-like objectE.g. Django InMemoryUploadedFile or open().
mime_typestrMIME type string, e.g. "image/jpeg", "application/pdf".
accountWhatsAppAccount | NoneOptional account instance.
Returns: media_id string for use in send_media_message().
.m4a files are automatically re-typed to audio/mp4 for Meta compatibility. This applies both when the filename ends in .m4a and when mime_type is "audio/x-m4a" or "audio/m4a".
from django_meta_whatsapp.utils import upload_media, send_media_message

with open("invoice.pdf", "rb") as f:
    media_id = upload_media(f, "application/pdf")

send_media_message(
    "919876543210",
    media_id=media_id,
    media_type="document",
    filename="invoice.pdf",
)

send_media_message

send_media_message(
    phone_number,
    media_id,
    media_type,
    caption='',
    filename='document',
    reply_message_id=None,
    account=None,
) -> dict
Sends a pre-uploaded media file.
ParameterTypeDescription
phone_numberstrRecipient phone number.
media_idstrID returned by upload_media().
media_typestrOne of "image", "video", "audio", "document".
captionstrOptional caption (supported for image, video, and document).
filenamestrDocument filename shown to the recipient (document type only).
reply_message_idstr | NoneOptional Meta message ID to reply to.
accountWhatsAppAccount | NoneOptional account instance.
Returns: Meta API response dict.

send_template_message

send_template_message(
    phone_number,
    template_name,
    language_code='en',
    components=None,
    account=None,
) -> dict
Sends an approved WhatsApp template message.
ParameterTypeDescription
phone_numberstrRecipient phone number.
template_namestrExact name of the approved template on Meta.
language_codestrBCP-47 language code, e.g. "en", "hi", "en_US".
componentslist | NonePre-built list from build_template_components(). If None, sends with no variables.
accountWhatsAppAccount | NoneOptional account instance.
Returns: Meta API response dict.
from django_meta_whatsapp.utils import send_template_message, build_template_components

components = build_template_components(
    body_params=["Rahul", "ORD-999"],
)
send_template_message("919876543210", "order_update", components=components)

build_template_components

build_template_components(header_params=None, body_params=None, buttons=None) -> list
Helper to build a Meta template components list from plain Python values.
ParameterTypeDescription
header_paramslist[str] | NoneText variable values for the header {{1}}, {{2}}
body_paramslist[str] | NoneText variable values for the body {{1}}, {{2}}… in order.
buttonslist[dict] | NoneEach dict: {"index": 0, "sub_type": "url"|"quick_reply", "payload": "..."}.
Returns: Ready-to-pass components list for send_template_message().
from django_meta_whatsapp.utils import build_template_components

components = build_template_components(
    header_params=["Order Shipped"],
    body_params=["Rahul", "ORD-999"],
    buttons=[{"index": 0, "sub_type": "quick_reply", "payload": "TRACK_ORDER"}],
)

Template Management

sync_templates_from_meta

sync_templates_from_meta(account=None) -> list
Fetches all approved/pending templates from Meta for the given account’s WABA.
  • Requires waba_id on the account or WHATSAPP["WABA_ID"] in settings.
  • Returns: List of raw template dicts from the Meta API (data field).
  • The caller is responsible for creating or updating WhatsAppTemplate records from the returned data.

push_template_to_meta

push_template_to_meta(template_obj, account=None) -> dict
Submits a WhatsAppTemplate to Meta for creation and approval.
ParameterTypeDescription
template_objWhatsAppTemplateA WhatsAppTemplate model instance.
accountWhatsAppAccount | NoneOverrides template_obj.account if provided.
Constructs the Meta components list from template_obj.header, body_text, footer_text, and buttons. Returns: Meta API response dict.

delete_template_from_meta

delete_template_from_meta(template_name, account=None) -> dict
Deletes a template from Meta by name.
ParameterTypeDescription
template_namestrThe template name string (not the local database ID).
accountWhatsAppAccount | NoneOptional account instance.
Returns: Meta API response dict.

Campaign Functions

resolve_audience

resolve_audience(campaign) -> list
Resolves the audience for a WhatsAppCampaign to a list of recipient dicts. Returns: [{"phone": "...", "name": "...", "params": {...}}, ...] Resolution is attempted in this order:
  1. WHATSAPP["CAMPAIGN_RESOLVER"] — a dotted-path to a custom resolver function that receives the campaign and returns the full recipient list.
  2. WHATSAPP["AUDIENCES"][campaign.audience_type] — a dotted-path to a named queryset provider function.
  3. audience_type == "contacts" — queries WhatsAppContact records, filtering opted_out=False, is_blocked=False. Additional filters from campaign.audience_filters are applied.
  4. audience_type == "csv" — parses campaign.csv_file; expects columns phone, name (case-insensitive).

run_campaign

run_campaign(campaign_id, account=None) -> dict
Synchronously executes a campaign (blocking call).
  • Resolves audience, sends template messages, and creates WhatsAppCampaignRecipient records.
  • Sets campaign status to "running" then "completed" (or "failed").
  • Returns: {"sent": N, "failed": N}
Use run_campaign() for small campaigns or testing. For large campaigns, use run_campaign_async() to avoid blocking the process.

run_campaign_async

run_campaign_async(campaign_id, account_id=None)
Queues a campaign via Celery if WHATSAPP_USE_CELERY = True in Django settings; otherwise runs synchronously. Returns:
  • {"queued": True} — if the task was successfully queued via Celery.
  • {"sent": N, "failed": N} — if executed synchronously.

Catalog Functions

sync_catalog_products

sync_catalog_products(catalog_id, account=None) -> dict
Fetches all products from Meta for the given catalog_id and upserts WhatsAppCatalogProduct records. Automatically paginates through all results. Returns: {"synced": N} where N is the total number of products upserted.

send_single_product_message

send_single_product_message(
    phone_number,
    catalog_id,
    retailer_id,
    body,
    footer='',
    account=None,
) -> dict
Sends an interactive single-product card from a catalog.
ParameterTypeDescription
phone_numberstrRecipient phone number.
catalog_idstrMeta Commerce catalog ID.
retailer_idstrThe product’s retailer ID within the catalog.
bodystrBody text shown with the product card.
footerstrOptional footer text.
Returns: Meta API response dict.

send_multi_product_message

send_multi_product_message(
    phone_number,
    catalog_id,
    sections,
    header,
    body,
    footer='',
    account=None,
) -> dict
Sends an interactive product list grouped into sections.
ParameterTypeDescription
sectionslist[dict][{"title": str, "product_items": [{"product_retailer_id": str}]}]
headerstrHeader text shown above the product list.
bodystrBody text.
footerstrOptional footer text.
Returns: Meta API response dict.

send_catalog_message

send_catalog_message(phone_number, thumbnail_retailer_id, body, footer='', account=None) -> dict
Sends a catalog message showing the full business catalog, with one product used as the thumbnail.
ParameterTypeDescription
thumbnail_retailer_idstrRetailer ID of the product to use as the catalog thumbnail.
bodystrBody text.
footerstrOptional footer text.
Returns: Meta API response dict.
send_product_carousel_message(phone_number, catalog_id, retailer_ids, body, account=None) -> dict
Sends a horizontally scrollable product carousel.
ParameterTypeDescription
catalog_idstrMeta Commerce catalog ID.
retailer_idslist[str]List of retailer ID strings displayed as carousel cards.
bodystrBody text shown above the carousel.
Returns: Meta API response dict.
send_catalog_link_message(phone_number, wa_number, account=None) -> dict
Sends a plain text message containing https://wa.me/c/<wa_number> — a direct link to the business’s WhatsApp catalog.
ParameterTypeDescription
wa_numberstrThe WhatsApp number associated with the catalog (without +).
Returns: Meta API response dict (delegates to send_text_message).

Blocked Users Functions

block_users

block_users(phone_numbers, account=None) -> dict
Blocks up to 1,000 users in a single Meta API call.
  • Updates local WhatsAppBlockedUser records for both successes and failures.
  • Sets WhatsAppContact.is_blocked = True for successfully blocked numbers.
Returns: Meta response dict with block_users.added_users and block_users.failed_users.

unblock_users

unblock_users(phone_numbers, account=None) -> dict
Unblocks a list of users.
  • Sets WhatsAppBlockedUser.is_active = False and records unblocked_at for removed users.
  • Sets WhatsAppContact.is_blocked = False.
Returns: Meta response dict with block_users.removed_users.

get_blocked_users

get_blocked_users(limit=100, after_cursor=None, account=None) -> dict
Fetches a paginated page of blocked users from Meta.
ParameterTypeDescription
limitintNumber of results per page (default 100).
after_cursorstr | NonePagination cursor from a previous response’s paging.cursors.after.
Returns: Raw Meta response dict with data[] entries and paging cursors.

sync_blocked_users_from_meta

sync_blocked_users_from_meta(account=None) -> int
Full sync — paginates through all blocked users on Meta and updates local WhatsAppBlockedUser records. Also sets WhatsAppContact.is_blocked = True for matched contacts. Returns: Total count of records synced.

In-App Signup Functions

create_signup

create_signup(
    display_name,
    signup_message,
    confirmation_message,
    privacy_policy_url,
    website_url='',
    promo_code='',
    account=None,
) -> dict
Creates a new In-App Signup link via the Meta Graph API.
ParameterTypeDescription
display_namestrInternal label, not shown to subscribers.
signup_messagestrPre-consent screen text shown to the user inside WhatsApp.
confirmation_messagestrSent to the user after they subscribe. Use {{promo_code}} to embed the promo.
privacy_policy_urlstrURL to privacy policy. Immutable after creation on Meta.
website_urlstrOptional website URL.
promo_codestrOptional alphanumeric promo code.
accountWhatsAppAccountRequired. Must have waba_id configured.
Returns: Meta API response dict including the id of the created signup.
create_signup() requires a WhatsAppAccount instance with waba_id set. It raises ValueError if account is None or account.waba_id is empty.

list_signups

list_signups(account=None) -> list
Lists all In-App Signup links for the account’s WABA. Returns: List of signup dicts from the Meta API data field.

get_signup

get_signup(signup_id, account=None) -> dict
Fetches full details of a specific signup link from Meta. Returns: Meta API response dict for the signup.

update_signup

update_signup(signup_id, promo_code=None, confirmation_message=None, account=None) -> dict
Updates mutable fields of a signup link. Only promo_code and confirmation_message can be changed after creation. Returns: Meta API response dict.

disable_signup

disable_signup(signup_id, account=None) -> dict
Disables a signup link by setting its status to DISABLED on Meta. Returns: Meta API response dict.

Build docs developers (and LLMs) love