From 2b5900c6a7579051b48867c429821b20c13710fa Mon Sep 17 00:00:00 2001 From: Kevin MacMartin Date: Sun, 3 Jan 2021 00:35:29 -0500 Subject: [PATCH] Allow for unlimited retries, add configuration to set a start and end time for checking, don't fail if a network error prevents a page from loading, and update the readme --- config.example.json | 4 ++- newegg-purchaser.js | 76 +++++++++++++++++++++++++++++---------------- readme.md | 6 ++-- 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/config.example.json b/config.example.json index beaecd0..ef705ca 100644 --- a/config.example.json +++ b/config.example.json @@ -3,8 +3,10 @@ "password":"", "cv2":"", "item_page":"", - "refresh_time":"60", + "refresh_time":"55", "refresh_tries": "60", + "start_time": "7:00", + "end_time": "20:00", "price_limit":"925", "auto_submit":"true" } diff --git a/newegg-purchaser.js b/newegg-purchaser.js index a7fe1a0..f4fc25a 100755 --- a/newegg-purchaser.js +++ b/newegg-purchaser.js @@ -26,16 +26,30 @@ async function run() { }); const page = await browser.newPage(), - maxVariance = 8; + maxVariance = 8, + startTime = Number(config.start_time.replace(/:.*/, "")) + Number(config.start_time.replace(/^[^:]*:/, "")) / 60, + endTime = Number(config.end_time.replace(/:.*/, "")) + Number(config.end_time.replace(/^[^:]*:/, "")) / 60; let success = true, randomVariance = 0, - currentTry = 1; + currentTry = 1, + date, + timeNow; + + async function navigateToPage(url) { + try { + await page.goto(url, { waitUntil: "load" }); + } catch (err) { + log(`Failed to navigate to ${url}, retrying in 30 seconds...`); + await page.waitForTimeout(30000); + await navigateToPage(url); + } + } log("Started bot"); while (true) { - await page.goto("https://secure.newegg.ca/NewMyAccount/AccountLogin.aspx?nextpage=https%3a%2f%2fwww.newegg.ca%2f", { waitUntil: "load" }); + await navigateToPage("https://secure.newegg.ca/NewMyAccount/AccountLogin.aspx?nextpage=https%3a%2f%2fwww.newegg.ca%2f"); if (page.url().includes("signin")) { try { @@ -78,35 +92,43 @@ async function run() { await page.waitForTimeout(3500); while (true) { - await page.goto(`https://www.newegg.ca/${config.item_page}`, { waitUntil: "load" }); + date = new Date(); + timeNow = date.getHours() + date.getMinutes() / 60; - if (await clickButtonWithText(page, "Add to cart")) { - log("Adding the product the to cart"); - await page.waitForSelector(".modal-content", { timeout: 5000 }); - await page.waitForTimeout(1000); + if (timeNow >= startTime && timeNow <= endTime) { + await navigateToPage(`https://www.newegg.ca/${config.item_page}`); - if (await clickButtonWithText(page, "No, thanks")) { - log("Rejected product coverage option"); - } + if (await clickButtonWithText(page, "Add to cart")) { + log("Adding the product the to cart"); + await page.waitForSelector(".modal-content", { timeout: 5000 }); + await page.waitForTimeout(1000); - try { - await page.waitForSelector(".message-title", { timeout: 5000 }); - log("Successfully added the item to the cart!"); - } catch (error) { - log("Fail: Added to cart but no success window appeared"); + if (await clickButtonWithText(page, "No, thanks")) { + log("Rejected product coverage option"); + } + + try { + await page.waitForSelector(".message-title", { timeout: 5000 }); + log("Successfully added the item to the cart!"); + } catch (error) { + log("Fail: Added to cart but no success window appeared"); + success = false; + } + + break; + } else if (config.refresh_tries !== 0 && currentTry > config.refresh_tries) { + log(`Fail: Maximum number of refresh tries reached (${config.refresh_tries})`); success = false; + break; + } else { + randomVariance = Math.floor(Math.random() * maxVariance); + log(`(${currentTry}) Product currently unavailable, retrying in ${Number(config.refresh_time) + randomVariance} seconds...`); + currentTry++; + await page.waitForTimeout((Number(config.refresh_time) + randomVariance) * 1000); } - - break; - } else if (currentTry > config.refresh_tries) { - log(`Fail: Maximum number of refresh tries reached (${config.refresh_tries})`); - success = false; - break; } else { - randomVariance = Math.floor(Math.random() * maxVariance); - log(`(${currentTry}) Product currently unavailable, retrying in ${Number(config.refresh_time) + randomVariance} seconds...`); - currentTry++; - await page.waitForTimeout((Number(config.refresh_time) + randomVariance) * 1000); + log(`${date.getHours()}:${date.getMinutes()} is outside the active time period between ${config.start_time} and ${config.end_time}`); + await page.waitForTimeout(60000); } } } @@ -114,7 +136,7 @@ async function run() { if (success) { while (true) { log("Navigating to secure checkout"); - await page.goto("https://secure.newegg.ca/shop/cart", { waitUntil: "load" }); + await navigateToPage("https://secure.newegg.ca/shop/cart"); const totalPriceElement = await page.$(".summary-content-total span strong"), totalPrice = await page.evaluate(totalPriceElement => totalPriceElement.textContent, totalPriceElement); diff --git a/readme.md b/readme.md index 4e98f3b..2ad5e6e 100644 --- a/readme.md +++ b/readme.md @@ -15,10 +15,12 @@ PUPPETEER_PRODUCT=firefox npm install puppeteer * `cv2`: code on the back of your credit card * `item_page`: the part of the URL (starting with a slash) for the product after `https://www.newegg.ca` (eg: `/amd-ryzen-9-5900x/p/N82E16819113664`) * `refresh_time`: amount of time between page refreshes (with a random variance) - * `refresh_tries`: the number of times the script will check before quitting (to avoid getting banned) + * `refresh_tries`: the number of times the script will check before quitting (set to 0 for unlimited) + * `start_time`: a 24 hour time in the format `7:00` that determines when the script will start checking for the day + * `end_time`: a 24 hour time in the format `20:00` that determines when the script will stop checking for the day * `auto_submit`: set this to false if you want to do a test run (everything up to the actual purchase) * `price_limit`: set this to a number you don't want your cart total to exceed before checking out ## Credits -Inspired by https://github.com/Ataraksia/NeweggBot +Inspired by and some code borrowed from: https://github.com/Ataraksia/NeweggBot