1// Service Worker for Braze Push Notifications 2// This service worker handles push events and notification clicks 3 4const CACHE_NAME = 'braze-push-v1' 5const NOTIFICATION_ICON = '/favicons/foxnews/favicon-192x192.png' 6const NOTIFICATION_BADGE = '/favicons/foxnews/favicon-96x96.png' 7 8// Install event 9self.addEventListener('install', (event) => { 10 console.log('Service Worker: Install event') 11 self.skipWaiting() 12}) 13 14// Activate event 15self.addEventListener('activate', (event) => { 16 console.log('Service Worker: Activate event') 17 event.waitUntil(self.clients.claim()) 18}) 19 20// Push event - handle incoming push notifications 21self.addEventListener('push', (event) => { 22 console.log('Service Worker: Push event received', event) 23 24 const notificationData = { 25 title: 'Fox News', 26 body: 'You have a new notification', 27 icon: NOTIFICATION_ICON, 28 badge: NOTIFICATION_BADGE, 29 tag: 'fox-news-notification', 30 requireInteraction: false, 31 actions: [ 32 { 33 action: 'open', 34 title: 'Open', 35 icon: '/favicons/foxnews/favicon-96x96.png' 36 }, 37 { 38 action: 'dismiss', 39 title: 'Dismiss' 40 } 41 ] 42 } 43 44 // Parse push data if available 45 if (event.data) { 46 try { 47 const data = event.data.json() 48 console.log('Service Worker: Push data received', data) 49 50 // Update notification with data from Braze 51 if (data.title) notificationData.title = data.title 52 if (data.body) notificationData.body = data.body 53 if (data.icon) notificationData.icon = data.icon 54 if (data.url) notificationData.data = { url: data.url } 55 if (data.braze_campaign_id) { 56 notificationData.data = { 57 ...notificationData.data, 58 braze_campaign_id: data.braze_campaign_id 59 } 60 } 61 } catch (error) { 62 console.error('Service Worker: Error parsing push data', error) 63 } 64 } 65 66 // Show notification 67 event.waitUntil( 68 self.registration.showNotification(notificationData.title, notificationData) 69 ) 70}) 71 72// Notification click event 73self.addEventListener('notificationclick', (event) => { 74 console.log('Service Worker: Notification click event', event) 75 76 event.notification.close() 77 78 if (event.action === 'dismiss') { 79 console.log('Service Worker: Notification dismissed') 80 return 81 } 82 83 // Default action or 'open' action 84 let urlToOpen = '/' 85 86 // Get URL from notification data 87 if (event.notification.data && event.notification.data.url) { 88 urlToOpen = event.notification.data.url 89 } 90 91 // Open or focus the window 92 event.waitUntil( 93 self.clients.matchAll({ type: 'window', includeUncontrolled: true }) 94 .then((clientList) => { 95 // Check if there's already a window open 96 for (const client of clientList) { 97 if (client.url.includes(self.location.origin) && 'focus' in client) { 98 client.navigate(urlToOpen) 99 return client.focus() 100 } 101 } 102 103 // Open new window if none exists 104 if (self.clients.openWindow) { 105 return self.clients.openWindow(urlToOpen) 106 } 107 }) 108 ) 109}) 110 111// Background sync event (if supported) 112self.addEventListener('sync', (event) => { 113 console.log('Service Worker: Background sync event', event.tag) 114 115 if (event.tag === 'braze-sync') { 116 event.waitUntil( 117 // Handle background sync for Braze data 118 syncBrazeData() 119 ) 120 } 121}) 122 123// Message event - handle messages from main thread 124self.addEventListener('message', (event) => { 125 console.log('Service Worker: Message received', event.data) 126 127 if (event.data && event.data.type === 'SKIP_WAITING') { 128 self.skipWaiting() 129 } 130}) 131 132// Helper function for background sync 133function syncBrazeData() { 134 try { 135 // This would typically sync any pending Braze data 136 console.log('Service Worker: Syncing Braze data') 137 // Implementation would depend on specific Braze requirements 138 } catch (error) { 139 console.error('Service Worker: Error syncing Braze data', error) 140 } 141} 142 143// Handle fetch events (optional - for caching) 144self.addEventListener('fetch', (event) => { 145 // Only handle requests for our domain 146 if (!event.request.url.startsWith(self.location.origin)) { 147 return 148 } 149 150 // Cache static assets
151 if (event.request.destination === 'image' || 152 event.request.destination === 'script' || 153 event.request.destination === 'style') { 154 event.respondWith( 155 caches.match(event.request) 156 .then((response) => { 157 if (response) { 158 return response 159 } 160 return fetch(event.request) 161 .then((response) => { 162 // Don't cache if not a valid response 163 if (!response || response.status !== 200 || response.type !== 'basic') { 164 return response 165 } 166 167 // Clone the response 168 const responseToCache = response.clone() 169 170 caches.open(CACHE_NAME) 171 .then((cache) => { 172 cache.put(event.request, responseToCache) 173 }) 174 175 return response 176 }) 177 }) 178 ) 179 } 180}) 181 182console.log('Service Worker: Script loaded successfully')
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.