# BGM WhatsApp Web bridge

Persistent Node.js service used only for the ERP's experimental **QR Code (WhatsApp Web)** connection. The official Meta Cloud API continues to run directly through the BGM API Worker.

## What it provides

- multiple isolated Baileys sessions;
- live QR generation and connection status;
- encrypted session persistence with AES-256-GCM;
- automatic reconnect with bounded exponential backoff;
- outbound text, image, video, audio, document and location messages;
- inbound text/media/location metadata sent to the ERP Inbox and CRM through signed callbacks;
- authenticated private HTTP API with no QR or credential logging.

This is an unofficial WhatsApp Web integration. It must use a dedicated test/service number, must not be used for bulk messaging, and can be disconnected or restricted by WhatsApp. The official Cloud API remains the production path.

## Runtime

- Node.js 22.13 or newer;
- persistent private disk for `BGM_SESSION_DIRECTORY`;
- an HTTPS reverse proxy or container ingress;
- outbound access to WhatsApp Web and the ERP callback URL;
- no horizontal replication unless session ownership/locking is added.

Copy `.env.example` into the secret manager of the chosen Node host. Never commit the three secrets. `HOST=0.0.0.0` is normally required in a container; use the default `127.0.0.1` behind a local reverse proxy.

```bash
pnpm install --frozen-lockfile
pnpm run whatsapp-bridge:build
pnpm run whatsapp-bridge:test
pnpm run whatsapp-bridge:start
```

The bridge exposes:

- `GET /health` (public, contains no account data)
- `POST /v1/sessions`
- `GET /v1/sessions/:sessionId`
- `POST /v1/sessions/:sessionId/messages`
- `POST /v1/sessions/:sessionId/disconnect`

All `/v1` routes require `Authorization: Bearer <BGM_BRIDGE_API_SECRET>`. Callbacks are signed with `BGM_API_CALLBACK_SECRET` using `X-BGM-Bridge-Timestamp` and `X-BGM-Bridge-Signature`.

## ERP configuration

After the service has a stable HTTPS URL, configure these Cloudflare Worker secrets/variables:

- `BGM_WHATSAPP_WEB_BRIDGE_URL`: HTTPS origin of this service;
- `BGM_WHATSAPP_WEB_BRIDGE_SECRET`: same value as `BGM_BRIDGE_API_SECRET`;
- `BGM_WHATSAPP_WEB_CALLBACK_SECRET`: same value as `BGM_API_CALLBACK_SECRET`;
- `BGM_WHATSAPP_TOKEN_ENCRYPTION_KEY`: separate key used to encrypt official Meta tokens.

Apply database migration `0016_colorful_pixie.sql` before enabling the Worker variables.

## Manual acceptance test

1. Open ERP → WhatsApp → Settings.
2. Choose **QR Code (WhatsApp Web)** and click **Connect with QR Code**.
3. On a dedicated phone: WhatsApp → Linked devices → Link a device.
4. Scan the live QR. The state must change from `Generating QR` to `Waiting for scan` and then `Connected`.
5. Send a text from a second phone; it must create/update the CRM contact and appear in the unified Inbox.
6. Reply with text and test an HTTPS image, audio and document URL.
7. Restart the bridge; the encrypted session must restore automatically without a new QR.
8. Click **Disconnect**; the bridge must log out and delete encrypted session material.

Do not use a personal or business-critical number for the acceptance test.
