mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
fix(ntfy): fix silent delivery, malformed payload, and tag fallthrough
### Description Fixes three issues with the `ntfy` notification provider to improve mobile delivery and readability. **Previous Behavior:** 1. **Silent Delivery:** Priority was hardcoded to `1` (Min). On Android and iOS, priority 1 notifications are delivered completely silently (no sound, no vibration, hidden from lock screen). 2. **Malformed Payload:** The `payload.data` object was appended as a raw, stringified JSON blob, making the notification body difficult to read. 3. **Tag Fallthrough:** The chained ternary logic for tags caused `error` level events to fall through to the default `information_source` icon. ### Changes Made - **Dynamic Priority Mapping:** Added `getPriority` to map severity levels to Ntfy's 1-5 scale. `info`/default maps to `2` (quiet ping), `warning` to `3` (default alert), `error` to `4` (high), and `critical` to `5` (max). - **Plain Text Data Formatting:** Added `formatData` to parse the JSON payload into a clean `- key: value` list. Markdown was purposely avoided to ensure clean rendering in mobile OS lock screen previews. - **Improved Tagging:** Refactored into a `getTags` helper. Added a base `floppy_disk` icon to instantly identify the notifications, and properly mapped `error` payloads to the `x` icon. ### Related Issues None (Direct Fix)
This commit is contained in:
@@ -1,5 +1,36 @@
|
||||
import type {EventPayload, DispatchResult} from '../types';
|
||||
|
||||
const getPriority = (level?: string): number => {
|
||||
switch (level) {
|
||||
case 'critical': return 5;
|
||||
case 'error': return 4;
|
||||
case 'warning': return 3;
|
||||
case 'info':
|
||||
default: return 2;
|
||||
}
|
||||
};
|
||||
|
||||
const formatData = (data: any): string => {
|
||||
if (!data || typeof data !== 'object') return '';
|
||||
return '\n\nDetails:\n' + Object.entries(data)
|
||||
.map(([key, value]) => {
|
||||
const stringVal = value !== null && typeof value === 'object' ? JSON.stringify(value) : String(value);
|
||||
return `- ${key}: ${stringVal}`;
|
||||
})
|
||||
.join('\n');
|
||||
};
|
||||
|
||||
const getTags = (level?: string): string[] => {
|
||||
const baseTags = ['floppy_disk'];
|
||||
|
||||
if (level === 'critical') baseTags.push('rotating_light');
|
||||
else if (level === 'error') baseTags.push('x');
|
||||
else if (level === 'warning') baseTags.push('warning');
|
||||
else baseTags.push('information_source');
|
||||
|
||||
return baseTags;
|
||||
};
|
||||
|
||||
export async function sendNtfy(
|
||||
config: { ntfyServerUrl?: string; ntfyTopic: string; ntfyToken?: string, ntfyUsername?: string, ntfyPassword?: string },
|
||||
payload: EventPayload
|
||||
@@ -11,9 +42,9 @@ export async function sendNtfy(
|
||||
const body = {
|
||||
topic: ntfyTopic,
|
||||
title: payload.title,
|
||||
message: payload.message + (payload.data ? `\n\nData:\n${JSON.stringify(payload.data, null, 2)}` : ''),
|
||||
priority: 1,
|
||||
tags: [payload.level === 'critical' ? 'rotating_light' : payload.level === 'warning' ? 'warning' : 'information_source'],
|
||||
message: payload.message + formatData(payload.data),
|
||||
priority: getPriority(payload.level),
|
||||
tags: getTags(payload.level),
|
||||
};
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
|
||||
Reference in New Issue
Block a user