feat: update for complex add to cart, fix nvidia (#108)

This commit is contained in:
fuckingrobot
2020-09-21 08:24:20 -04:00
committed by GitHub
parent 722eaf3cd6
commit 3ea146da14
4 changed files with 99 additions and 12 deletions
+5 -1
View File
@@ -91,7 +91,11 @@ async function lookup(browser: Browser, store: Store) {
const givenUrl = link.cartUrl ? link.cartUrl : link.url; const givenUrl = link.cartUrl ? link.cartUrl : link.url;
if (Config.browser.open) { if (Config.browser.open) {
await open(givenUrl); if (link.openCartAction === undefined) {
await open(givenUrl);
} else {
link.openCartAction(browser);
}
} }
sendNotification(givenUrl, link); sendNotification(givenUrl, link);
+80 -8
View File
@@ -1,20 +1,92 @@
import {Store} from './store'; import {Store} from './store';
import {Browser, Response} from 'puppeteer';
import {timestampUrlParameter} from '../timestamp-url-parameter';
import {Logger} from '../../logger';
import open from 'open';
const fe2060SuperId = 5379432500;
const fe3080Id = 5438481700;
const locale = 'en_us';
const nvidiaApiKey = '9485fa7b159e42edb08a83bde0d83dia';
function digitalRiverStockUrl(id: number): string {
return `https://api.digitalriver.com/v1/shoppers/me/products/${id}/inventory-status?` +
`&apiKey=${nvidiaApiKey}` +
timestampUrlParameter();
}
interface NvidiaSessionTokenJSON {
access_token: string;
}
function nvidiaSessionUrl(): string {
return `https://store.nvidia.com/store/nvidia/SessionToken?format=json&locale=${locale}` +
`&apiKey=${nvidiaApiKey}` +
timestampUrlParameter();
}
function addToCartUrl(id: number, token: string): string {
return 'https://api.digitalriver.com/v1/shoppers/me/carts/active/line-items?format=json&method=post' +
`&productId=${id}` +
`&token=${token}` +
'&quantity=1' +
timestampUrlParameter();
}
function checkoutUrl(token: string): string {
return `https://api.digitalriver.com/v1/shoppers/me/carts/active/web-checkout?token=${token}`;
}
function fallbackCartUrl(): string {
return `https://www.nvidia.com/en-us/shop/geforce?${timestampUrlParameter()}`;
}
function generateCartAction(id: number, cardName: string) {
return async (browser: Browser) => {
const page = await browser.newPage();
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, starting auto add to cart... 🚀🚀🚀`);
let response: Response | null;
try {
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, getting access token... 🚀🚀🚀`);
response = await page.goto(nvidiaSessionUrl(), {waitUntil: 'networkidle0'});
if (response === null) {
throw new Error('NvidiaAccessTokenUnavailable');
}
const data = await response.json() as NvidiaSessionTokenJSON;
const accessToken = data.access_token;
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, adding to cart... 🚀🚀🚀`);
response = await page.goto(addToCartUrl(id, accessToken), {waitUntil: 'networkidle0'});
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, opening checkout page... 🚀🚀🚀`);
Logger.info(checkoutUrl(accessToken));
await open(checkoutUrl(accessToken));
} catch {
Logger.error(`✖ [nvidia] ${cardName} could not automatically add to cart, opening page`);
await open(fallbackCartUrl());
}
await page.close();
};
}
export const Nvidia: Store = { export const Nvidia: Store = {
links: [ links: [
{ {
brand: 'TEST',
cartUrl: 'https://www.nvidia.com/en-us/shop/geforce',
model: 'CARD',
series: 'debug', series: 'debug',
url: 'https://api.digitalriver.com/v1/shoppers/me/products/5379432500/inventory-status?apiKey=9485fa7b159e42edb08a83bde0d83dia' brand: 'TEST',
model: 'CARD',
url: digitalRiverStockUrl(fe2060SuperId),
openCartAction: generateCartAction(fe2060SuperId, 'TEST CARD')
}, },
{ {
brand: 'nvidia',
cartUrl: 'https://www.nvidia.com/en-us/shop/geforce',
model: 'founders edition',
series: '3080', series: '3080',
url: 'https://api.digitalriver.com/v1/shoppers/me/products/5438481700/inventory-status?apiKey=9485fa7b159e42edb08a83bde0d83dia' brand: 'nvidia',
model: 'founders edition',
url: digitalRiverStockUrl(fe3080Id),
openCartAction: generateCartAction(fe3080Id, 'nvidia founders edition 3080')
} }
], ],
labels: { labels: {
+6 -3
View File
@@ -1,9 +1,12 @@
import {Browser} from 'puppeteer';
export interface Link { export interface Link {
brand: string;
cartUrl?: string;
model: string;
series: string; series: string;
brand: string;
model: string;
url: string; url: string;
cartUrl?: string;
openCartAction?: (browser: Browser) => void;
screenshot?: string; screenshot?: string;
} }
+8
View File
@@ -0,0 +1,8 @@
/**
* Generates unique URL param to prevent cached responses (similar to jQuery that Nvidia uses)
*
* @return string in format &=1111111111111 (time since epoch in ms)
*/
export function timestampUrlParameter(): string {
return `&_=${Date.now()}`;
}