Price Report
All checks were successful
Deploy to Server / deploy (push) Successful in 31s

This commit is contained in:
2025-10-25 18:56:45 -04:00
parent 2a60504cea
commit cd3206da1b
5 changed files with 256 additions and 2 deletions

38
src/services/ebay.ts Normal file
View File

@@ -0,0 +1,38 @@
import * as cheerio from 'cheerio';
export async function fetchMedianSoldPriceUSDForSku(sku: string): Promise<number | null> {
const query = encodeURIComponent(`"${sku}"`);
const url = `https://www.ebay.com/sch/i.html?_nkw=${query}&LH_Sold=1&LH_Complete=1&rt=nc`;
const res = await fetch(url, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
} as any
} as any);
if (!res.ok) return null;
const html = await res.text();
const $ = cheerio.load(html);
const prices: number[] = [];
$('li.s-item').each((_i, el) => {
const priceText = $(el).find('.s-item__price').first().text().trim();
if (!priceText) return;
// Accept only USD (has $)
if (!priceText.includes('$')) return;
// Remove ranges like "$10.00 to $20.00"
const single = priceText.split(' to ')[0];
const num = single.replace(/[^0-9.]/g, '');
if (!num) return;
const value = Number(num);
if (!Number.isFinite(value) || value <= 0) return;
prices.push(value);
});
if (prices.length === 0) return null;
prices.sort((a, b) => a - b);
const mid = Math.floor(prices.length / 2);
if (prices.length % 2 === 0) {
return Number(((prices[mid - 1] + prices[mid]) / 2).toFixed(2));
} else {
return Number(prices[mid].toFixed(2));
}
}