4.5 KiB
Powiadomienia Web Push
Powiadomienia obejmują:
- nowe ostrzeżenia meteorologiczne IMGW dla Polski,
- poranny brief dnia,
- wieczorny brief z prognozą na jutro,
- testowe powiadomienie wysyłane z
/settings.
Konfiguracja użytkownika znajduje się w widoku /settings.
Wymagania
Do wysyłki Web Push potrzebne są klucze VAPID:
WEB_PUSH_VAPID_PUBLIC_KEY=
WEB_PUSH_VAPID_PRIVATE_KEY=
WEB_PUSH_VAPID_SUBJECT=mailto:admin@example.com
Klucze można wygenerować poleceniem:
npx web-push generate-vapid-keys
Endpointy harmonogramu wymagają też sekretu crona w produkcji:
NOTIFICATIONS_CRON_SECRET=
Subskrypcje Web Push i historia wysyłek są zapisywane w SQLite:
WTR_DATABASE_PATH=./data/wtr.sqlite
Jeśli zmienna nie jest ustawiona, aplikacja używa ./data/wtr.sqlite względem katalogu projektu.
Preferencje Subskrypcji
Subskrypcja Web Push zapisuje:
- endpoint subskrypcji przeglądarki,
- region pogodowy
PLalboGLOBAL, - województwo dla oficjalnych ostrzeżeń IMGW w Polsce,
- język interfejsu,
- czy ostrzeżenia są aktywne,
- czy aktywny jest brief poranny,
- czy aktywny jest brief na jutro,
- współrzędne i nazwę lokalizacji,
- opcjonalny powiat TERYT,
- wybraną jednostkę temperatury dla briefów wysyłanych z serwera,
- wybraną jednostkę wiatru dla briefów wysyłanych z serwera.
Ostrzeżenia meteo są filtrowane po powiecie TERYT, jeśli lokalizacja go dostarcza. W przeciwnym razie używany jest fallback wojewódzki.
Dla subskrypcji GLOBAL oficjalne ostrzeżenia IMGW są wyłączone, province może być puste, a powiadomienia mogą obejmować brief poranny i brief na jutro oparte o prognozę modelową Open-Meteo.
Worker Self-Hosted
Worker powiadomień uruchamia się osobno od aplikacji:
npm run notifications:worker
Wymaga równolegle działającej aplikacji Next.js. Domyślnie odpytuje:
http://127.0.0.1:3000
Jeśli aplikacja działa pod innym adresem albo portem, ustaw:
WTR_APP_URL=http://127.0.0.1:4000
Worker wczytuje .env i .env.local. Zmienne ustawione bezpośrednio w shellu mają pierwszeństwo.
Harmonogram
Domyślna konfiguracja:
NOTIFICATIONS_WARNING_INTERVAL_MINUTES=5
NOTIFICATIONS_BRIEF_INTERVAL_MINUTES=5
NOTIFICATIONS_MORNING_BRIEF_TIME=07:00
NOTIFICATIONS_TOMORROW_BRIEF_TIME=18:00
Worker:
- sprawdza nowe ostrzeżenia co 5 minut,
- co 5 minut odpytuje endpointy briefów,
- endpoint
/api/notifications/daily-briefwysyła po 07:00 lokalnego czasu zapisanego w subskrypcji, - endpoint
/api/notifications/tomorrow-briefwysyła po 18:00 lokalnego czasu zapisanego w subskrypcji, - nie blokuje jednego harmonogramu błędem drugiego.
Endpointy harmonogramu nie uruchamiają się same bez workera albo zewnętrznego crona.
Endpointy briefów zwracają diagnostykę JSON z polami subscriptions, eligibleSubscriptions, sent, skipped,
failed oraz skippedReasons. Dla problemów z harmonogramem najważniejsze powody to:
disabled- subskrypcja istnieje, ale dany brief nie jest włączony w zapisanym stanie serwera,missingLocation- brief jest włączony, ale subskrypcja nie ma współrzędnych,beforeTime- lokalny czas subskrypcji jest jeszcze przed skonfigurowaną godziną,alreadySent- brief dla tej lokalnej daty został już oznaczony jako wysłany,noBrief- prognoza nie pozwoliła zbudować treści briefu.
Zewnętrzny Cron
Jeśli nie używasz npm run notifications:worker, zewnętrzny cron powinien wywoływać:
GET /api/notifications/check
GET /api/notifications/daily-brief
GET /api/notifications/tomorrow-brief
W produkcji dodaj jeden z nagłówków:
Authorization: Bearer <NOTIFICATIONS_CRON_SECRET>
x-cron-secret: <NOTIFICATIONS_CRON_SECRET>
Platformy
- iOS/iPadOS wymaga dodania PWA do ekranu początkowego i uruchomienia aplikacji z ikony.
- Android i desktop nie są blokowane wymogiem
standalone, jeśli przeglądarka obsługuje Web Push. - GPS i powiadomienia wymagają bezpiecznego kontekstu HTTPS poza wyjątkami typu
localhost.
Ograniczenia
lib/push-store.ts przechowuje subskrypcje i historię wysyłek w lokalnym SQLite przez better-sqlite3. Dane przetrwają restart procesu, jeśli plik wskazany przez WTR_DATABASE_PATH znajduje się w trwałym katalogu. Na self-hostingu warto backupować plik bazy razem z plikami -wal i -shm, jeśli istnieją.
Powiadomienie testowe jest wysyłane na konkretny endpoint subskrypcji przekazany z /settings, a nie broadcastowane do wszystkich urządzeń.