> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lokpanchang.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Meta & WhatsApp

> Meta Webhooks, connection to WhatsApp Business API, and using WhatsApp template messages

The application receives user messages and sends replies through the **Meta (Facebook) ecosystem**: the **WhatsApp Cloud API** is part of the **Meta Graph API**. This page covers webhooks (how Meta calls our API), the connection to the WhatsApp Business API, and how we use **template messages** for panchangam and other business-initiated messages.

## Meta Webhooks

Meta sends HTTP requests to a **webhook URL** you configure in the Meta for Developers app. For this project the webhook is exposed at **`https://api.lokpanchang.com/webhook`** (production) or, in development, at a public URL provided by [Ngrok](/infrastructure/ngrok) (e.g. `https://xxxx.ngrok.app/webhook`).

### Verification (GET)

When you register or save the webhook URL in Meta, Meta sends a **GET** request to verify ownership:

* **Query parameters:** `hub.mode=subscribe`, `hub.verify_token=<your-token>`, `hub.challenge=<challenge-string>`.
* **App behavior:** The Flask route in **`app.py`** compares `hub.verify_token` to **`VERIFY_TOKEN`** (hardcoded as `"test123"`). If they match, the app responds with **200** and the **body** set to `hub.challenge`. Otherwise it returns 403.
* **Config in Meta:** In the WhatsApp app’s webhook settings, set the **Verify token** to the same value as `VERIFY_TOKEN` (e.g. `test123`).

### Receiving events (POST)

After verification, Meta sends **POST** requests to the same URL for every event (user messages, delivery/read status, etc.):

* **Payload:** JSON with `object: "whatsapp_business_account"`, `entry[]`, `changes[]`, and for messages a `value.messages[]` array. Each message has `id`, `from` (phone), `type` (e.g. `text`, `location`), and type-specific content.
* **App behavior:** The **POST `/webhook`** handler in `app.py` only processes entries that contain **`messages`**. Status updates (e.g. delivery receipts) are skipped. For each message it deduplicates by message ID, then dispatches:
  * **`type == "location"`** → `handle_location_message` (geocode, save user, generate panchangam, send template + optional text).
  * **`type == "text"`** → `handle_text_message` (e.g. "start" → request location; "stop" → unsubscribe; "help" → help text).
* **Response:** The handler must respond with **200 OK** quickly so Meta does not retry. Heavy work (panchangam generation, sending replies) is done in the same request in this app.

See [Backend](/backend) for the full webhook flow.

## Connection to WhatsApp Business API

* **API base:** Requests to send messages go to **Meta Graph API**: **`https://graph.facebook.com/v18.0/`** (version and base URL are in **`messaging.py`**).
* **Credentials:**
  * **`WHATSAPP_PHONE_NUMBER_ID`** — The WhatsApp Business phone number ID (from Meta Business Suite / App Dashboard).
  * **`WHATSAPP_ACCESS_TOKEN`** — A long-lived access token with `whatsapp_business_messaging` and `whatsapp_business_management` (or equivalent) permissions.
* **Sending:** The app builds the request URL as **`{base}/{PHONE_NUMBER_ID}/messages`** and sends **POST** with the token in the **`Authorization: Bearer <token>`** header. Request body is JSON (see [Template messages](#using-whatsapp-template-messages) below for template format).
* **Where in code:** **`messaging.py`** — `send_whatsapp_message` (text), `send_panchangam_template`, `send_whatsapp_template_message`, `send_location_request_message` — all use `requests.post(URL, headers=..., json=...)` with the same base URL and token.

## Using WhatsApp template messages

Business-initiated messages (e.g. daily panchangam at 6:30 AM) must use **pre-approved templates** so they are allowed outside the 24-hour customer service window. The app uses several templates:

* **Panchangam (primary):** When **`USE_SHORT_PANCHANGAM_TEMPLATE`** is true in `messaging.py`, the app sends the **`new_panchangam_short`** template (24 body parameters). When false, template choice is **country-based**: US (country code `1`) → **`dailymessage`** (utility); others → **`panchangam_global`** (marketing), both with 42 body parameters (location, date, weekday, panchangam elements, times, etc.).
* **Other templates:** **`tst_msg`** (test message, no params), **`user_unsubscribe`** (unsubscribe confirmation), and **location request** (interactive button) are used where appropriate.

Template parameters are built in **`messaging.py`**: **`generate_panchangam_template_parameters`** and **`generate_panchangam_template_parameters_short`** turn the panchangam dict (from [Core Panchangam calculation](/panchangam/core-calculation)) into the ordered list of body parameters. The request body follows the [WhatsApp Cloud API format](https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages) for template messages: `type: "template"`, `template: { name, language, components: [ { type: "body", parameters: [ { type: "text", text: "..." } ] } ] }`.

Templates must be created and approved in the Meta Business Manager / WhatsApp Manager; once approved, the app only sends the template name and parameters. See [Backend](/backend) and [Admin portal](/admin-portal) for how sends are triggered (webhook, Celery, admin actions).
