# Changelog of WhatsApp Scraper (`badr_xba/whatsapp-number-scraper`) Actor

- **URL**: https://apify.com/badr_xba/whatsapp-number-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/badr_xba/whatsapp-number-scraper.md

## Changelog

### 2026-11-09 (review invitation)

- Successful runs that saved at least one result end their status message with one short, optional invitation to leave a Store review or open an issue (never on failed or empty runs); README section "Feedback and reviews". Output and billing unchanged.

### 2026-11-08 (visual kit 1.1.0)

#### Added

- `errorCode` on every `FAILED_INPUTS` entry (provider failures: `providerUnreachable`, `providerRateLimited`,
  `providerServerError`, `providerAuthRejected`, `providerBadAddress`, `providerHttpError`, `providerBadAnswer`,
  `providerStopped`, `unexpectedError`); `RUN_SUMMARY.failedByCode` and `RUN_SUMMARY.warnings` (`{code, message}`).
- Visual report on kit 1.1.0: live progress page while numbers are checked, failed numbers grouped by error code,
  data-quality panel. The report is saved with status FAILED when the run crashes.

### 2026-11-08 (visual report)

#### Added

- **Visual report** (`REPORT` record, Output tab → *Visual report*): validation dashboard with valid / invalid /
  on WhatsApp / not on WhatsApp / unknown counts, country, line-type and WhatsApp-status charts, one card per
  number (formats, validity, WhatsApp status, line type, carrier, place, time zone, issues) and a table view, with
  search, filters, sorting and CSV/JSON export of the filtered rows. No picture is read or shown. Built by the
  shared `src/visual_kit.py` (v1.0.0) with this Actor's `src/report.py`. At most 2,000 rows are kept in memory for
  it; it is never billed and a report error is only logged as a warning.
- Output schema: *Visual report* link; key-value store schema: `REPORT` (text/html).

### 2026-11-07

#### Fixed

- The run crashed (exit 91) when "Keep only these countries" was not a list or text (for example a number sent through the API). It is now read safely and unknown entries are reported.
- Non-numeric values for the provider rate limit, attempts or timeout (`"fast"`) crashed the run; they now fall back to the default with a warning. Text booleans such as `"false"` sent by integrations are read correctly.
- WhatsApp links (`wa.me/…`, `api.whatsapp.com/send?phone=…`) are always read as international numbers: the default country is no longer applied to them, so an invalid link number is explained in its own country.
- Moroccan numbers now get the time zone `Africa/Casablanca` instead of libphonenumber's `Atlantic/Canary` (one hour off in winter).
- The demo sample (empty input) is no longer sent to a configured WhatsApp provider.

#### Improved

- Provider retries: exponential back-off with jitter, `Retry-After` respected (capped at 30 s), explicit connect timeout, bounded connection pool.
- If the provider refuses the first numbers with HTTP 401/403/404/405 (wrong key, address or method), the Actor stops sending the rest of the list. In a local test with 30 numbers: 8 requests instead of 30, 10.5 s instead of 20.9 s. Unsent numbers are listed in `FAILED_INPUTS` and not billed, as before.
- Any URL is masked in provider error messages, and the `httpx` request log is muted, so the provider address (which can contain a token) never reaches the log.
- Log and status messages are in English.
- Dataset schema now declares every output field (types, nullability, enums, honest notes on often-empty fields).
- `whatsappAuthHeader` and `whatsappAuthPrefix` are secret inputs (prefill instead of default; the code keeps the same defaults `Authorization` / `Bearer `). The old names `whatsappKeyHeader` / `whatsappKeyPrefix` still work.
- `phonenumbers` dependency upper-bounded (`<10`).
- Offline test suite (`python -m pytest -q`), excluded from the Docker image.
