I’m using the media db plugin to import movies, series and books to my vault. But since media db does not fill the streamingServices field for movies and series I decided to do it myself.
I coded a basic script using a template but I can’t get it to work, unfortunately…
<%*
tp.hooks.on_all_templates_executed(async () => {
const propertyName = "streamingServices";
const API_KEY = "xxx";
const file = tp.file.find_tfile(tp.file.path(true));
// Update front matter using Obsidian API
await app.fileManager.processFrontMatter(file, async (frontmatter) => {
const imdb_id = frontmatter.id;
if (imdb_id) {
//const providers = ["a","b","c"]; This works
const providers = await getProviders(imdb_id); //but this does not...
frontmatter[propertyName] = providers; //this also returns as expected an array ['Netflix', 'Disney Plus', 'TV+']
console.log("Streaming services:", providers); // works fine same as above
console.log("Streaming services:", frontmatter[propertyName]);
} else {
console.log("No IMDB ID found in the front matter");
}
});
async function getProviders(imdb_id) {
console.log("Getting providers");
console.log(imdb_id);
try {
// Get movie ID from IMDB ID
const idResponse = await fetch(
`https://api.themoviedb.org/3/movie/${imdb_id}/external_ids?api_key=${API_KEY}`
);
if (!idResponse.ok) {
throw new Error("Network response was not OK");
}
const idInfo = await idResponse.json();
const movie_id = idInfo.id;
// Get providers for the movie
const providersResponse = await fetch(
`https://api.themoviedb.org/3/movie/${movie_id}/watch/providers?api_key=${API_KEY}`
);
if (!providersResponse.ok) {
throw new Error("Network response was not OK");
}
const movies = await providersResponse.json();
const serviceArray = movies.results.TR?.flatrate;
if (serviceArray === undefined) {
console.log("No streaming services found");
return [];
}
const return_array = serviceArray.map((element) => element.provider_name);
return return_array;
} catch (error) {
console.error(
"There has been a problem with your fetch operation:",
error
);
}
}
});
-%>
Things I have tried
I have tried to use app.vault.read() approach which I’ve seen here. But still no chance. I have also searched the web for like 10 hours but either I got too much tunnel visioned or it is not possible to do so.
TLDR; I want to add custom properties to #movie files after I create them with templater(media db but it uses templater)
But the property is dependent of an API call.
I would try making the call to processFrontMatter without those async calls. In other words, prepare what you want to write before you call that function. This would be a safer approach instead of nesting the async calls like you’re currently doing.
I put my logic into my_script.js file and got the data just fine. services returns a Promise which has [[PromiseResult]]: Array(3) which has the right info. Also other console.logs return the same Promise but none of them changes the property, unfortunately.