// public/zixflow-sw.js
const WRITE_KEY = 'YOUR_API_KEY';
const ZIXFLOW_API = 'https://events.zixflow.in/v1/track';
// Store user ID (set from main app)
self.__ZIXFLOW_USER_ID__ = null;
// Listen for messages from main app
self.addEventListener('message', (event) => {
if (event.data?.type === 'SET_USER_ID') {
self.__ZIXFLOW_USER_ID__ = event.data.userId;
}
});
// Track delivery
self.addEventListener('push', (event) => {
const data = event.data?.json() ?? {};
const deliveryId = data['Zixflow-Delivery-ID'] ?? '';
const token = data['Zixflow-Delivery-Token'] ?? '';
// Track delivery
if (deliveryId && token) {
trackEvent('Push Notification Delivered', {
'Zixflow-Delivery-ID': deliveryId,
'Zixflow-Delivery-Token': token,
});
}
// Parse action buttons
const buttons = parseActionButtons(data.action_buttons);
// Show notification
event.waitUntil(
self.registration.showNotification(data.title ?? 'Notification', {
body: data.body ?? '',
icon: data.image_url,
badge: data.badge_url,
data: data,
actions: buttons,
})
);
});
// Track opens and action clicks
self.addEventListener('notificationclick', (event) => {
const data = event.notification.data ?? {};
const deliveryId = data['Zixflow-Delivery-ID'] ?? '';
const token = data['Zixflow-Delivery-Token'] ?? '';
event.notification.close();
// Always track opened
if (deliveryId && token) {
trackEvent('Push Notification Opened', {
'Zixflow-Delivery-ID': deliveryId,
'Zixflow-Delivery-Token': token,
});
}
// Handle action button click
if (event.action) {
const actionIndex = parseInt(event.action.replace(/\D/g, ''), 10);
const rawButtons = parseActionButtonsRaw(data.action_buttons);
const actionName = rawButtons[actionIndex]?.name ?? '';
const actionDeeplink = rawButtons[actionIndex]?.deeplink ?? '';
trackEvent('Push Notification Action Clicked', {
'Zixflow-Delivery-ID': deliveryId,
'Zixflow-Delivery-Token': token,
'action_index': actionIndex,
'action_name': actionName,
'action_deeplink': actionDeeplink,
'source': 'web_push',
});
if (actionDeeplink) {
event.waitUntil(clients.openWindow(actionDeeplink));
return;
}
}
// Default navigation
const deeplink = data['deeplink_url'] ?? '';
event.waitUntil(
deeplink ? clients.openWindow(deeplink) : clients.openWindow('/')
);
});
// Helper: Track event
function trackEvent(eventName, properties) {
fetch(ZIXFLOW_API, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${btoa(WRITE_KEY + ':')}`,
},
body: JSON.stringify({
event: eventName,
userId: self.__ZIXFLOW_USER_ID__,
properties: properties,
}),
}).catch((err) => {
console.error('Failed to track event:', err);
});
}
// Helper: Parse action buttons for notification API
function parseActionButtons(raw) {
const buttons = parseActionButtonsRaw(raw);
return buttons.slice(0, 2).map((btn, i) => ({
action: `ACTION_${i}`,
title: btn.name || `Action ${i + 1}`,
}));
}
// Helper: Parse raw action buttons data
function parseActionButtonsRaw(raw) {
if (!raw) return [];
try {
return typeof raw === 'string' ? JSON.parse(raw) : raw;
} catch {
return [];
}
}