/** * iTunes Search API integration for fetching release years * API Documentation: https://performance-partners.apple.com/search-api */ interface ItunesResult { wrapperType: string; kind: string; artistName: string; collectionName: string; trackName: string; releaseDate: string; primaryGenreName: string; } interface ItunesResponse { resultCount: number; results: ItunesResult[]; } /** * Get the earliest release year for a song from iTunes * @param artist Artist name * @param title Song title * @returns Release year or null if not found */ export async function getReleaseYearFromItunes(artist: string, title: string): Promise { try { // Construct search URL // entity=song ensures we get individual tracks // limit=10 to get a good range of potential matches (originals, remasters, best ofs) const term = encodeURIComponent(`${artist} ${title}`); const url = `https://itunes.apple.com/search?term=${term}&entity=song&limit=10`; const response = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } }); if (!response.ok) { console.error(`iTunes API error: ${response.status} ${response.statusText}`); return null; } const data: ItunesResponse = await response.json(); if (data.resultCount === 0) { return null; } // Filter for exact(ish) matches to avoid wrong songs // and find the earliest release date let earliestYear: number | null = null; const normalizedTitle = title.toLowerCase().replace(/[^\w\s]/g, ''); const normalizedArtist = artist.toLowerCase().replace(/[^\w\s]/g, ''); for (const result of data.results) { // Basic validation that it's the right song const resTitle = result.trackName.toLowerCase().replace(/[^\w\s]/g, ''); const resArtist = result.artistName.toLowerCase().replace(/[^\w\s]/g, ''); // Check if title and artist are contained in the result (fuzzy match) if (resTitle.includes(normalizedTitle) && resArtist.includes(normalizedArtist)) { if (result.releaseDate) { const year = new Date(result.releaseDate).getFullYear(); if (!isNaN(year)) { if (earliestYear === null || year < earliestYear) { earliestYear = year; } } } } } return earliestYear; } catch (error) { console.error(`Error fetching release year from iTunes for "${title}" by "${artist}":`, error); return null; } }