This project now includes a Bun backend that polls IDA events and sends Web Push notifications to installed PWAs.
That means notifications can be delivered while the app is not open, including on iOS (when installed to Home Screen and push permission is granted).
- Frontend PWA:
- Installable app shell + service worker
- Subscribes to push and registers subscription with backend
- Supports city-based notification filter (for example
Odense) - Shows latest events snapshot from backend
- Bun backend:
- Polls IDA API on a schedule
- Stores seen event IDs, push subscriptions, and subscriber preferences in SQLite
- Sends push messages to subscribers when new meetup IDs appear
- Sends deep links to IDA event pages using
meetupNumber
- Bun 1.0+
- HTTPS in production (required for Web Push on mobile/iOS)
- iOS 16.4+ for Home Screen Web Push support
- Install dependencies:
bun install- Generate VAPID keys:
bun run vapid:generate- Create
.envfrom.env.exampleand fill in values:
IDA_API_USERNAMEIDA_API_PASSWORD_B64(base64-encoded IDA password)IDA_AUTH_URLif the auth endpoint changesVAPID_PUBLIC_KEYVAPID_PRIVATE_KEYVAPID_SUBJECTCORS_ALLOW_ORIGINif frontend is hosted on a different origin than backend
To produce IDA_API_PASSWORD_B64 locally:
printf %s 'your-password-here' | base64bun run devOpen:
http://localhost:3000
- Ensure
.envexists and contains valid values for:
IDA_API_USERNAMEIDA_API_PASSWORD_B64VAPID_PUBLIC_KEYVAPID_PRIVATE_KEYVAPID_SUBJECT
- Build and start:
docker compose up -d --build- Check status and logs:
docker compose ps
docker compose logs -f ida-event-notifier- Stop:
docker compose downData is persisted in the named volume notifier-data.
git pull
docker compose up -d --build- Serve the app over HTTPS on a real domain (not plain HTTP).
- Open the site in Safari on iPhone.
- Add to Home Screen.
- Launch the installed app and tap Enable Background Push.
- Allow notifications when prompted.
The app now shows explicit subscription diagnostics (Push subscription: active ...) so you can confirm whether the backend has registered your device.
After this, the Bun backend can send push notifications even when the PWA is not open.
If you deploy this compose stack on a server, put it behind an HTTPS reverse proxy (for example Caddy, Nginx, or Traefik) and route your domain to this app.
iOS web push will not work on plain HTTP.
GET /api/config- public config including VAPID public keyGET /api/health- backend health and poll statusGET /api/events- latest fetched meetup snapshotPOST /api/subscribe- register push subscriptionPOST /api/unsubscribe- remove push subscriptionPOST /api/subscription-status- verify if a given device endpoint is registeredPOST /api/test-push- send test pushPOST /api/check-now- trigger immediate pollPOST /api/reset-seen- clear seen event IDs
data/notifier.dbis created automatically.- The backend exchanges
IDA_API_USERNAME+IDA_API_PASSWORD_B64for a bearer token and refreshes it automatically before expiry. - Stale subscriptions are removed when push endpoints return 404/410.
- Notifications can be filtered per subscriber by city name, matched against
meetup.location.city. - Notification click opens a deep link to
https://ida.dk/arrangementer-og-kurser/arrangementer/{meetupNumber}when available. - On first backend poll, current events are used as baseline and no push is sent.