Skip to content

Commit

Permalink
feat: update for complex add to cart, fix nvidia (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
fuckingrobot committed Sep 21, 2020
1 parent 722eaf3 commit 3ea146d
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 9 deletions.
6 changes: 5 additions & 1 deletion src/store/lookup.ts
Expand Up @@ -91,7 +91,11 @@ async function lookup(browser: Browser, store: Store) {
const givenUrl = link.cartUrl ? link.cartUrl : link.url;

if (Config.browser.open) {
await open(givenUrl);
if (link.openCartAction === undefined) {
await open(givenUrl);
} else {
link.openCartAction(browser);
}
}

sendNotification(givenUrl, link);
Expand Down
84 changes: 78 additions & 6 deletions src/store/model/nvidia.ts
@@ -1,20 +1,92 @@
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 = {
links: [
{
series: 'debug',
brand: 'TEST',
cartUrl: 'https://www.nvidia.com/en-us/shop/geforce',
model: 'CARD',
series: 'debug',
url: 'https://api.digitalriver.com/v1/shoppers/me/products/5379432500/inventory-status?apiKey=9485fa7b159e42edb08a83bde0d83dia'
url: digitalRiverStockUrl(fe2060SuperId),
openCartAction: generateCartAction(fe2060SuperId, 'TEST CARD')
},
{
series: '3080',
brand: 'nvidia',
cartUrl: 'https://www.nvidia.com/en-us/shop/geforce',
model: 'founders edition',
series: '3080',
url: 'https://api.digitalriver.com/v1/shoppers/me/products/5438481700/inventory-status?apiKey=9485fa7b159e42edb08a83bde0d83dia'
url: digitalRiverStockUrl(fe3080Id),
openCartAction: generateCartAction(fe3080Id, 'nvidia founders edition 3080')
}
],
labels: {
Expand Down
7 changes: 5 additions & 2 deletions src/store/model/store.ts
@@ -1,9 +1,12 @@
import {Browser} from 'puppeteer';

export interface Link {
series: string;
brand: string;
cartUrl?: string;
model: string;
series: string;
url: string;
cartUrl?: string;
openCartAction?: (browser: Browser) => void;
screenshot?: string;
}

Expand Down
8 changes: 8 additions & 0 deletions src/store/timestamp-url-parameter.ts
@@ -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()}`;
}

0 comments on commit 3ea146d

Please sign in to comment.