Skip to content

Commit

Permalink
Add ability to open product url automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
Prince25 committed Nov 23, 2020
1 parent 1cbbc43 commit 5698709
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 77 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Buy me a [pizza](buymeacoff.ee/PrinceSingh) if you'd like to see this project ex
<br><br>
> How does it work?
Enter the product URLs and set how often you want the program to check if those products are in stock. When an item becomes available, it will notify you through both text on console and three auditory beeps.
Enter the product URLs, set how often you want the program to check if those products are in stock, and if you want the product page to normal automatically in your default web browser when it gets in stock. When an item becomes available, it will notify you through both text on console and three auditory beeps.

> What stores/wesbites are supported?
Expand Down Expand Up @@ -48,4 +48,5 @@ Currently, the following stores are supported:
* Add color to console
* ~~Initially create seperation between intervals for Amazon items~~
* ~~Add a way to have independent delay timers for Amazon~~
* ~~Open product page when in stock~~
* ~~Fix~~ Find Bugs
153 changes: 85 additions & 68 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { fileURLToPath } from "url";
import antonline from './stores/antonline.js'
import amazon from './stores/amazon.js'
import bestbuy from './stores/bestbuy.js'
Expand All @@ -15,7 +16,7 @@ const URLS = [
"https://www.bestbuy.com/site/amd-ryzen-9-5900x-4th-gen-12-core-24-threads-unlocked-desktop-processor-without-cooler/6438942.p?skuId=6438942",
"https://www.bestbuy.com/site/sony-playstation-5-console/6426149.p?skuId=6426149",
"https://www.costco.com/sony-playstation-5-gaming-console-bundle.product.100691489.html",
"https://www.microcenter.com/product/630283/Ryzen_9_5900X_Vermeer_37GHz_12-Core_AM4_Boxed_Processor",
// "https://www.microcenter.com/product/630283/Ryzen_9_5900X_Vermeer_37GHz_12-Core_AM4_Boxed_Processor",
"https://www.newegg.com/amd-ryzen-9-5900x/p/N82E16819113664?Item=N82E16819113664",
"https://www.newegg.com/asus-geforce-rtx-3080-rog-strix-rtx3080-o10g-gaming/p/N82E16814126457",
"https://www.newegg.com/asus-geforce-rtx-3080-tuf-rtx3080-o10g-gaming/p/N82E16814126452",
Expand All @@ -29,10 +30,18 @@ const INTERVAL = {
value: 10
}

// Opens the product url in the default browser if set to true
export const OPEN_URL = true;

// Separates the check between Amazon items by this value
const AMAZON_DELAY = 25;


// Runs main only if this file is executed
if (process.argv[1] === fileURLToPath(import.meta.url))
main();


// https://www.XXX.com/... -> XXX
function getDomainName(url) {
let hostName = new URL(url).hostname;
Expand Down Expand Up @@ -65,18 +74,24 @@ async function checkStoreWithDelay(item) {
let timer = (firstRun) => {
return new Promise(
function(resolve) {
item.storeFunc(item.url, item.interval, INTERVAL.value, firstRun, resolve);
item.storeFunc(item.url, item.interval, INTERVAL.value, firstRun, item.urlOpened, resolve);
}
);
}

timer(item.firstRun).then(
async function(interval) {
async function({interval, urlOpened}) {
if (item.interval.value != interval) {
item.firstRun = true;
item.interval.value = interval;
} else item.firstRun = false;

if (OPEN_URL && urlOpened && urlOpened != item.urlOpened) {
item.urlOpened = true;
setTimeout(() => item.urlOpened = false, 1000 * 115) // Open URL every 2 minutes
}


switch(item.interval.unit) {
case 'seconds':
await setTimeout(checkStoreWithDelay, item.interval.value * 1000, item)
Expand All @@ -95,68 +110,70 @@ async function checkStoreWithDelay(item) {
}


let amazonItems = [];
function amazonItem(url) {
this.url = url;
this.interval = {...INTERVAL};
this.firstRun = true;
this.storeFunc = amazon;
};


URLS.forEach(url => {
let storeName;
try {
storeName = getDomainName(url);
} catch(e) {
console.error('Incorrect URL format:', url)
console.error(e)
}

switch(storeName) {
case 'antonline':
checkStore(antonline, url);
break;

case 'amazon':
amazonItems.push(new amazonItem(url));
break;

case 'bestbuy':
checkStore(bestbuy, url);
break;

case 'costco':
checkStore(costco, url);
break;

case 'microcenter':
checkStore(microcenter, url);
break;

case 'newegg':
checkStore(newegg, url);
break;

default:
console.error('This store is not supported:', storeName)
}
});

if (amazonItems.length > 0)
amazonItems.forEach(
(item, idx) => {
switch(INTERVAL.unit) {
case 'seconds':
setTimeout(checkStoreWithDelay, AMAZON_DELAY * 1000 * idx, item);
break;

case 'minutes':
setTimeout(checkStoreWithDelay, AMAZON_DELAY * 1000 * 60 * idx, item);
break;

case 'hours':
setTimeout(checkStoreWithDelay, AMAZON_DELAY * 1000 * 60 * 60 * idx, item);
break;
}
});
function main() {
let amazonItems = [];
function amazonItem(url) {
this.url = url;
this.interval = {...INTERVAL};
this.firstRun = true;
this.urlOpened = false;
this.storeFunc = amazon;
};

URLS.forEach(url => {
let storeName;
try {
storeName = getDomainName(url);
} catch(e) {
console.error('Incorrect URL format:', url)
console.error(e)
}

switch(storeName) {
case 'antonline':
checkStore(antonline, url);
break;

case 'amazon':
amazonItems.push(new amazonItem(url));
break;

case 'bestbuy':
checkStore(bestbuy, url);
break;

case 'costco':
checkStore(costco, url);
break;

case 'microcenter':
checkStore(microcenter, url);
break;

case 'newegg':
checkStore(newegg, url);
break;

default:
console.error('This store is not supported:', storeName)
}
});

if (amazonItems.length > 0)
amazonItems.forEach(
(item, idx) => {
switch(INTERVAL.unit) {
case 'seconds':
setTimeout(checkStoreWithDelay, AMAZON_DELAY * 1000 * idx, item);
break;

case 'minutes':
setTimeout(checkStoreWithDelay, AMAZON_DELAY * 1000 * 60 * idx, item);
break;

case 'hours':
setTimeout(checkStoreWithDelay, AMAZON_DELAY * 1000 * 60 * 60 * idx, item);
break;
}
});
}
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"axios": "^0.21.0",
"beepbeep": "^1.3.0",
"dom-parser": "^0.1.6",
"moment": "^2.29.1"
"moment": "^2.29.1",
"open": "^7.3.0"
}
}
11 changes: 7 additions & 4 deletions stores/amazon.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { fileURLToPath } from "url";
import { OPEN_URL } from '../main.js'
import fs from "fs";
import threeBeeps from "../beep.js"
import axios from "axios";
import moment from "moment";
import DomParser from "dom-parser"; // https://www.npmjs.com/package/dom-parser
import open from "open"


if (process.argv[1] === fileURLToPath(import.meta.url)) {
Expand All @@ -12,7 +14,7 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
value: 25 // Amazon detects bots if too low, do > 10 seconds
}
let url = 'https://www.amazon.com/Coredy-Super-Strong-Automatic-Self-Charging-Medium-Pile/dp/B07NPNN57S'
amazon(url, interval);
amazon(url, interval, interval.value, true, false, () => null);
}


Expand All @@ -24,7 +26,7 @@ function writeErrorToFile(error) {
}


export default async function amazon(url, interval, originalIntervalValue, firstRun, resolve) {
export default async function amazon(url, interval, originalIntervalValue, firstRun, urlOpened, resolve) {
try {
let res = await axios.get(url, {
headers: {
Expand All @@ -47,12 +49,13 @@ export default async function amazon(url, interval, originalIntervalValue, first
}
else if (inventory != null && inventory == 'Add to Cart') {
threeBeeps();
if (OPEN_URL && !urlOpened) { open(url); urlOpened = true; }
console.info(moment().format('LTS') + ': ***** In Stock at Amazon *****: ', title);
console.info(url);
}
resolve(interval.value);
resolve({interval: interval.value, urlOpened: urlOpened});
}
else resolve(Math.floor(interval.value + Math.random() * originalIntervalValue))
else resolve({interval: Math.floor(interval.value + Math.random() * originalIntervalValue), urlOpened: urlOpened})

} catch (e) {
writeErrorToFile(e)
Expand Down
8 changes: 6 additions & 2 deletions stores/antonline.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import { fileURLToPath } from "url";
import { OPEN_URL } from '../main.js'
import fs from "fs";
import threeBeeps from "../beep.js"
import axios from "axios";
import moment from "moment";
import DomParser from "dom-parser"; // https://www.npmjs.com/package/dom-parser
import open from "open"


if (process.argv[1] === fileURLToPath(import.meta.url)) {
let interval = {
unit: 'seconds', // seconds, m: minutes, h: hours
value: 5
value: 30
}
let url = 'https://www.antonline.com/Sony/Electronics/Gaming_Devices/Gaming_Consoles/1413553'
let url = 'https://www.antonline.com/Sony/Electronics/Audio_Electronics/Headsets+Earsets/1398728'
antonline(url, interval);
}


let firstRun = new Set();
let urlOpened = false;
export default async function antonline(url, interval) {
try {
var res = await axios.get(url);
Expand All @@ -33,6 +36,7 @@ export default async function antonline(url, interval) {
}
else if (inventory && inventory == 'Add to Cart') {
threeBeeps();
if (OPEN_URL && !urlOpened) { open(url); urlOpened = true; setTimeout(() => urlOpened = false, 1000 * 115) } // Open URL every 2 minutes
console.info(moment().format('LTS') + ': ***** In Stock at AntOnline *****: ', title);
console.info(url);
}
Expand Down
5 changes: 5 additions & 0 deletions stores/bestbuy.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { fileURLToPath } from "url";
import { OPEN_URL } from '../main.js'
import fs from 'fs';
import threeBeeps from "../beep.js"
import axios from "axios";
import moment from "moment";
import DomParser from "dom-parser"; // https://www.npmjs.com/package/dom-parser
import open from "open"


if (process.argv[1] === fileURLToPath(import.meta.url)) {
Expand All @@ -17,6 +19,7 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {


let firstRun = new Set();
let urlOpened = false;
export default async function bestbuy(url, interval) {
try {
var res = await axios.get(url);
Expand All @@ -30,11 +33,13 @@ export default async function bestbuy(url, interval) {
if (inventory.length > 0) inventory = inventory[0].textContent
if (open_box && open_box.length > 0) {
threeBeeps();
if (OPEN_URL && !urlOpened) { open(url); urlOpened = true; setTimeout(() => urlOpened = false, 1000 * 115) } // Open URL every 2 minutes
console.info(moment().format('LTS') + ': ***** Open Box at BestBuy *****: ', title);
console.info(url);
}
if (inventory == 'Add to Cart') {
threeBeeps();
if (OPEN_URL && !urlOpened) { open(url); urlOpened = true; setTimeout(() => urlOpened = false, 1000 * 115) } // Open URL every 2 minutes
console.info(moment().format('LTS') + ': ***** In Stock at BestBuy *****: ', title);
console.info(url);
}
Expand Down
4 changes: 4 additions & 0 deletions stores/costco.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { fileURLToPath } from "url";
import { OPEN_URL } from '../main.js'
import fs from "fs";
import threeBeeps from "../beep.js"
import axios from "axios";
import moment from "moment";
import DomParser from "dom-parser"; // https://www.npmjs.com/package/dom-parser
import open from "open"


if (process.argv[1] === fileURLToPath(import.meta.url)) {
Expand All @@ -17,6 +19,7 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {


let firstRun = new Set();
let urlOpened = false;
export default async function costco(url, interval) {
try {
var res = await axios.get(url);
Expand All @@ -32,6 +35,7 @@ export default async function costco(url, interval) {
}
else if (inventory != 'Out of Stock') {
threeBeeps();
if (OPEN_URL && !urlOpened) { open(url); urlOpened = true; setTimeout(() => urlOpened = false, 1000 * 115) } // Open URL every 2 minutes
console.info(moment().format('LTS') + ': ***** In Stock at Costco *****: ', title);
console.info(url);
}
Expand Down
Loading

0 comments on commit 5698709

Please sign in to comment.