import { getSpotifyAccessToken } from "https://esm.town/v/dthyresson/getSpotifyAccessToken";
import { blob } from "https://esm.town/v/std/blob";
import { email } from "https://esm.town/v/std/email";
import { kebabCase } from "npm:lodash-es";
const SPOTIFY_TRACK_KEY_PREFIX = "spotify_track";
type SpotifyTrackUrlFormat = "web" | "app";
export type SpotifyTrackUrlOptions = {
format?: SpotifyTrackUrlFormat;
};
export function buildSpotifyTrackKey(artist: string, title: string) {
const key = `${SPOTIFY_TRACK_KEY_PREFIX}_artist:${kebabCase(artist)}_title:${kebabCase(title)}`.toLowerCase();
console.debug("buildSpotifyTrackKey", artist, title, key);
return key;
}
export function spotifyTrackUrl(track, format: SpotifyTrackUrlFormat) {
if (!track) return;
if (format === "app") {
return spotifyTrackAppLink(track);
}
const url = `https://open.spotify.com/track/${track.id}`;
return url;
}
export function spotifyTrackAppLink(track) {
if (!track) return;
const url = `spotify://track/${track.id}`;
return url;
}
async function cacheTrack(spotifyTrackKey: string, track: any) {
console.debug(`Caching track ${spotifyTrackKey}`);
await blob.setJSON(spotifyTrackKey, track);
if (track.id) {
const artist = track.artists[0].name;
const title = track.name;
const key = buildSpotifyTrackKey(artist, title);
console.debug(`Caching track ${key}`);
await blob.setJSON(key, track);
await blob.setJSON(`${SPOTIFY_TRACK_KEY_PREFIX}_id:${track.id}`, track);
}
}
export async function getSpotifyTrackUrl(artist: string, title: string, options?: SpotifyTrackUrlOptions) {
const format = options?.format || "web";
const spotifyTrackKey = buildSpotifyTrackKey(artist, title);
const cachedTrack = await blob.getJSON(spotifyTrackKey);
if (cachedTrack) {
console.debug(`Found track in cache for ${spotifyTrackKey}`);
const result = { trackUrl: spotifyTrackUrl(cachedTrack, format), ...cachedTrack };
return result;
}
const accessToken = await getSpotifyAccessToken();
const query = `track:${title} artist:${artist}`;
const encodedQuery = encodeURIComponent(query);
const response = await fetch(`https://api.spotify.com/v1/search?q=${query}&type=track`, {
headers: {
"Authorization": `Bearer ${accessToken.access_token}`,
},
});
if (response.ok) {
const searchData = await response.json();
const track = searchData.tracks.items[0];
if (track) {
await cacheTrack(spotifyTrackKey, track);
}
const trackUrl = spotifyTrackUrl(track, format);
if (!trackUrl) {
const text = `Missing track id: ${artist} ${title}`;
console.error(text);
await email({ subject: "Error in getSpotifyTrackUrl", text });
return;
}
const result = { trackUrl, ...track };
return result;
}