import fetch from 'node-fetch'; import { playAudioFile } from 'audic'; import open from 'open'; import puppeteer from 'puppeteer-extra'; import StealthPlugin from 'puppeteer-extra-plugin-stealth'; import AnonymizeUAPlugin from 'puppeteer-extra-plugin-anonymize-ua'; import AdblockerPlugin from 'puppeteer-extra-plugin-adblocker'; import fs from 'fs'; const url = 'https://www.bestbuy.com/gateway/graphql'; const browser_path = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'; puppeteer.use(StealthPlugin()); puppeteer.use(AnonymizeUAPlugin()); puppeteer.use( AdblockerPlugin({ blockTrackers: true, } )); const headers = { 'Host': 'www.bestbuy.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0', 'Accept': 'application/json', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Referer': 'https://www.bestbuy.com/site/nvidia-geforce-rtx-5090-32gb-gddr7-graphics-card-dark-gun-metal/6614151.p?skuId=6614151', 'X-REQUEST-ID': 'add-on-selector', 'X-CLIENT-ID': 'ATTACH-accessories-in-variations', 'Content-Type': 'application/json', 'mode': 'cors', 'Origin': 'https://www.bestbuy.com', 'Connection': 'keep-alive', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'Priority': 'u=4', 'TE': 'trailers' }; const skuIds = ["6614151","6616096","6617487","6614119","6614120","6616095","6616092","6616096","6614122","6616093","6616090","6616091","6615930","6615929","6615931"] const queries = skuIds.map(skuId => ({ skuId, query: ` query AOS_fetchButtonStateData($zip: String!, $store: String!) { productBySkuId(skuId: "${skuId}") { fulfillmentOptions( input: { buttonState: {context: PDP, destinationZipCode: $zip, storeId: $store}, shipping: {destinationZipCode: $zip}, inStorePickup: {storeId: $store} } ) { buttonStates { buttonState planButtonState displayText skuId } } } } ` })); //CHANGE YOUR STORES HERE const params = [ { zip: "97504", store: "2517" }, ]; let lines = 0; let found = false; let winningResult = null; function getProductUrl(skuId) { return `https://www.bestbuy.com/site/${skuId}.p?skuId=${skuId}`; } async function addToCart(productUrl) { const browser = await puppeteer.launch({ headless: false, defaultViewport: null, ignoreDefaultArgs: ["--disable-extensions"], dumpio: true, args: ["--start-maximized", "--no-sandbox", "--disable-setuid-sandbox"], executablePath: browser_path, }); const page = await browser.newPage(); // Load cookies try{ const cookies = JSON.parse(fs.readFileSync('./cookies.json', 'utf8')); await page.setCookie(...cookies); }catch (error){ console.error('An error occurred:',error) } // Load local storage data try{ const localStorageData = JSON.parse(fs.readFileSync('./localStorage.json', 'utf8')); await page.evaluateOnNewDocument((data) => { for (const key in data) { localStorage.setItem(key, data[key]); } }, localStorageData); }catch (error){ console.error('An error occurred:',error) } await page.goto(productUrl); // Wait for the "Add to Cart" button to be available and click it try{ await page.waitForSelector('.add-to-cart-button',{ timeout: 300000 }); await page.click('.add-to-cart-button'); console.log('Item added to cart'); await page.waitForSelector('button.btn-primary[data-track="Checkout - Top"]',{ timeout: 300000 }); await page.click('button.btn-primary[data-track="Checkout - Top"]'); console.log('Checkout button clicked'); }catch (error){ console.error('An error occurred:',error) } } async function fetchGraphQL(zip, store, query) { const body = { query, variables: { zip, store }, operationName: "AOS_fetchButtonStateData" }; try { const response = await fetch(url, { method: 'POST', headers, body: JSON.stringify(body) }); if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } return await response.json(); } catch (err) { console.error(`Error fetching for zip ${zip}, store ${store} query ${query}:`, err); return null; } } async function pollStore(zip, store) { console.log(`Starting poll for zip ${zip} and store ${store}...`); while (!found) { for (const { skuId, query } of queries) { const data = await fetchGraphQL(zip, store, query); if ( data && data.data && data.data.productBySkuId && data.data.productBySkuId.fulfillmentOptions && data.data.productBySkuId.fulfillmentOptions.buttonStates && data.data.productBySkuId.fulfillmentOptions.buttonStates.length > 0 ) { const buttonState = data.data.productBySkuId.fulfillmentOptions.buttonStates[0].buttonState; console.log(`skuId: ${skuId} Store: ${store} Ship to: ${zip} -> buttonState: ${buttonState}`); if (buttonState !== "SOLD_OUT") { found = true; const productUrl = getProductUrl(skuId) console.log(productUrl) winningResult = { skuId, zip, store, buttonState, data }; const openPromise = open(productUrl); const addToCartPromise = addToCart(productUrl); await open('./alarm.wav'); await addToCartPromise return winningResult; } } else { console.log(`Incomplete data for zip ${zip}, store ${store}.`); } lines++ if(lines > 30) { lines = 0; process.stdout.write('\x1B[3J\x1B[2J\x1B[H'); } await new Promise(resolve => setTimeout(resolve, 500)); } } return null; } async function runAllPollers() { const pollers = params.map(({ zip, store }) => pollStore(zip, store)); const result = await Promise.race(pollers); console.log("Found a store with available button state:"); console.log(JSON.stringify(result, null, 2)); } runAllPollers();