mqtt setup panel: match jellyfin webhook plugin's actual fields
All checks were successful
Build and Push Docker Image / build (push) Successful in 1m4s
All checks were successful
Build and Push Docker Image / build (push) Successful in 1m4s
the plugin's MQTT destination form uses different field names and a different shape than what we'd documented: - single 'Broker URL' → split 'MQTT Server' + 'MQTT Port' (+ 'Use TLS') - 'Events' → 'Notification Type', and 'Item Updated' doesn't exist; jellyfin reports every file change as 'Item Added' - plugin requires Webhook Name, Status, Use Credentials, Quality of Service fields that weren't in the panel derive server/port/TLS from the saved mqtt_url so the copy buttons give back the exact values the plugin expects. handler still accepts ItemUpdated as a safety net in case the plugin adds it later.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "netfelix-audio-fix",
|
||||
"version": "2026.04.14.2",
|
||||
"version": "2026.04.14.3",
|
||||
"scripts": {
|
||||
"dev:server": "NODE_ENV=development bun --hot server/index.tsx",
|
||||
"dev:client": "vite",
|
||||
|
||||
@@ -28,6 +28,23 @@ const HANDLEBARS_TEMPLATE = `{
|
||||
"itemType": "{{ItemType}}"
|
||||
}`;
|
||||
|
||||
/**
|
||||
* Pull host / port / TLS out of the mqtt_url the user saved. The Jellyfin
|
||||
* plugin's MQTT destination asks for host and port as separate fields
|
||||
* plus an explicit TLS checkbox, whereas we store a single URL.
|
||||
*/
|
||||
function parseBroker(raw: string): { host: string; port: string; useTls: boolean } {
|
||||
if (!raw) return { host: "", port: "1883", useTls: false };
|
||||
try {
|
||||
const u = new URL(raw);
|
||||
const useTls = u.protocol === "mqtts:" || u.protocol === "wss:";
|
||||
const port = u.port || (useTls ? "8883" : "1883");
|
||||
return { host: u.hostname, port, useTls };
|
||||
} catch {
|
||||
return { host: "", port: "1883", useTls: false };
|
||||
}
|
||||
}
|
||||
|
||||
function CopyableValue({ label, value, mono = true }: { label: string; value: string; mono?: boolean }) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
const copy = async () => {
|
||||
@@ -230,13 +247,40 @@ export function MqttSection({ cfg, locked }: { cfg: Record<string, string>; lock
|
||||
✓ Plugin detected{plugin.plugin?.Version ? ` (v${plugin.plugin.Version})` : ""}. Add an MQTT destination with:
|
||||
</p>
|
||||
)}
|
||||
<div className="mt-2">
|
||||
<CopyableValue label="Broker URL" value={url || "mqtt://broker:1883"} />
|
||||
<CopyableValue label="Topic" value={topic || "jellyfin/events"} />
|
||||
<CopyableValue label="Events" value="Item Added, Item Updated" mono={false} />
|
||||
<CopyableValue label="Item types" value="Movie, Episode" mono={false} />
|
||||
<CopyableValue label="Template" value={HANDLEBARS_TEMPLATE} />
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 mt-1 mb-2">
|
||||
Open Jellyfin → <span className="font-mono">Dashboard → Plugins → Webhook → Add Generic Destination →</span> MQTT
|
||||
tab, and fill in:
|
||||
</p>
|
||||
{(() => {
|
||||
const broker = parseBroker(url);
|
||||
const useCredentials = !!(username || cfg.mqtt_password);
|
||||
return (
|
||||
<div className="mt-2">
|
||||
<CopyableValue label="Webhook Name" value="Audio Fix" mono={false} />
|
||||
<CopyableValue label="Webhook Url" value="n/a" mono={false} />
|
||||
<CopyableValue label="Status" value="Enabled" mono={false} />
|
||||
<CopyableValue label="Notification Type" value="Item Added" mono={false} />
|
||||
<CopyableValue label="Item Type" value="Movies, Episodes" mono={false} />
|
||||
<CopyableValue label="MQTT Server" value={broker.host || "broker.lan"} />
|
||||
<CopyableValue label="MQTT Port" value={broker.port} />
|
||||
<CopyableValue label="Use TLS" value={broker.useTls ? "Enabled" : "Disabled"} mono={false} />
|
||||
<CopyableValue label="Use Credentials" value={useCredentials ? "Enabled" : "Disabled"} mono={false} />
|
||||
{useCredentials && (
|
||||
<>
|
||||
<CopyableValue label="Username" value={username || "(same as above)"} />
|
||||
<CopyableValue label="Password" value={cfg.mqtt_password ? "(same as above)" : ""} />
|
||||
</>
|
||||
)}
|
||||
<CopyableValue label="Topic" value={topic || "jellyfin/events"} />
|
||||
<CopyableValue label="Quality of Service" value="At most once (QoS 0)" mono={false} />
|
||||
<CopyableValue label="Template" value={HANDLEBARS_TEMPLATE} />
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
<p className="text-[11px] text-gray-400 mt-2">
|
||||
Jellyfin's plugin doesn't expose an "Item Updated" event. When we rewrite a file, Jellyfin treats it as a new add
|
||||
and fires <span className="font-mono">Item Added</span> — that's the event we listen for.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user