const PUSHOVER_URL = 'https://api.pushover.net/1/messages.json'; const toNumber = (value, fallback) => { const parsed = Number(value); return Number.isFinite(parsed) ? parsed : fallback; }; export async function sendPushoverMessage(config, message) { const userKey = String(config?.pushover?.userKey || '').trim(); const apiToken = String(config?.pushover?.apiToken || '').trim(); if (!userKey || !apiToken) { throw new Error('Pushover requires userKey and apiToken.'); } const body = new URLSearchParams({ token: apiToken, user: userKey, title: String(message?.title || 'Vault Alert'), message: String(message?.message || ''), priority: String(toNumber(message?.priority, 0)) }); if (message?.url) { body.set('url', String(message.url)); } if (message?.urlTitle) { body.set('url_title', String(message.urlTitle)); } if (message?.sound) { body.set('sound', String(message.sound)); } const response = await fetch(PUSHOVER_URL, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body }); if (!response.ok) { const text = await response.text().catch(() => ''); throw new Error(`Pushover error (${response.status}): ${text || 'request failed'}`); } return response.json().catch(() => ({ ok: true })); }