• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
halffullheart

halffullheart

heartbeat

Public
Like
heartbeat
Home
Code
5
README.md
client.js
generate-vapid-keys.ts
H
main.ts
C
monitor.ts
Environment variables
3
Branches
1
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
…
Viewing readonly version of main branch: v14
View latest version
README.md

πŸ–₯️ Home Server Monitor

A serverless monitoring solution for your home server with real-time push notifications.

🌐 Your App URLs

  • Web UI: https://halffullheartbeat.val.run
  • Heartbeat Endpoint: POST https://halffullheartbeat.val.run/heartbeat

πŸš€ Quick Setup

Step 1: Generate VAPID Keys for Push Notifications

  1. Go to https://www.val.town/v/halffullheart/heartbeat/generate-vapid-keys
  2. Click "Run" to generate your VAPID keys
  3. Copy the keys from the output

Step 2: Add Environment Variables

  1. Go to your val settings: https://www.val.town/v/halffullheart/heartbeat
  2. Click "Environment Variables"
  3. Add these three variables:
    • VAPID_PUBLIC_KEY - from step 1
    • VAPID_PRIVATE_KEY - from step 1
    • VAPID_EMAIL - your email (e.g., mailto:you@example.com)

Step 3: Configure Your Home Server

Add a cron job or scheduled task on your home server to ping the heartbeat endpoint every 15 minutes:

Linux/Mac (crontab):

# Add to crontab (run: crontab -e) */15 * * * * curl -X POST https://halffullheartbeat.val.run/heartbeat

Windows (Task Scheduler PowerShell):

# Run every 15 minutes $action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-Command "Invoke-WebRequest -Uri https://halffullheartbeat.val.run/heartbeat -Method POST"' $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 15) Register-ScheduledTask -TaskName "ServerHeartbeat" -Action $action -Trigger $trigger

Docker (if your server runs Docker):

# Run this container on your server docker run -d --name heartbeat --restart unless-stopped \ alpine/curl:latest sh -c \ "while true; do curl -X POST https://halffullheartbeat.val.run/heartbeat; sleep 900; done"

Simple Bash Script:

#!/bin/bash # Save as heartbeat.sh and run: ./heartbeat.sh & while true; do curl -X POST https://halffullheartbeat.val.run/heartbeat sleep 900 # 15 minutes done

Step 4: Subscribe to Notifications

  1. Open the web UI: https://halffullheartbeat.val.run
  2. Click "Enable Notifications"
  3. Grant notification permissions when prompted

πŸ“± How It Works

  1. Your Server: Sends a heartbeat every 15 minutes to the /heartbeat endpoint
  2. Monitor: Checks every 15 minutes if a heartbeat was received in the last hour
  3. Notifications: If no heartbeat for 1+ hour, sends push notifications to all subscribers
  4. Web UI: Real-time status display that updates every 30 seconds

πŸ”§ API Endpoints

POST /heartbeat

Your server calls this endpoint every 15 minutes.

Response:

{ "success": true, "timestamp": 1234567890 }

GET /status

Get current server status.

Response:

{ "lastHeartbeat": 1234567890, "isOnline": true, "minutesSince": 5, "currentTime": 1234567890 }

POST /subscribe

Subscribe to push notifications (called automatically by web UI).

πŸ› οΈ Architecture

  • main.ts: HTTP endpoint with web UI (PWA)
  • monitor.ts: Interval function (runs every 15 minutes)
  • SQLite Database: Stores heartbeats and notification subscriptions
  • Web Push: VAPID-based push notifications

πŸ“Š Database Schema

heartbeats table:

  • id - Auto-increment primary key
  • timestamp - Unix timestamp in milliseconds

subscriptions table:

  • id - Auto-increment primary key
  • endpoint - Push notification endpoint (unique)
  • p256dh - Public key for encryption
  • auth - Authentication secret
  • created_at - Subscription timestamp

🎨 Features

  • βœ… Real-time server status monitoring
  • βœ… PWA (Progressive Web App) installable on mobile
  • βœ… Push notifications when server goes down
  • βœ… Beautiful, responsive UI
  • βœ… Automatic cleanup of invalid subscriptions
  • βœ… CORS-enabled API
  • βœ… Service Worker for offline support

πŸ” Security

  • Environment variables for sensitive keys
  • VAPID keys for authenticated push notifications
  • CORS headers for API access
  • Unique subscription endpoints per device

πŸ“ Notes

  • Server is considered "down" after 1 hour without heartbeat
  • Monitor runs every 15 minutes (configurable in monitor.ts)
  • Notifications sent to all active subscribers
  • Invalid subscriptions automatically removed
  • SQLite database scoped to this val

πŸ› Troubleshooting

No notifications?

  • Check that VAPID environment variables are set
  • Ensure you granted notification permissions
  • Check monitor.ts logs for errors

Server showing offline?

  • Verify your server's cron job is running
  • Check that the heartbeat endpoint is reachable
  • Look at the heartbeat timestamps in the database

Test the heartbeat:

curl -X POST https://halffullheartbeat.val.run/heartbeat

πŸ“ž Support

For issues or questions, check the Val Town documentation: https://docs.val.town

FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
Β© 2026 Val Town, Inc.