fix: handle isbn as array from Listenarr search results

This commit is contained in:
2026-07-01 08:21:48 -04:00
parent 36e71ead7b
commit 82e1f1b010
+95
View File
@@ -0,0 +1,95 @@
import axios from "axios";
const LISTENARR_URL = process.env.LISTENARR_URL || "";
const LISTENARR_API_KEY = process.env.LISTENARR_API_KEY || "";
const listenarrApi = axios.create({
baseURL: LISTENARR_URL,
timeout: 15000,
headers: {
"X-Api-Key": LISTENARR_API_KEY,
"Content-Type": "application/json",
},
});
export async function searchAudiobooks(
query: string
): Promise<any[]> {
const resp = await listenarrApi.get("/api/v1/search/audible", {
params: { query },
});
return resp.data?.results || [];
}
export async function addAudiobook(options: {
asin: string;
title: string;
authors: string[];
imageUrl?: string;
description?: string;
monitored?: boolean;
autoSearch?: boolean;
subtitle?: string;
narrators?: string[];
publisher?: string;
language?: string;
releaseDate?: string;
runtimeLengthMin?: number;
genres?: string[];
series?: string;
seriesNumber?: string;
isbn?: string;
explicit?: boolean;
abridged?: boolean;
}): Promise<any> {
// Defensive: ensure series/seriesNumber are always strings, not arrays
const series = typeof options.series === "string" ? options.series : "";
const seriesNumber = typeof options.seriesNumber === "string" ? options.seriesNumber : "";
const body: any = {
metadata: {
asin: options.asin,
title: options.title,
subtitle: options.subtitle || "",
source: "audible",
authors: options.authors || [],
narrators: options.narrators || [],
imageUrl: options.imageUrl || "",
description: options.description || "",
publisher: options.publisher || "",
language: options.language || "",
releaseDate: options.releaseDate || "",
runtime: options.runtimeLengthMin ? options.runtimeLengthMin * 60 : 0,
genres: options.genres || [],
series: series,
seriesNumber: seriesNumber,
isbn: Array.isArray(options.isbn) ? options.isbn : (typeof options.isbn === "string" && options.isbn ? options.isbn.split(",") : []),
explicit: options.explicit || false,
abridged: options.abridged || false,
},
autoSearch: options.autoSearch !== false,
monitored: options.monitored !== false,
qualityProfileId: 1,
};
const resp = await listenarrApi.post("/api/v1/library/add", body);
return resp.data;
}
export async function getListenarrStatus(): Promise<{
connected: boolean;
data?: any;
error?: string;
}> {
try {
const resp = await listenarrApi.get("/api/v1/system/info", {
timeout: 5000,
});
return { connected: true, data: resp.data };
} catch (error: any) {
return {
connected: false,
error: error?.message || "Failed to connect to Listenarr",
};
}
}