// functions/artist/[id].js class ServerAPI { constructor() { this.INSTANCES_URLS = [ 'https://tidal-uptime.jiffy-puffs-1j.workers.dev/', 'https://tidal-uptime.props-76styles.workers.dev/', ]; this.apiInstances = null; } async getInstances() { if (this.apiInstances) return this.apiInstances; let data = null; const urls = [...this.INSTANCES_URLS].sort(() => Math.random() - 0.5); for (const url of urls) { try { const response = await fetch(url); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); data = await response.json(); break; } catch (error) { console.warn(`Failed to fetch from ${url}:`, error); } } if (data) { this.apiInstances = (data.api || []) .map((item) => item.url || item) .filter((url) => !url.includes('spotisaver.net')); return this.apiInstances; } console.error('Failed to load instances from all uptime APIs'); return [ 'https://eu-central.monochrome.tf', 'https://us-west.monochrome.tf', 'https://arran.monochrome.tf', 'https://triton.squid.wtf', 'https://api.monochrome.tf', 'https://monochrome-api.samidy.com', 'https://maus.qqdl.site', 'https://vogel.qqdl.site', 'https://katze.qqdl.site', 'https://hund.qqdl.site', 'https://tidal.kinoplus.online', 'https://wolf.qqdl.site', ]; } async fetchWithRetry(relativePath) { const instances = await this.getInstances(); if (instances.length === 0) { throw new Error('No API instances configured.'); } let lastError = null; for (const baseUrl of instances) { const url = baseUrl.endsWith('/') ? `${baseUrl}${relativePath.substring(1)}` : `${baseUrl}${relativePath}`; try { const response = await fetch(url); if (response.ok) { return response; } lastError = new Error(`Request failed with status ${response.status}`); } catch (error) { lastError = error; } } throw lastError || new Error(`All API instances failed for: ${relativePath}`); } async getArtistMetadata(id) { try { const response = await this.fetchWithRetry(`/artist/${id}`); return await response.json(); } catch { const response = await this.fetchWithRetry(`/artist?id=${id}`); return await response.json(); } } getArtistPictureUrl(id, size = '750') { if (!id) return ''; const formattedId = id.replace(/-/g, '/'); return `https://resources.tidal.com/images/${formattedId}/${size}x${size}.jpg`; } } export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot/i.test( userAgent ); const artistId = params.id; if (isBot && artistId) { try { const api = new ServerAPI(); const data = await api.getArtistMetadata(artistId); const artist = data.artist || data.data || data; if (artist && (artist.name || artist.title)) { const name = artist.name || artist.title; const description = `Listen to ${name} on Monochrome`; const imageUrl = artist.picture ? api.getArtistPictureUrl(artist.picture, '750') : 'https://monochrome.samidy.com/assets/appicon.png'; const pageUrl = new URL(request.url).href; const metaHtml = ` ${name}

${name}

Artist Picture `; return new Response(metaHtml, { headers: { 'content-type': 'text/html;charset=UTF-8' } }); } } catch (error) { console.error(`Error for artist ${artistId}:`, error); } } const url = new URL(request.url); url.pathname = '/'; return env.ASSETS.fetch(new Request(url, request)); }