import { logger } from '@/lib/logger'; import type { StateChange, SubscriptionRecord } from './types'; import { sendWebPush } from './web-push'; import { getVapidKeys } from './vapid'; interface UnifiedPushPayload { kind: 'jmap-state-change'; title: string; body: string; changed: Record>; } function buildPayload(record: SubscriptionRecord, change: StateChange): UnifiedPushPayload { const types = new Set(); for (const perAccount of Object.values(change.changed)) { for (const type of Object.keys(perAccount)) types.add(type); } const hasEmail = types.has('Email') || types.has('EmailDelivery'); return { kind: 'jmap-state-change', title: hasEmail ? 'New mail' : 'Mailbox updated', body: record.accountLabel ?? '', changed: change.changed, }; } export async function sendUnifiedPush( record: SubscriptionRecord, change: StateChange, ): Promise { try { const vapid = await getVapidKeys(); const payload = Buffer.from(JSON.stringify(buildPayload(record, change)), 'utf-8'); const result = await sendWebPush({ endpoint: record.endpoint, p256dh: record.p256dh, auth: record.auth, payload, vapid, ttlSeconds: 60, urgency: 'high', }); if (!result.ok) { logger.warn('push: unified-push delivery failed', { status: result.status, body: result.body, }); return false; } return true; } catch (error) { logger.warn('push: unified-push delivery error', { error: error instanceof Error ? error.message : 'Unknown error', }); return false; } }