# Version 3.0.2 TextBee Reply Capture Fix

This patch fixes the case where the initial intake SMS is delivered, but the customer's reply does not show in the lead dashboard and the lead remains `new`.

## Root cause addressed

TextBee webhooks can be inconsistent. Polling was added as a fallback, but v3.0 required `receivedAt` for poll messages by default. Some TextBee received-SMS API responses may omit `receivedAt`, so the poller could skip the reply even though a current lead existed.

## Fixes

### 1. Polling can process no-timestamp replies for recent active leads

New env setting:

TEXTBEE_POLL_ALLOW_MISSING_RECEIVED_AT_FOR_ACTIVE_LEADS=true

When true, if TextBee polling returns a message without `receivedAt`, the app will process it only when:

- the sender has a recent active, non-archived lead
- the same inbound body is not already saved on that lead
- the event ledger has not already recorded that event

### 2. Poller bootstraps old TextBee history

On first poll after restart, existing TextBee received-SMS history is marked as already seen.

Log:

[TextBee poll bootstrap completed]

This prevents old TextBee inbox messages from being imported as new leads.

### 3. Archived leads are not used for inbound matching

`findLeadByPhone()` now ignores archived leads.

### 4. Manual TextBee process endpoint can force import for debugging

POST /admin/api/textbee/process-received?force=true

This bypasses cursor/missing-receivedAt skips but still respects event/message dedupe.

## Recommended env

TEXTBEE_INBOUND_POLLING_ENABLED=true
TEXTBEE_INBOUND_POLLING_INTERVAL_SECONDS=30
TEXTBEE_INBOUND_POLLING_LIMIT=10
TEXTBEE_POLL_IGNORE_HISTORY_ON_START=true
TEXTBEE_POLL_LOOKBACK_SECONDS=0
TEXTBEE_POLL_REQUIRE_RECEIVED_AT=true
TEXTBEE_POLL_ALLOW_MISSING_RECEIVED_AT_FOR_ACTIVE_LEADS=true
