← back to Govarbitrage

src/lib/marketplace-links.ts

139 lines

// Build deep-search links to (a) other auction/resale marketplaces and (b)
// social "goods-needed"/flipping boards, from a listing's identifying terms.
// All $0, no API keys — each link opens the network's live results for the item.

export interface LinkChip {
  label: string;
  url: string;
  group: "auction" | "resale" | "retail" | "board";
}

interface Named {
  title: string;
  manufacturer?: string | null;
  model?: string | null;
  category?: string | null;
}

/** Best short search query for an item: prefer brand+model, strip lot/qty noise. */
export function searchQuery(l: Named): string {
  const generic = /^(assorted|mixed|various|lot|n\/a|unknown|misc)/i;
  const parts: string[] = [];
  if (l.manufacturer && !generic.test(l.manufacturer)) parts.push(l.manufacturer);
  if (l.model && !generic.test(l.model)) parts.push(l.model);
  let q = parts.join(" ").trim();
  if (!q) q = l.title;
  // Strip lot/quantity noise: "(4 EA)", "Lot of 12", "1 LOT", trailing counts.
  q = q
    .replace(/\([^)]*\)/g, " ")
    .replace(/\b(lot of|qty|quantity)\b\s*\d*/gi, " ")
    .replace(/\b\d+\s*(ea|each|lot|pcs?|units?)\b/gi, " ")
    .replace(/\bDEMIL\b/gi, " ")
    .replace(/[^\w\s.\-/]/g, " ")
    .replace(/\s+/g, " ")
    .trim();
  return q.split(/\s+/).slice(0, 7).join(" ");
}

const enc = (s: string) => encodeURIComponent(s);

/** Actual offers/comps on other auction + resale + retail networks. */
export function auctionNetworkLinks(l: Named): LinkChip[] {
  const q = searchQuery(l);
  const e = enc(q);
  const links: LinkChip[] = [
    { label: "eBay Sold", url: `https://www.ebay.com/sch/i.html?_nkw=${e}&LH_Sold=1&LH_Complete=1`, group: "resale" },
    { label: "eBay Active", url: `https://www.ebay.com/sch/i.html?_nkw=${e}`, group: "resale" },
    { label: "GovDeals", url: `https://www.govdeals.com/search?kWord=${e}`, group: "auction" },
    { label: "AllSurplus", url: `https://www.allsurplus.com/search?query=${e}`, group: "auction" },
    { label: "Public Surplus", url: `https://www.publicsurplus.com/sms/browse/search?keyword=${e}`, group: "auction" },
    { label: "Municibid", url: `https://municibid.com/Browse?search=${e}`, group: "auction" },
    { label: "Google Shopping", url: `https://www.google.com/search?tbm=shop&q=${e}`, group: "retail" },
  ];
  // Category-specialist venues.
  const cat = `${l.category ?? ""} ${l.title}`.toLowerCase();
  if (/forklift|generator|welder|lathe|cnc|scissor|mower|tractor|compressor|industrial|machin/.test(cat)) {
    links.push({ label: "MachineryTrader", url: `https://www.machinerytrader.com/listings/search?keywords=${e}`, group: "resale" });
  }
  if (/lab|microscope|centrifuge|analyzer|hplc|spectro|scientific/.test(cat)) {
    links.push({ label: "LabX", url: `https://www.labx.com/search?q=${e}`, group: "resale" });
  }
  if (/medical|dental|patient|exam|surgical|hospital|stretcher|vital/.test(cat)) {
    links.push({ label: "DOTmed", url: `https://www.dotmed.com/equipment/search?q=${e}`, group: "resale" });
  }
  return links;
}

export interface RegionLinks {
  region: string;
  links: LinkChip[];
}

/** International resale + auction venues to check an item's price abroad. */
export function internationalNetworkLinks(l: Named): RegionLinks[] {
  const e = enc(searchQuery(l));
  return [
    {
      region: "Europe",
      links: [
        { label: "eBay UK", url: `https://www.ebay.co.uk/sch/i.html?_nkw=${e}`, group: "resale" },
        { label: "eBay Germany", url: `https://www.ebay.de/sch/i.html?_nkw=${e}`, group: "resale" },
        { label: "Catawiki", url: `https://www.catawiki.com/en/s?q=${e}`, group: "auction" },
        { label: "Troostwijk", url: `https://www.troostwijkauctions.com/en/l?searchQuery=${e}`, group: "auction" },
      ],
    },
    {
      region: "Japan",
      links: [
        { label: "Yahoo! Auctions JP", url: `https://auctions.yahoo.co.jp/search/search?p=${e}`, group: "resale" },
        { label: "Mercari JP", url: `https://jp.mercari.com/search?keyword=${e}`, group: "resale" },
      ],
    },
    {
      region: "Hong Kong",
      links: [{ label: "Carousell HK", url: `https://www.carousell.com.hk/search/${e}`, group: "resale" }],
    },
    {
      region: "Australia",
      links: [
        { label: "GraysOnline", url: `https://www.graysonline.com/search?keywords=${e}`, group: "auction" },
        { label: "Pickles", url: `https://www.pickles.com.au/search?q=${e}`, group: "auction" },
        { label: "eBay AU", url: `https://www.ebay.com.au/sch/i.html?_nkw=${e}`, group: "resale" },
      ],
    },
    {
      region: "China",
      links: [
        { label: "Taobao", url: `https://s.taobao.com/search?q=${e}`, group: "resale" },
        { label: "JD Auction", url: `https://auction.jd.com/searchList.html?keyword=${e}`, group: "auction" },
        { label: "Alibaba", url: `https://www.alibaba.com/trade/search?SearchText=${e}`, group: "retail" },
      ],
    },
  ];
}

/** Flat top-N international chips (for the compact dashboard column). */
export function internationalTopLinks(l: Named): LinkChip[] {
  const e = enc(searchQuery(l));
  return [
    { label: "eBay UK", url: `https://www.ebay.co.uk/sch/i.html?_nkw=${e}`, group: "resale" },
    { label: "Yahoo! JP", url: `https://auctions.yahoo.co.jp/search/search?p=${e}`, group: "resale" },
    { label: "Grays AU", url: `https://www.graysonline.com/search?keywords=${e}`, group: "auction" },
    { label: "Taobao CN", url: `https://s.taobao.com/search?q=${e}`, group: "resale" },
  ];
}

/** Social "goods-needed"/flipping/ISO boards + local marketplaces. */
export function boardLinks(l: Named): LinkChip[] {
  const q = searchQuery(l);
  const e = enc(q);
  return [
    { label: "Reddit", url: `https://www.reddit.com/search/?q=${e}`, group: "board" },
    { label: "r/Flipping", url: `https://www.reddit.com/r/Flipping/search/?q=${e}&restrict_sr=1`, group: "board" },
    { label: "Reddit ISO/Wanted", url: `https://www.reddit.com/search/?q=${enc(`${q} ISO OR wanted OR "looking for"`)}`, group: "board" },
    { label: "Facebook Marketplace", url: `https://www.facebook.com/marketplace/search/?query=${e}`, group: "board" },
    { label: "Craigslist", url: `https://www.craigslist.org/search/sss?query=${e}`, group: "board" },
    { label: "Discord (Disboard)", url: `https://disboard.org/search?keyword=${e}`, group: "board" },
  ];
}