← back to Watches
src/utils/dealers/dealer-apis.js
194 lines
/**
* Watch Dealer API Integrations
* Scraping and API tools for OMEGA price data
*/
export const dealerAPIs = {
// Open / Scrape-Friendly Dealers
chrono24: {
name: 'Chrono24',
hasOmega: true,
apiType: 'Private (scrappable)',
baseUrl: 'https://www.chrono24.com',
searchUrl: 'https://www.chrono24.com/search/index.htm',
jsonEndpoint: 'https://www.chrono24.com/search/browse.json',
notes: 'JSON feed easy to scrape, best historical data',
scrapeMethod: 'json',
exampleQuery: '?query=omega+speedmaster&models=126',
selectors: {
price: '.price',
title: '.article-item-title',
image: '.article-image img',
link: '.article-item-container a',
}
},
watchCharts: {
name: 'WatchCharts',
hasOmega: true,
apiType: 'Paid API',
baseUrl: 'https://watchcharts.com',
apiUrl: 'https://api.watchcharts.com/v1',
notes: 'Best historical charts, subscription required',
pricing: '$50-200/month',
features: ['Historical pricing', 'Market index', 'Trends'],
exampleModels: {
speedmaster: 'omega-speedmaster-moonwatch-professional-311-30-42-30-01-005',
seamaster: 'omega-seamaster-diver-300m-210-30-42-20-01-001'
}
},
ebayWatches: {
name: 'eBay Watches',
hasOmega: true,
apiType: 'Official API',
baseUrl: 'https://www.ebay.com/b/Omega-Wristwatches/31387/bn_628363',
apiUrl: 'https://api.ebay.com/buy/browse/v1/item_summary/search',
authRequired: true,
notes: 'Sold/completed listings excellent for real pricing',
documentation: 'https://developer.ebay.com/api-docs/buy/browse/overview.html',
queryParams: {
q: 'omega speedmaster',
filter: 'buyingOptions:{FIXED_PRICE},itemLocationCountry:US',
sort: 'price'
}
},
jomashop: {
name: 'Jomashop',
hasOmega: true,
apiType: 'Unofficial (scrappable)',
baseUrl: 'https://www.jomashop.com',
searchUrl: 'https://www.jomashop.com/omega-watches.html',
notes: 'HTML structured, easy to scrape, great prices',
scrapeMethod: 'html',
selectors: {
price: '.price-box .price',
title: '.product-name a',
image: '.product-image img',
sku: '.sku'
}
},
watchCompanyTokyo: {
name: 'The Watch Company (Tokyo)',
hasOmega: true,
apiType: 'JSON endpoints',
baseUrl: 'https://www.thewatchcompany.com',
productApi: 'https://www.thewatchcompany.com/api/products',
notes: 'Excellent for Japan arbitrage, tax-free export',
currency: 'JPY',
features: ['Tax-free export', 'Condition grading', 'Photos'],
exampleEndpoint: '/api/products?brand=omega&model=speedmaster'
},
jackroadTokyo: {
name: 'Jackroad & Betty (Tokyo)',
hasOmega: true,
apiType: 'JSON endpoints',
baseUrl: 'https://www.jackroad.co.jp',
notes: 'Strong Speedmaster selection, scrape-friendly',
currency: 'JPY',
searchUrl: 'https://www.jackroad.co.jp/shop/c/c10omega/',
features: ['Detailed condition reports', 'Box/papers info']
},
komehyoJapan: {
name: 'Komehyo Japan',
hasOmega: true,
apiType: 'Scrappable',
baseUrl: 'https://komehyo.jp',
notes: 'Retail + outlet pricing, very popular',
currency: 'JPY',
features: ['Outlet section', 'Strict grading', 'Photos']
},
watchBox: {
name: 'WatchBox',
hasOmega: true,
apiType: 'Private API (query by ref)',
baseUrl: 'https://www.thewatchbox.com',
apiUrl: 'https://api.thewatchbox.com',
notes: 'Premium inventory, can query by reference number',
features: ['Buy quotes', 'Trade-in', 'Authentication']
},
luxuryBazaar: {
name: 'Luxury Bazaar',
hasOmega: true,
apiType: 'Scrappable',
baseUrl: 'https://www.luxurybazaar.com',
searchUrl: 'https://www.luxurybazaar.com/watches/omega/',
notes: 'Bulk buying available, custom affiliate deals',
features: ['Bulk purchases', 'Custom commissions']
}
};
/**
* Scraper for Chrono24 listings
*/
export async function scrapeChrono24(query = 'omega speedmaster') {
const url = `https://www.chrono24.com/search/index.htm?query=${encodeURIComponent(query)}`;
try {
// This would use Playwright/Puppeteer
const response = await fetch(url);
const html = await response.text();
// Parse HTML for listings
// Return structured data
return {
source: 'Chrono24',
url,
listings: [], // Parsed data
timestamp: new Date().toISOString()
};
} catch (error) {
console.error('Chrono24 scrape failed:', error);
return null;
}
}
/**
* Get Japan dealer prices (for arbitrage)
*/
export async function getJapanPrices(model = 'speedmaster') {
const dealers = [
dealerAPIs.watchCompanyTokyo,
dealerAPIs.jackroadTokyo,
dealerAPIs.komehyoJapan
];
const results = await Promise.allSettled(
dealers.map(dealer => fetch(`${dealer.baseUrl}/api/products?q=${model}`))
);
return results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
}
/**
* Get current market price from multiple sources
*/
export async function getMarketPrice(reference) {
// Aggregate from:
// 1. Chrono24 average
// 2. eBay sold listings
// 3. WatchBox current
// 4. Jomashop retail
const sources = [];
// TODO: Implement parallel scraping
return {
reference,
averagePrice: 0,
sources,
timestamp: new Date().toISOString()
};
}
export default dealerAPIs;