Let other applications send messages through the notification channels

POST /notifications/app-message delivers an app's message to every channel
with the new "Messages from connected apps" switch on (off by default),
through quiet hours, the digest and the log. API keys need the new "Send
notifications" permission, and their owner notifications:update; plain text,
http(s) links, 20 messages a minute per key. The electricity-price door and
this one now share one scoped-key check. /queue?batch=<id> opens and
highlights one batch order.
This commit is contained in:
maziggy
2026-09-27 12:45:50 +02:00
parent 4c590a4ee0
commit 6855d65d12
41 changed files with 706 additions and 59 deletions
@@ -54,6 +54,7 @@ export function AddNotificationModal({ provider, onClose }: AddNotificationModal
provider?.on_location_ha_sensor_alert ?? false
);
const [onFirstLayerComplete, setOnFirstLayerComplete] = useState(provider?.on_first_layer_complete ?? false);
const [onAppMessage, setOnAppMessage] = useState(provider?.on_app_message ?? false);
// Provider-specific config (scalar fields only — event_priorities is split out
// into its own state because it's an object, not a string).
@@ -213,6 +214,7 @@ export function AddNotificationModal({ provider, onClose }: AddNotificationModal
on_ha_sensor_alert: onHaSensorAlert,
on_location_ha_sensor_alert: onLocationHaSensorAlert,
on_first_layer_complete: onFirstLayerComplete,
on_app_message: onAppMessage,
};
if (isEditing) {
@@ -715,6 +717,18 @@ export function AddNotificationModal({ provider, onClose }: AddNotificationModal
</div>
</div>
{/* Messages other applications send (POST /notifications/app-message) */}
<div className="space-y-2 p-3 bg-bambu-dark rounded-lg">
<p className="text-xs text-bambu-gray uppercase tracking-wide mb-2">{t('notifications.connectedApps')}</p>
<div className="flex items-center justify-between">
<div>
<span className="text-sm text-white">{t('notifications.appMessages')}</span>
<span className="text-xs text-bambu-gray ml-1">{t('notifications.appMessagesDescription')}</span>
</div>
<Toggle checked={onAppMessage} onChange={setOnAppMessage} />
</div>
</div>
{/* Per-event ntfy priority (#990) */}
{providerType === 'ntfy' && (() => {
const enabledEvents: Array<{ key: string; label: string }> = [];