104 lines
4.1 KiB
JavaScript
104 lines
4.1 KiB
JavaScript
|
||
const webPush = {
|
||
async init() {
|
||
if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
|
||
console.error('[WebPush] Push повідомлення не підтримуються');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
// Отримуємо публічний ключ VAPID із сервера
|
||
const uuid = localStorage.getItem('uuid');
|
||
const res = await fetch(`${CONFIG.api}push/key`, {
|
||
method: 'GET',
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
"Authorization": uuid
|
||
}
|
||
});
|
||
const { publicKey } = await res.json();
|
||
|
||
// Перетворюємо ключ
|
||
function urlBase64ToUint8Array(base64String) {
|
||
const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
|
||
const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
|
||
const raw = atob(base64);
|
||
return Uint8Array.from([...raw].map(ch => ch.charCodeAt(0)));
|
||
}
|
||
|
||
// Беремо вже зареєстрований Service Worker
|
||
const registration = await navigator.serviceWorker.ready;
|
||
|
||
// Перевіряємо, чи є підписка
|
||
let subscription = await registration.pushManager.getSubscription();
|
||
|
||
if (!subscription) {
|
||
|
||
// Запитуємо дозвіл
|
||
const permission = await Notification.requestPermission();
|
||
if (permission !== 'granted') {
|
||
console.warn('[WebPush] Push повідомлення заборонено користувачем');
|
||
return;
|
||
}
|
||
|
||
// Підписка на push
|
||
subscription = await registration.pushManager.subscribe({
|
||
userVisibleOnly: true,
|
||
applicationServerKey: urlBase64ToUint8Array(publicKey)
|
||
});
|
||
|
||
// дані пристроя
|
||
const deviceInfo = {
|
||
name: navigator.userAgent,
|
||
model: navigator.platform || "unknown"
|
||
};
|
||
|
||
// Надсилання на сервер
|
||
await fetch(`${CONFIG.api}push/subscribe`, {
|
||
method: 'POST',
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
"Authorization": uuid
|
||
},
|
||
body: JSON.stringify({ subscription, device: deviceInfo })
|
||
});
|
||
|
||
console.log('[WebPush] Push підписка готова:', subscription);
|
||
|
||
console.log('[WebPush] Створено нову підписку');
|
||
} else {
|
||
console.log('[WebPush] Підписка вже існує');
|
||
}
|
||
|
||
} catch (err) {
|
||
console.error('[WebPush] Помилка ініціалізації push:', err);
|
||
}
|
||
},
|
||
|
||
async unsubscribe() {
|
||
const uuid = localStorage.getItem('uuid');
|
||
const registration = await navigator.serviceWorker.ready;
|
||
const subscription = await registration.pushManager.getSubscription();
|
||
|
||
if (subscription) {
|
||
// видаляємо підписку у браузері
|
||
const success = await subscription.unsubscribe();
|
||
|
||
if (success) {
|
||
console.log("[WebPush] Локальна підписка скасована");
|
||
|
||
// повідомляємо сервер
|
||
await fetch(`${CONFIG.api}push//unsubscribe`, {
|
||
method: "DELETE",
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
"Authorization": uuid
|
||
},
|
||
body: JSON.stringify({ endpoint: subscription.endpoint })
|
||
});
|
||
}
|
||
} else {
|
||
console.log("[WebPush] Підписки немає");
|
||
}
|
||
}
|
||
} |