#!/usr/bin/env node const puppeteer = require("puppeteer"), config = require("./config.json"); function log(message) { console.log(`${new Date().toString().replace(/ GMT.*/, "")}: ${message}`); } async function clickButtonWithText(page, text) { const [ button ] = await page.$x(`//button[contains(., '${text}')]`); if (typeof button !== "undefined") { try { await button.click(); return true; } catch (err) { return false; } } else { return false; } } async function run() { const browser = await puppeteer.launch({ headless: false, product: "firefox", defaultViewport: { width: 1440, height: 724 } }); const page = await browser.newPage(), maxVariance = 8, refreshTries = Number(config.refresh_tries), 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, 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 navigateToPage("https://secure.newegg.ca/NewMyAccount/AccountLogin.aspx?nextpage=https%3a%2f%2fwww.newegg.ca%2f"); if (page.url().includes("signin")) { try { await page.waitForSelector("button.btn.btn-orange", { timeout: 5000 }); await page.type("#labeled-input-signEmail", config.username); await page.click("button.btn.btn-orange"); await page.waitForTimeout(1500); while (true) { try { await page.waitForSelector("#labeled-input-password", { timeout: 5000 }); await page.waitForSelector("button.btn.btn-orange"); await page.type("#labeled-input-password", config.password); await page.click("button.btn.btn-orange"); log("Successfully logged in"); break; } catch (err) { try { await page.waitForSelector(".nav-complex-inner .fa-caret-down", { timeout: 5000 }); log("Successfully logged in"); break; } catch (err) { log("Waiting for authorization"); await page.waitForTimeout(5000); } } } } catch (err) { log("Fail: Login form missing"); success = false; } break; } else { await page.waitForTimeout(1000); } } if (success) { await page.waitForTimeout(3500); while (true) { date = new Date(); timeNow = date.getHours() + date.getMinutes() / 60; if (timeNow >= startTime && timeNow <= endTime) { await navigateToPage(`https://www.newegg.ca/${config.item_page}`); 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 (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 (refreshTries !== 0 && currentTry > refreshTries) { log(`Fail: Maximum number of refresh tries reached (${refreshTries})`); 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); } } else { log(`${date.getHours()}:${date.getMinutes()} is outside the active time period between ${config.start_time} and ${config.end_time}`); await page.waitForTimeout(30000); } } } if (success) { while (true) { log("Navigating to secure checkout"); 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); if (typeof totalPrice === "undefined" || totalPrice === "" || totalPrice === null) { log("Fail: Unable to determine total price"); break; } if (Number(totalPrice) > config.price_limit) { log(`Fail: Total price of "${totalPrice}" exceeds price limit`); break; } if (await clickButtonWithText(page, "Secure Checkout")) { await page.waitForTimeout(3000); if (await clickButtonWithText(page, "Continue to payment")) { log("Continuing to payment..."); await page.waitForSelector("[placeholder=\"CVV2\"]", { timeout: 5000 }); await page.waitForTimeout(1000); log("Filling out the cv2..."); await page.type("[placeholder=\"CVV2\"]", config.cv2); if (await clickButtonWithText(page, "Review your order")) { log("Reviewing order..."); if (config.auto_submit === "true") { if (await clickButtonWithText(page, "Place Order")) { log("Order placed!!!"); } else { log("Fail: Unable to press the Place Order button"); } } else { log("The auto_submit config value is set to false"); } } else { log("Fail: Unable to click the 'Review your order' button"); } break; } else { await page.waitForTimeout(1000); } } else { await page.waitForTimeout(1000); } } } if (!success) { // await browser.close(); } } run();