# Screenshot Transmission Implementation ## Overview Clients send screenshots via MQTT during heartbeat intervals. The listener service receives these screenshots and forwards them to the server API for storage. ## Architecture ### MQTT Topic - **Topic**: `infoscreen/{uuid}/screenshot` - **Payload Format**: - Raw binary image data (JPEG/PNG), OR - JSON with base64-encoded image: `{"image": ""}` ### Components #### 1. Listener Service (`listener/listener.py`) - **Subscribes to**: `infoscreen/+/screenshot` - **Function**: `handle_screenshot(uuid, payload)` - Detects payload format (binary or JSON) - Converts binary to base64 if needed - Forwards to API via HTTP POST #### 2. Server API (`server/routes/clients.py`) - **Endpoint**: `POST /api/clients//screenshot` - **Authentication**: No authentication required (internal service call) - **Accepts**: - JSON: `{"image": ""}` - Binary: raw image data - **Storage**: - Saves to `server/screenshots/{uuid}_{timestamp}.jpg` (with timestamp) - Saves to `server/screenshots/{uuid}.jpg` (latest, for quick retrieval) #### 3. Retrieval (`server/wsgi.py`) - **Endpoint**: `GET /screenshots/` - **Returns**: Latest screenshot for the given client UUID - **Nginx**: Exposes `/screenshots/{uuid}.jpg` in production ## Unified Identification Method Screenshots are identified by **client UUID**: - Each client has a unique UUID stored in the `clients` table - Screenshots are stored as `{uuid}.jpg` (latest) and `{uuid}_{timestamp}.jpg` (historical) - The API endpoint requires UUID validation against the database - Retrieval is done via `GET /screenshots/` which returns the latest screenshot ## Data Flow ``` Client → MQTT (infoscreen/{uuid}/screenshot) ↓ Listener Service ↓ (validates client exists) ↓ (converts binary → base64 if needed) ↓ API POST /api/clients/{uuid}/screenshot ↓ (validates client UUID) ↓ (decodes base64 → binary) ↓ Filesystem: server/screenshots/{uuid}.jpg ↓ Dashboard/Nginx: GET /screenshots/{uuid} ``` ## Configuration ### Environment Variables - **Listener**: `API_BASE_URL` (default: `http://server:8000`) - **Server**: Screenshots stored in `server/screenshots/` directory ### Dependencies - Listener: Added `requests>=2.31.0` to `listener/requirements.txt` - Server: Uses built-in Flask and base64 libraries ## Error Handling - **Client Not Found**: Returns 404 if UUID doesn't exist in database - **Invalid Payload**: Returns 400 if image data is missing or invalid - **API Timeout**: Listener logs error and continues (timeout: 10s) - **Network Errors**: Listener logs and continues operation ## Security Considerations - Screenshot endpoint does not require authentication (internal service-to-service) - Client UUID must exist in database before screenshot is accepted - Base64 encoding prevents binary data issues in JSON transport - File size is tracked and logged for monitoring ## Future Enhancements - Add screenshot retention policy (auto-delete old timestamped files) - Add compression before transmission - Add screenshot quality settings - Add authentication between listener and API - Add screenshot history API endpoint