# Next Session: WhatsApp wa-js Sending Migration

## What

Replace DOM selector-based WhatsApp Web sending with **WPPConnect wa-js** injection. This eliminates 7 fragile sending selectors that broke in session 11 by hooking WhatsApp's internal webpack modules instead of chasing DOM elements. Reading (DOM polling) stays unchanged. The plan survived two adversarial reviews that identified 16 issues — all CRITICAL/HIGH/MEDIUM findings are addressed in the approved plan.

## Plan

Read the approved plan first:
```
cat ~/.claude/plans/snoopy-munching-horizon.md
```
It has the full implementation, all review findings, design decisions, and code examples.

## Key Design Decisions (from adversarial review)

1. **All `wa_js.py` functions are `_unlocked`** — caller holds `page_lock`, wa_js.py never acquires it. Prevents deadlock between wa_sender.py (which holds lock) and wa_js.py (which would re-acquire it). Same pattern as existing `_navigate_to_chat_unlocked()`.

2. **Event-driven page reload detection** — `page.on("load")` sets `_wajs_stale=True` immediately on page refresh. The 30s health loop poll alone leaves a window where sends fail silently.

3. **Every `page.evaluate()` wrapped in `asyncio.wait_for(timeout=30)` + `try/except`** — Prevents permanent lock hold if WPP hangs. JS exceptions propagate as Python errors (not None), so try/except is mandatory.

4. **JID cache cleared on every re-injection** — Prevents stale JIDs from previous session surviving browser restart.

5. **Three-tier JID resolution** — cache → `WPP.chat.list()` → `getActiveChat()` fallback. WhatsApp lazy-loads chats; the target group might not appear in `chat.list()`.

6. **No `_injected` bool flag** — Removed entirely. State derived from `is_ready()` (checks actual page). The flag outlives browser context restarts.

7. **NPM package is `@wppconnect/wa-js`** (NOT `@nichat/wa-js` as the old NEXT-SESSION doc says). CDN: `https://cdn.jsdelivr.net/npm/@wppconnect/wa-js@3/dist/wppconnect-wa.js`

8. **Vendor bundle with version pin + SHA256 integrity** — Detects SD card corruption on Panda, enables clear update path.

9. **Telegram alert on DEGRADED** — If wa-js fails to inject, don't just log it. Send a Telegram alert so Rajesh knows sending is broken.

10. **Audit data-testid selectors** — `alert_phone` and `alert_computer` still use `data-testid` (stripped since 2026-04-07). Migrate to `data-icon` selectors.

## Files to Modify (ordered)

1. `services/whatsapp-agent/vendor/wppconnect-wa.js` — **NEW**: Download bundled wa-js v3.22.1
2. `services/whatsapp-agent/vendor/wppconnect-wa.version` — **NEW**: Version pin file
3. `services/whatsapp-agent/vendor/wppconnect-wa.sha256` — **NEW**: SHA256 integrity hash
4. `services/whatsapp-agent/wa_js.py` — **NEW**: Injection, JID resolution, send wrappers (~150 lines)
5. `services/whatsapp-agent/wa_sender.py` — **REWRITE**: send_message() + send_image() to use wa_js
6. `services/whatsapp-agent/wa_browser.py` — Inject wa-js after CONNECTED + page.on("load") listener
7. `services/whatsapp-agent/wa_web.py` — Remove 7 sending selectors, migrate data-testid selectors
8. `services/whatsapp-agent/agent.py` — Health loop: _wajs_stale check. /v1/health: wajs_ready field.
9. `services/whatsapp-agent/tests/test_wa_js.py` — **NEW**: 25 tests for wa_js module
10. `services/whatsapp-agent/tests/test_wa_sender.py` — **REWRITE**: Mock wa_js, not DOM

## Start Command

```
cat ~/.claude/plans/snoopy-munching-horizon.md
```
Then implement the plan. All adversarial findings are already addressed in it.

## Verification

1. **Local tests:** `cd services/whatsapp-agent && python3 -m pytest tests/ -v` — all pass
2. **Deploy:** `git commit && git push` → on Panda: `git pull && stop.sh && start.sh`
3. **Health check:** `curl -s http://panda:8780/v1/health` → `wajs_ready: true`
4. **Send text:** `curl -X POST http://panda:8780/v1/send -d '{"chat":"Holliday","text":"wa-js test"}'`
5. **Send image:** `curl -X POST http://panda:8780/v1/send-image -d '{"chat":"Holliday","image_path":"/tmp/test.jpg","caption":"test"}'`
6. **Reading works:** Send phone message to Holliday → check `tail -f /tmp/whatsapp-agent.log`
7. **Reload resilience:** Simulate page refresh → logs show re-injection within one health tick
