# heartbeat-pwa This is the Progressive Web App (PWA) client for Heartbeat. It will ping the central server every minute, as long as the device is actively being used (optional activity detection) and the app is enabled. The PWA can be installed on mobile devices (iOS/Android) and desktop browsers, providing a native app-like experience with offline support and background sync capabilities. # Jump to - [Features](#features) - [Installation](#installation) - [Configuration](#configuration) - [Background Operation](#background-operation) - [Deployment](#deployment) ## Features - **Installable**: Add to home screen on mobile devices for app-like experience - **Activity Detection**: Optional detection of user interaction (touch, click, keyboard) - **Notifications**: Alerts for connection issues and successful reconnections - **Persistent Storage**: Configuration and statistics stored in IndexedDB - **Activity Logs**: View recent heartbeat attempts and system events ## Installation ### Option 1: Visit the hosted version 1. Open your mobile browser and navigate to your hosted Heartbeat PWA URL (example: https://pwa.heartbeat.josie.health/) 2. For iOS: Tap the share button and select "Add to Home Screen" 3. For Android: Tap the menu and select "Install App" or "Add to Home Screen" 4. The app will install and appear on your home screen with an icon ### Option 2: Self-host the PWA 1. Clone or download the PWA files: ```bash git clone https://github.com/pfeifferj/heartbeat-pwa.git cd heartbeat-pwa ``` 2. Serve the files using any web server: ```bash # Using Python python3 -m http.server 8000 # Using Node.js npx serve . # Using nginx/apache # Copy files to your web root ``` 3. For HTTPS (required for service workers and background sync): - Use a reverse proxy with SSL termination - Or deploy to a platform that provides HTTPS (Netlify, Vercel, etc.) ## Configuration 1. Open the PWA in your browser or installed app 2. Enter your Heartbeat server configuration: - **Server URL**: Your Heartbeat server endpoint (e.g., `https://your.heartbeat.domain`) - **Auth Token**: Your authentication token from the Heartbeat server - **Device Name**: A friendly name for this device (e.g., "iPhone", "Android Tablet") 3. Toggle options: - **Enable Heartbeat**: Start/stop sending heartbeats - **Activity Detection**: Only send heartbeats when device is actively used (within 2 minutes) - **Enable Notifications**: Allow notifications for connection status changes 4. Click "Save Configuration" to persist your settings ## Background Operation ### Server-Initiated Heartbeat Checks (Recommended) The PWA supports **server-initiated heartbeat checks** via push notifications, which solves background execution limitations: **How it works:** 1. PWA subscribes to push notifications when "Enable Server Checks" is clicked 2. Server can send push notifications to wake up the service worker at any time 3. Service worker automatically sends a heartbeat and shows a notification 4. Works even when PWA is completely closed on the device **Setup Requirements:** 1. Server must have VAPID keys configured (see [Server Setup](#server-setup-for-push-notifications) below) 2. Enable notifications in PWA settings 3. Click "Enable Server Checks" button 4. Server admin can trigger checks via API or scheduled checkins ### Traditional Background Sync (Limited) Without server-initiated checks, background operation is limited: #### Android (Chrome/Edge) - **When installed as PWA**: Limited background execution with Periodic Background Sync - **Minimum interval**: 12 hours when app is closed (browser limitation) - **Best practice**: Keep app open but minimized for continuous heartbeats #### iOS (Safari) - **No background execution** when PWA is closed - **Must keep app open** (can be minimized) for heartbeats to continue - **Alternative**: Use Shortcuts app to periodically open the PWA #### Desktop Browsers - Background sync works when browser is running - Service worker remains active for offline queuing - Best results with PWA installed as desktop app ### Recommendations **For reliable monitoring:** 1. **Best**: Use server-initiated heartbeat checks (requires server setup) 2. **Good**: Keep PWA installed and open/minimized 3. **Alternative**: Use native heartbeat-unix clients for desktop systems ## Server Setup for Push Notifications To enable server-initiated heartbeat checks, the main heartbeat server needs to be configured with VAPID keys and the new push notification endpoints. ### Prerequisites The main heartbeat server must be updated with the push notification functionality. See the [SERVER_PUSH.md](SERVER_PUSH.md) file for complete implementation details. ### 1. Generate VAPID Keys ```bash # Install web-push CLI tool npm install -g web-push # Generate VAPID keys web-push generate-vapid-keys # Output will look like: # Public Key: BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U # Private Key: tUkzMcPbtl2-xZ4Z5A1OqiELPo2Pc9-SFNw6hU8_Hh0 ``` ### 2. Configure Server Environment Add to your heartbeat server's `.env` file: ```bash # VAPID Configuration for Push Notifications VAPID_PUBLIC_KEY=BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U VAPID_PRIVATE_KEY=tUkzMcPbtl2-xZ4Z5A1OqiELPo2Pc9-SFNw6hU8_Hh0 VAPID_SUBJECT=mailto:your-email@example.com ``` ### 3. Configure PWA Replace `YOUR_VAPID_PUBLIC_KEY_HERE` in `app.js` with your actual public key: ```javascript const vapidPublicKey = 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'; ``` ### 4. Trigger Heartbeat Checks **Manual trigger (all devices):** ```bash curl -X POST \ -H "Auth: your-heartbeat-token" \ -H "Content-Type: application/json" \ -d '{"allDevices": true}' \ https://your.heartbeat.domain/api/trigger-heartbeat-check ``` **Manual trigger (specific device):** ```bash curl -X POST \ -H "Auth: your-heartbeat-token" \ -H "Content-Type: application/json" \ -d '{"deviceName": "iPhone"}' \ https://your.heartbeat.domain/api/trigger-heartbeat-check ``` **Automated trigger (cron job every 5 minutes):** ```bash */5 * * * * curl -s -X POST -H "Auth: your-token" -H "Content-Type: application/json" -d '{"allDevices": true}' https://your.heartbeat.domain/api/trigger-heartbeat-check >/dev/null 2>&1 ``` ### 5. Verify Setup 1. Check server logs for VAPID configuration on startup 2. Enable server checks in PWA - should show "Server Checks Enabled" 3. Trigger a manual check - PWA should receive notification and send heartbeat 4. Check heartbeat server logs for successful push notifications sent ## Deployment ### Kubernetes/OpenShift Deployment The PWA can be deployed to Kubernetes/OpenShift using ConfigMaps: ```bash # Create ConfigMaps for PWA files oc create configmap heartbeat-pwa-files \ --from-file=index.html \ --from-file=app.js \ --from-file=service-worker.js \ --from-file=manifest.json \ -n your-namespace # Create ConfigMap for icons oc create configmap heartbeat-pwa-icons \ --from-file=icons/icon-192x192.png \ --from-file=icons/icon-512x512.png \ -n your-namespace # Apply deployment (see k8s-manifests.yaml) oc apply -f k8s-manifests.yaml ``` ### Docker Deployment Build and run with Docker: ```bash # Build the image docker build -t heartbeat-pwa . # Run the container docker run -d -p 8080:80 heartbeat-pwa ``` ### Static Hosting The PWA is purely static and can be hosted on: - GitHub Pages - Netlify - Vercel - Cloudflare Pages - Any static file server with HTTPS ## Troubleshooting ### Icons not showing when installed - Ensure icon files exist in the `icons/` directory - Verify paths in `manifest.json` are correct - Check browser console for 404 errors ### Notifications not working - Click "Enable Notifications" button when prompted - Check browser/OS notification settings - Notifications require HTTPS in production ### Background sync not working - Ensure PWA is installed (not just bookmarked) - Check browser compatibility for Periodic Background Sync - Review browser console for service worker errors ### Heartbeats not sending - Verify server URL includes protocol (https://) - Check auth token is correct - Look at Activity Log for error messages - Ensure device has internet connection