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

# Lead Sources

> IndiaMART polling, Facebook webhooks, and CSV imports.

## Supported Lead Sources

| Source                 | Code path                    | Storage source value |
| ---------------------- | ---------------------------- | -------------------- |
| IndiaMART CRM API      | `lead_fetcher.py` poller     | `indiamart`          |
| Facebook Lead Ads      | `lead_fetcher.py` webhook    | `facebook_ads`       |
| Facebook Page messages | `lead_fetcher.py` webhook    | `facebook_page`      |
| CSV upload             | `streamlit_app.py` dashboard | `facebook`           |
| Manual SQL             | Direct insert                | Any configured value |

## IndiaMART

The poller calls:

```text theme={null}
https://mapi.indiamart.com/wservce/crm/crmListing/v2/
```

With:

```env theme={null}
INDIAMART_API_KEY=your_indiamart_api_key
INDIAMART_POLL_INTERVAL_MINUTES=15
INDIAMART_NEW_ONLY_MODE=true
```

When `INDIAMART_NEW_ONLY_MODE=true`, the code calls the API without explicit start/end timestamps after initialization, using IndiaMART's new-lead cursor behavior.

Stored fields:

* `phone` from `SENDER_MOBILE`
* `name` from `SENDER_NAME`
* `email` from `SENDER_EMAIL`
* `product_name` from `QUERY_PRODUCT_NAME`
* `city` from `SENDER_CITY`
* `state` from `SENDER_STATE`
* `query_message` from `QUERY_MESSAGE`

## Facebook Webhooks

Webhook endpoint:

```text theme={null}
GET  /webhook/facebook
POST /webhook/facebook
```

Configuration:

```env theme={null}
FACEBOOK_ACCESS_TOKEN=your_page_access_token
FACEBOOK_PAGE_ID=your_page_id
FACEBOOK_APP_SECRET=your_facebook_app_secret
FACEBOOK_VERIFY_TOKEN=your_verify_token
FACEBOOK_AD_FORM_IDS=form_id_1,form_id_2
WEBHOOK_PORT=8081
```

The `GET` endpoint handles Facebook verification. The `POST` endpoint handles events.

If `FACEBOOK_APP_SECRET` is configured, the app verifies `X-Hub-Signature-256`.

## Facebook Lead Ads

When Facebook sends a `leadgen` event, the app fetches the lead via Graph API and stores:

* `phone`
* `name`
* `email`
* `source='facebook_ads'`

## Facebook Page Messages

For Page messages, the app attempts to fetch the sender phone number through Graph API. If no phone is available, it stores:

```text theme={null}
fb_psid_{sender_id}
```

The scheduler will not dial `fb_psid_...` values. It marks those leads failed because they do not contain a real phone number.

## CSV Upload

The Streamlit dashboard supports CSV lead upload.

Required columns:

* `name`
* `phone`

Optional columns:

* `source`
* `email`
* `product_name`
* `city`
* `state`
* `query_message`

CSV-uploaded rows are treated as Facebook-style leads by the dashboard's `_clean_source_value()` function.
