163 lines
4.8 KiB
TypeScript
163 lines
4.8 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
|
|
/**
|
|
* eBay API Proxy Route
|
|
* Proxies requests to eBay Finding API to avoid CORS issues
|
|
*/
|
|
|
|
interface eBaySearchParams {
|
|
keywords: string
|
|
categoryId?: string
|
|
sortOrder?: string
|
|
maxResults?: number
|
|
}
|
|
|
|
interface eBaySearchResult {
|
|
itemId: string
|
|
title: string
|
|
price: string
|
|
currency: string
|
|
imageUrl?: string
|
|
viewItemUrl: string
|
|
condition?: string
|
|
shippingCost?: string
|
|
affiliateLink: string
|
|
}
|
|
|
|
type MaybeArray<T> = T | T[]
|
|
|
|
// Affiliate campaign ID for generating links
|
|
const AFFILIATE_CAMPAIGN_ID = process.env.EBAY_AFFILIATE_CAMPAIGN_ID?.trim() || ''
|
|
|
|
// Generate eBay affiliate link
|
|
function generateAffiliateLink(viewItemUrl: string): string {
|
|
if (!AFFILIATE_CAMPAIGN_ID) {
|
|
return viewItemUrl
|
|
}
|
|
|
|
try {
|
|
const url = new URL(viewItemUrl)
|
|
url.searchParams.set('mkcid', '1')
|
|
url.searchParams.set('mkrid', '711-53200-19255-0')
|
|
url.searchParams.set('siteid', '0')
|
|
url.searchParams.set('campid', AFFILIATE_CAMPAIGN_ID)
|
|
url.searchParams.set('toolid', '10001')
|
|
url.searchParams.set('mkevt', '1')
|
|
return url.toString()
|
|
} catch {
|
|
return viewItemUrl
|
|
}
|
|
}
|
|
|
|
function first<T>(value: MaybeArray<T> | undefined): T | undefined {
|
|
if (!value) {
|
|
return undefined
|
|
}
|
|
|
|
return Array.isArray(value) ? value[0] : value
|
|
}
|
|
|
|
function normalizeItem(item: any): eBaySearchResult {
|
|
const currentPrice = first(item.sellingStatus?.currentPrice)
|
|
const shippingCost = first(item.shippingInfo?.shippingServiceCost)
|
|
const condition = first(item.condition)
|
|
const viewItemUrl = item.viewItemURL || item.viewItemUrl || ''
|
|
|
|
return {
|
|
itemId: item.itemId || '',
|
|
title: item.title || 'Unknown Item',
|
|
price: `${currentPrice?.value || '0'} ${currentPrice?.currencyId || 'USD'}`,
|
|
currency: currentPrice?.currencyId || 'USD',
|
|
imageUrl: first(item.galleryURL) || undefined,
|
|
viewItemUrl,
|
|
condition: condition?.conditionDisplayName || undefined,
|
|
shippingCost: shippingCost?.value
|
|
? `${shippingCost.value} ${shippingCost.currencyId || currentPrice?.currencyId || 'USD'}`
|
|
: undefined,
|
|
affiliateLink: generateAffiliateLink(viewItemUrl),
|
|
}
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const { searchParams } = new URL(request.url)
|
|
|
|
const keywords = searchParams.get('keywords')
|
|
const categoryId = searchParams.get('categoryId') || undefined
|
|
const sortOrder = searchParams.get('sortOrder') || 'BestMatch'
|
|
const maxResults = parseInt(searchParams.get('maxResults') || '6', 10)
|
|
|
|
if (!keywords) {
|
|
return NextResponse.json({ error: 'Keywords parameter is required' }, { status: 400 })
|
|
}
|
|
|
|
const appId = process.env.EBAY_APP_ID?.trim()
|
|
|
|
if (!appId) {
|
|
console.error('EBAY_APP_ID not configured')
|
|
return NextResponse.json(
|
|
{ error: 'eBay API not configured. Please set EBAY_APP_ID environment variable.' },
|
|
{ status: 503 }
|
|
)
|
|
}
|
|
|
|
// Build eBay Finding API URL
|
|
const baseUrl = 'https://svcs.ebay.com/services/search/FindingService/v1'
|
|
const url = new URL(baseUrl)
|
|
|
|
url.searchParams.set('OPERATION-NAME', 'findItemsAdvanced')
|
|
url.searchParams.set('SERVICE-VERSION', '1.0.0')
|
|
url.searchParams.set('SECURITY-APPNAME', appId)
|
|
url.searchParams.set('RESPONSE-DATA-FORMAT', 'JSON')
|
|
url.searchParams.set('REST-PAYLOAD', 'true')
|
|
url.searchParams.set('keywords', keywords)
|
|
url.searchParams.set('sortOrder', sortOrder)
|
|
url.searchParams.set('paginationInput.entriesPerPage', maxResults.toString())
|
|
|
|
if (categoryId) {
|
|
url.searchParams.set('categoryId', categoryId)
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(url.toString(), {
|
|
method: 'GET',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
},
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const errorText = await response.text()
|
|
console.error('eBay API error:', response.status, errorText)
|
|
return NextResponse.json(
|
|
{ error: `eBay API error: ${response.status}` },
|
|
{ status: response.status }
|
|
)
|
|
}
|
|
|
|
const data = await response.json()
|
|
|
|
// Parse eBay API response
|
|
const findItemsAdvancedResponse = data.findItemsAdvancedResponse?.[0]
|
|
if (!findItemsAdvancedResponse) {
|
|
return NextResponse.json([])
|
|
}
|
|
|
|
const searchResult = findItemsAdvancedResponse.searchResult?.[0]
|
|
if (!searchResult || !searchResult.item || searchResult.item.length === 0) {
|
|
return NextResponse.json([])
|
|
}
|
|
|
|
const items = Array.isArray(searchResult.item) ? searchResult.item : [searchResult.item]
|
|
|
|
const results: eBaySearchResult[] = items.map((item: any) => normalizeItem(item))
|
|
|
|
return NextResponse.json(results)
|
|
|
|
} catch (error) {
|
|
console.error('Error fetching from eBay API:', error)
|
|
return NextResponse.json(
|
|
{ error: 'Failed to fetch products from eBay' },
|
|
{ status: 500 }
|
|
)
|
|
}
|
|
}
|