jefflix-website/app/api/radio/search/route.ts

93 lines
2.3 KiB
TypeScript

import { NextResponse } from 'next/server'
const RADIO_GARDEN_API = 'https://radio.garden/api'
const HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'application/json',
'Referer': 'https://radio.garden/',
}
interface RGSearchHit {
_source: {
code: string
type: 'channel' | 'place' | 'country'
page: {
url: string
title: string
place?: { id: string; title: string }
country?: { id: string; title: string }
subtitle?: string
}
}
_score: number
}
interface RGSearchResponse {
hits: { hits: RGSearchHit[] }
}
function extractId(url: string): string {
const parts = url.split('/')
return parts[parts.length - 1]
}
export interface SearchStation {
id: string
title: string
placeId: string
placeTitle: string
country: string
}
export interface SearchPlace {
id: string
title: string
country: string
}
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const q = searchParams.get('q')
if (!q || q.length < 2) {
return NextResponse.json({ stations: [], places: [] })
}
try {
const res = await fetch(`${RADIO_GARDEN_API}/search?q=${encodeURIComponent(q)}`, {
headers: HEADERS,
signal: AbortSignal.timeout(10000),
})
if (!res.ok) throw new Error(`Radio Garden search returned ${res.status}`)
const json: RGSearchResponse = await res.json()
const stations: SearchStation[] = []
const places: SearchPlace[] = []
for (const hit of json.hits.hits) {
const src = hit._source
if (src.type === 'channel') {
stations.push({
id: extractId(src.page.url),
title: src.page.title,
placeId: src.page.place?.id || '',
placeTitle: src.page.place?.title || '',
country: src.page.country?.title || src.code,
})
} else if (src.type === 'place') {
places.push({
id: extractId(src.page.url),
title: src.page.title,
country: src.page.country?.title || src.code,
})
}
}
return NextResponse.json({ stations, places })
} catch (error) {
console.error('Radio search error:', error)
return NextResponse.json({ error: 'Search failed' }, { status: 502 })
}
}