- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
11 KiB
11 KiB
WebPush Browser-Nutzung
Vollständige Anleitung zur Verwendung des WebPush Moduls im Browser.
Quick Start
1. Demo-Seite aufrufen
Die Demo-Seite befindet sich unter:
src/Framework/WebPush/templates/demo.view.php
Du musst eine Route für die Demo-Seite erstellen (siehe unten).
2. Automatische Integration (main.js)
Das WebPush Modul wird automatisch beim App-Start initialisiert und ist global unter window.webPushManager verfügbar.
// main.js initialisiert automatisch:
if (WebPushManager.isSupported()) {
window.webPushManager = new WebPushManager({
apiBase: '/api/push',
onSubscriptionChange: (subscription) => {
console.log('🔔 Push subscription changed:',
subscription ? 'Subscribed' : 'Unsubscribed');
}
});
}
Browser Console Nutzung
Du kannst das WebPush Modul direkt über die Browser-Console verwenden:
Initialisierung prüfen
// Prüfen ob WebPush verfügbar ist
console.log(window.webPushManager); // WebPushManager Instanz
// Browser-Support prüfen
if (window.webPushManager) {
console.log('✅ WebPush ist verfügbar');
} else {
console.log('❌ WebPush nicht initialisiert');
}
WebPush initialisieren
// WebPush initialisieren (registriert Service Worker und holt VAPID Key)
const isSubscribed = await window.webPushManager.init();
console.log('Subscribed:', isSubscribed);
Push-Benachrichtigungen abonnieren
// Berechtigung anfordern und abonnieren
try {
const subscription = await window.webPushManager.subscribe();
console.log('✅ Erfolgreich abonniert!', subscription);
} catch (error) {
console.error('❌ Fehler beim Abonnieren:', error);
}
Subscription-Status prüfen
// Aktuellen Subscription-Status abrufen
const subscription = await window.webPushManager.getSubscription();
if (subscription) {
console.log('✅ Abonniert:', subscription.endpoint);
} else {
console.log('❌ Nicht abonniert');
}
// Oder einfach:
const isSubscribed = await window.webPushManager.isSubscribed();
console.log('Subscribed:', isSubscribed);
Test-Benachrichtigung senden
// Test-Benachrichtigung mit Standard-Text
await window.webPushManager.sendTestNotification();
// Test-Benachrichtigung mit eigenem Text
await window.webPushManager.sendTestNotification(
'Mein Titel',
'Meine Nachricht hier!'
);
Push-Benachrichtigungen deaktivieren
// Abonnement beenden
const success = await window.webPushManager.unsubscribe();
if (success) {
console.log('✅ Erfolgreich deabonniert');
} else {
console.log('❌ Deabonnieren fehlgeschlagen');
}
Berechtigungsstatus prüfen
// Notification Permission prüfen
const permission = window.webPushManager.getPermissionStatus();
console.log('Permission:', permission);
// Mögliche Werte: 'granted', 'denied', 'default'
Eigene Integration in Templates
Einfache Button-Integration
<button onclick="subscribeToWebPush()">
🔔 Push-Benachrichtigungen aktivieren
</button>
<script>
async function subscribeToWebPush() {
if (!window.webPushManager) {
alert('WebPush nicht verfügbar');
return;
}
try {
// Initialisieren falls noch nicht geschehen
if (!await window.webPushManager.isSubscribed()) {
await window.webPushManager.init();
}
// Abonnieren
await window.webPushManager.subscribe();
alert('✅ Push-Benachrichtigungen aktiviert!');
} catch (error) {
alert('❌ Fehler: ' + error.message);
}
}
</script>
Status-Anzeige mit Auto-Update
<div id="push-status">
Status: <span id="status-text">Prüfe...</span>
</div>
<button id="toggle-push" onclick="toggleWebPush()">
Push aktivieren
</button>
<script>
let isSubscribed = false;
async function updatePushStatus() {
if (!window.webPushManager) return;
isSubscribed = await window.webPushManager.isSubscribed();
const statusText = document.getElementById('status-text');
const toggleBtn = document.getElementById('toggle-push');
if (isSubscribed) {
statusText.textContent = '✅ Aktiv';
toggleBtn.textContent = 'Push deaktivieren';
} else {
statusText.textContent = '❌ Inaktiv';
toggleBtn.textContent = 'Push aktivieren';
}
}
async function toggleWebPush() {
if (!window.webPushManager) {
alert('WebPush nicht verfügbar');
return;
}
try {
if (!isSubscribed) {
await window.webPushManager.subscribe();
} else {
await window.webPushManager.unsubscribe();
}
await updatePushStatus();
} catch (error) {
alert('Fehler: ' + error.message);
}
}
// Status beim Laden aktualisieren
document.addEventListener('DOMContentLoaded', () => {
if (window.webPushManager) {
window.webPushManager.init().then(updatePushStatus);
}
});
</script>
Route für Demo-Seite erstellen
Füge diese Route in deinem Router hinzu (z.B. in WebRoutes.php):
use App\Framework\Attributes\Route;
use App\Framework\Http\Method;
final readonly class WebPushDemoController
{
#[Route(path: '/webpush/demo', method: Method::GET)]
public function demo(): ViewResult
{
return new ViewResult(
template: 'framework/webpush/demo',
data: []
);
}
}
Dann kannst du die Demo unter https://localhost/webpush/demo aufrufen.
Erweiterte Verwendung
Mit Callbacks
// Eigener WebPushManager mit Callbacks
import { WebPushManager } from '/resources/js/modules/webpush/WebPushManager.js';
const webPush = new WebPushManager({
apiBase: '/api/push',
serviceWorkerUrl: '/js/sw-push.js',
vapidPublicKey: 'YOUR_PUBLIC_KEY', // Optional, wird sonst vom Server geholt
onSubscriptionChange: (subscription) => {
if (subscription) {
console.log('User subscribed!');
// Update UI, save to database, etc.
} else {
console.log('User unsubscribed!');
// Update UI, cleanup, etc.
}
}
});
await webPush.init();
Fehlerbehandlung
try {
await window.webPushManager.subscribe();
} catch (error) {
switch (error.message) {
case 'Notification permission denied':
alert('Bitte erlaube Push-Benachrichtigungen in deinem Browser');
break;
case 'Service Workers are not supported':
alert('Dein Browser unterstützt keine Push-Benachrichtigungen');
break;
default:
alert('Fehler: ' + error.message);
}
}
API-Endpunkte
Das WebPush Modul erwartet folgende Backend-Endpunkte:
GET /api/push/vapid-key- VAPID Public Key abrufenPOST /api/push/subscribe- Subscription speichernPOST /api/push/unsubscribe- Subscription entfernenPOST /api/push/test- Test-Benachrichtigung senden
Diese sind bereits im Framework unter WebPushController.php implementiert.
Browser-Kompatibilität
- ✅ Chrome/Edge 42+
- ✅ Firefox 44+
- ✅ Safari 16+ (macOS Ventura+)
- ✅ Opera 39+
- ❌ iOS Safari (keine Unterstützung für Web Push)
Prüfe die Unterstützung mit:
if (WebPushManager.isSupported()) {
// Browser unterstützt Web Push
} else {
// Browser unterstützt Web Push nicht
}
Debugging
Service Worker Status prüfen
// In Browser Console:
navigator.serviceWorker.getRegistrations().then(registrations => {
console.log('Service Worker Registrations:', registrations);
});
Subscription Details anzeigen
const subscription = await window.webPushManager.getSubscription();
if (subscription) {
console.log('Endpoint:', subscription.endpoint);
console.log('Keys:', subscription.toJSON());
}
Browser-Berechtigungen zurücksetzen
- Chrome: Einstellungen → Datenschutz und Sicherheit → Website-Einstellungen → Benachrichtigungen
- Firefox: Einstellungen → Datenschutz & Sicherheit → Berechtigungen → Benachrichtigungen
- Safari: Einstellungen → Websites → Benachrichtigungen
Troubleshooting
"Service Workers are not supported"
- Browser unterstützt keine Service Workers
- HTTPS erforderlich (außer localhost)
"Notification permission denied"
- User hat Berechtigung verweigert
- Browser-Berechtigungen zurücksetzen (siehe oben)
"Failed to fetch VAPID public key"
- Backend nicht erreichbar unter
/api/push/vapid-key - VAPID Keys nicht generiert (siehe
php console.php webpush:keys)
Service Worker registriert sich nicht
- Prüfe ob Datei unter
/js/sw-push.jsexistiert - Prüfe Browser Console für Service Worker Fehler
- Stelle sicher dass HTTPS verwendet wird
Vollständiges Beispiel
<!DOCTYPE html>
<html>
<head>
<title>WebPush Test</title>
</head>
<body>
<h1>WebPush Test</h1>
<p>Status: <span id="status">Prüfe...</span></p>
<button id="init-btn" onclick="init()">Initialisieren</button>
<button id="sub-btn" onclick="subscribe()" disabled>Abonnieren</button>
<button id="unsub-btn" onclick="unsubscribe()" disabled>Deabonnieren</button>
<button id="test-btn" onclick="sendTest()" disabled>Test senden</button>
<script type="module">
import { WebPushManager } from '/resources/js/modules/webpush/WebPushManager.js';
let webPush = null;
window.init = async function() {
webPush = new WebPushManager({
apiBase: '/api/push',
onSubscriptionChange: updateUI
});
const isSubscribed = await webPush.init();
updateUI(isSubscribed ? await webPush.getSubscription() : null);
document.getElementById('init-btn').disabled = true;
};
window.subscribe = async function() {
try {
await webPush.subscribe();
alert('Erfolgreich abonniert!');
} catch (e) {
alert('Fehler: ' + e.message);
}
};
window.unsubscribe = async function() {
try {
await webPush.unsubscribe();
alert('Erfolgreich deabonniert!');
} catch (e) {
alert('Fehler: ' + e.message);
}
};
window.sendTest = async function() {
try {
await webPush.sendTestNotification('Test', 'Das ist ein Test!');
alert('Test-Benachrichtigung gesendet!');
} catch (e) {
alert('Fehler: ' + e.message);
}
};
function updateUI(subscription) {
const status = document.getElementById('status');
const subBtn = document.getElementById('sub-btn');
const unsubBtn = document.getElementById('unsub-btn');
const testBtn = document.getElementById('test-btn');
if (subscription) {
status.textContent = '✅ Abonniert';
subBtn.disabled = true;
unsubBtn.disabled = false;
testBtn.disabled = false;
} else {
status.textContent = '❌ Nicht abonniert';
subBtn.disabled = false;
unsubBtn.disabled = true;
testBtn.disabled = true;
}
}
</script>
</body>
</html>