mirror of
https://github.com/opelly27/streetmerchant.git
synced 2026-05-20 05:17:35 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fcb279d5de | |||
| 5c9e0b6d06 | |||
| 6c3cd01685 | |||
| d907092b44 | |||
| 7cfc7c7442 | |||
| 971fec20e4 |
+2
-1
@@ -7,4 +7,5 @@ SLACK_CHANNEL="SlackChannelName"
|
|||||||
SLACK_TOKEN="slack-token"
|
SLACK_TOKEN="slack-token"
|
||||||
STORES="bestbuy,bandh,nvidia"
|
STORES="bestbuy,bandh,nvidia"
|
||||||
PHONE_NUMBER="1234567890"
|
PHONE_NUMBER="1234567890"
|
||||||
CARRIER="tmobile"
|
PHONE_CARRIER="tmobile"
|
||||||
|
SCREENSHOT="true"
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [1.3.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.2.0...v1.3.0) (2020-09-19)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **logging:** add timestamp ([#48](https://www.github.com/jef/nvidia-snatcher/issues/48)) ([6c3cd01](https://www.github.com/jef/nvidia-snatcher/commit/6c3cd016850d03a6c6a894cab24ba2d3781a9af1))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **store:** amazon captcha false-positives ([#54](https://www.github.com/jef/nvidia-snatcher/issues/54)) ([5c9e0b6](https://www.github.com/jef/nvidia-snatcher/commit/5c9e0b6d06bd7e1223a7587fec067c8e79c9cfd6))
|
||||||
|
* evga xc3 ultra link ([#56](https://www.github.com/jef/nvidia-snatcher/issues/56)) ([d907092](https://www.github.com/jef/nvidia-snatcher/commit/d907092b443b056605e09cb2ca3e94e6ca811d9e))
|
||||||
|
* screenshot size, add screenshot config setting ([#53](https://www.github.com/jef/nvidia-snatcher/issues/53)) ([7cfc7c7](https://www.github.com/jef/nvidia-snatcher/commit/7cfc7c74429c808fa14468cdd497eb9f9aeb922c))
|
||||||
|
* sms carrier config, add google carrier ([#44](https://www.github.com/jef/nvidia-snatcher/issues/44)) ([971fec2](https://www.github.com/jef/nvidia-snatcher/commit/971fec20e441e2b12a38d5c8d17d2d4cb5e64d6b))
|
||||||
|
|
||||||
## [1.2.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.1.0...v1.2.0) (2020-09-19)
|
## [1.2.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.1.0...v1.2.0) (2020-09-19)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -69,11 +69,12 @@ First, you're going to need to copy the `.env.example` to `.env`. The current op
|
|||||||
| `NOTIFICATION_TEST` | Test all the notifications configured; optional, default: `false` |
|
| `NOTIFICATION_TEST` | Test all the notifications configured; optional, default: `false` |
|
||||||
| `PAGE_TIMEOUT` | Navigation Timeout in milliseconds (`0` for infinite); optional, default: `30000` |
|
| `PAGE_TIMEOUT` | Navigation Timeout in milliseconds (`0` for infinite); optional, default: `30000` |
|
||||||
| `PHONE_NUMBER` | 10 digit phone number, only USA, SMS may apply (e.g., `1234567890`); optional, email configuration required |
|
| `PHONE_NUMBER` | 10 digit phone number, only USA, SMS may apply (e.g., `1234567890`); optional, email configuration required |
|
||||||
| `PHONE_CARRIER` | Service provider for SMS, supports `["sprint", "tmobile", "att", "verizon"]`; optional, email configuration required |
|
| `PHONE_CARRIER` | Service provider for SMS, supports `["sprint", "tmobile", "att", "verizon", "google"]`; optional, email configuration required |
|
||||||
| `RATE_LIMIT_TIMEOUT` | Rate limit timeout for each full store cycle; optional, default: `5000` |
|
| `RATE_LIMIT_TIMEOUT` | Rate limit timeout for each full store cycle; optional, default: `5000` |
|
||||||
| `SLACK_CHANNEL` | Slack channel for posting (e.g., `update`); optional |
|
| `SLACK_CHANNEL` | Slack channel for posting (e.g., `update`); optional |
|
||||||
| `SLACK_TOKEN` | Slack API token; optional
|
| `SLACK_TOKEN` | Slack API token; optional
|
||||||
| `STORES` | List of [stores](#Supported-stores) you want to be scraped; optional, default: `nvidia` |
|
| `STORES` | List of [stores](#Supported-stores) you want to be scraped; optional, default: `nvidia` |
|
||||||
|
| `SCREENSHOT` | Capture screenshot of page on successful hit; optional, default `true` |
|
||||||
|
|
||||||
> :point_right: If you have multi-factor authentication (MFA), you will need to create an [app password](https://myaccount.google.com/apppasswords) and use this instead of your Gmail password.
|
> :point_right: If you have multi-factor authentication (MFA), you will need to create an [app password](https://myaccount.google.com/apppasswords) and use this instead of your Gmail password.
|
||||||
|
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nvidia-snatcher",
|
"name": "nvidia-snatcher",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nvidia-snatcher",
|
"name": "nvidia-snatcher",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"description": "🔮 For all your Nvidia needs",
|
"description": "🔮 For all your Nvidia needs",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+5
-4
@@ -9,7 +9,7 @@ const notifications = {
|
|||||||
password: process.env.EMAIL_PASSWORD ?? ''
|
password: process.env.EMAIL_PASSWORD ?? ''
|
||||||
},
|
},
|
||||||
phone: {
|
phone: {
|
||||||
availableCarriers: ['sprint', 'verizon', 'tmobile', 'att'],
|
availableCarriers: ['sprint', 'verizon', 'tmobile', 'att', 'google'],
|
||||||
carrier: process.env.PHONE_CARRIER,
|
carrier: process.env.PHONE_CARRIER,
|
||||||
number: process.env.PHONE_NUMBER
|
number: process.env.PHONE_NUMBER
|
||||||
},
|
},
|
||||||
@@ -21,10 +21,11 @@ const notifications = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const page = {
|
const page = {
|
||||||
height: 1920,
|
capture: process.env.SCREENSHOT ?? 'true',
|
||||||
|
width: 1920,
|
||||||
|
height: 1080,
|
||||||
navigationTimeout: Number(process.env.PAGE_TIMEOUT) ?? 30000,
|
navigationTimeout: Number(process.env.PAGE_TIMEOUT) ?? 30000,
|
||||||
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
|
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
|
||||||
width: 1080
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const rateLimitTimeout = Number(process.env.RATE_LIMIT_TIMEOUT) ?? 5000;
|
const rateLimitTimeout = Number(process.env.RATE_LIMIT_TIMEOUT) ?? 5000;
|
||||||
|
|||||||
+4
-2
@@ -68,8 +68,10 @@ async function lookup(store: Store) {
|
|||||||
Logger.info(`🚀🚀🚀 [${store.name}] ${graphicsCard} IN STOCK 🚀🚀🚀`);
|
Logger.info(`🚀🚀🚀 [${store.name}] ${graphicsCard} IN STOCK 🚀🚀🚀`);
|
||||||
Logger.info(link.url);
|
Logger.info(link.url);
|
||||||
|
|
||||||
Logger.debug('ℹ saving screenshot');
|
if (Config.page.capture === 'true') {
|
||||||
await page.screenshot({path: `success-${Date.now()}.png`});
|
Logger.debug('ℹ saving screenshot');
|
||||||
|
await page.screenshot({path: `success-${Date.now()}.png`});
|
||||||
|
}
|
||||||
|
|
||||||
const givenUrl = store.cartUrl ? store.cartUrl : link.url;
|
const givenUrl = store.cartUrl ? store.cartUrl : link.url;
|
||||||
await open(givenUrl);
|
await open(givenUrl);
|
||||||
|
|||||||
+3
-1
@@ -1,11 +1,13 @@
|
|||||||
import winston, {format} from 'winston';
|
import winston, {format} from 'winston';
|
||||||
|
|
||||||
const prettyJson = format.printf(info => {
|
const prettyJson = format.printf(info => {
|
||||||
|
const timestamp = new Date().toLocaleTimeString();
|
||||||
|
|
||||||
if (typeof info.message === 'object') {
|
if (typeof info.message === 'object') {
|
||||||
info.message = JSON.stringify(info.message, null, 4);
|
info.message = JSON.stringify(info.message, null, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${info.level} :: ${info.message}`;
|
return `[${timestamp}] ${info.level} :: ${info.message}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Logger = winston.createLogger({
|
export const Logger = winston.createLogger({
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ export default function sendNotification(cartUrl: string) {
|
|||||||
sendSlaskMessage(cartUrl);
|
sendSlaskMessage(cartUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.notifications.phone.number && Config.notifications.phone.carrier) {
|
if (Config.notifications.phone.number) {
|
||||||
if (Config.notifications.phone.availableCarriers.includes(Config.notifications.phone.carrier.toLowerCase())) {
|
const carrier = Config.notifications.phone.carrier?.toLowerCase();
|
||||||
|
if (carrier && Config.notifications.phone.availableCarriers.includes(carrier)) {
|
||||||
sendSMS(cartUrl);
|
sendSMS(cartUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ enum carrierAddress {
|
|||||||
sprint = 'messaging.sprintpcs.com',
|
sprint = 'messaging.sprintpcs.com',
|
||||||
verizon = 'vtext.com',
|
verizon = 'vtext.com',
|
||||||
tmobile = 'tmomail.net',
|
tmobile = 'tmomail.net',
|
||||||
att = 'txt.att.net'
|
att = 'txt.att.net',
|
||||||
|
google = 'msg.fi.google.com'
|
||||||
}
|
}
|
||||||
|
|
||||||
const transporter = nodemailer.createTransport({
|
const transporter = nodemailer.createTransport({
|
||||||
@@ -34,16 +35,15 @@ export default function sendSMS(text: string) {
|
|||||||
Logger.error(error);
|
Logger.error(error);
|
||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
Logger.info(`✔ email sent: ${info.response}`);
|
Logger.info(`✔ sms sent: ${info.response}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateAddress() {
|
function generateAddress() {
|
||||||
for (const carrier of Object.keys(carrierAddress)) {
|
const carrier = Config.notifications.phone.carrier?.toLowerCase();
|
||||||
if (Config.notifications.phone.carrier && carrier === Config.notifications.phone.carrier.toLowerCase()) {
|
if (carrier && Object.keys(carrierAddress).includes(carrier)) {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
return [Config.phone.number, carrierAddress[carrier]].join('@');
|
return [Config.notifications.phone.number, carrierAddress[carrier]].join('@');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -7,49 +7,49 @@ export const Amazon: Store = {
|
|||||||
brand: 'pny',
|
brand: 'pny',
|
||||||
model: 'xlr8',
|
model: 'xlr8',
|
||||||
url: 'https://www.amazon.com/PNY-GeForce-Gaming-Epic-X-Graphics/dp/B08HBR7QBM?ref_=ast_sto_dp',
|
url: 'https://www.amazon.com/PNY-GeForce-Gaming-Epic-X-Graphics/dp/B08HBR7QBM?ref_=ast_sto_dp',
|
||||||
oosLabels: ['currently unavailable']
|
oosLabels: ['currently unavailable', 'Enter the characters you see below']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
model: 'gaming trio',
|
model: 'gaming trio',
|
||||||
url: 'https://www.amazon.com/MSI-GeForce-RTX-3080-10G/dp/B08HR7SV3M?ref_=ast_sto_dp',
|
url: 'https://www.amazon.com/MSI-GeForce-RTX-3080-10G/dp/B08HR7SV3M?ref_=ast_sto_dp',
|
||||||
oosLabels: ['currently unavailable']
|
oosLabels: ['currently unavailable', 'Enter the characters you see below']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
model: 'ftw3',
|
model: 'ftw3',
|
||||||
url: 'https://www.amazon.com/EVGA-10G-P5-3897-KR-GeForce-Technology-Backplate/dp/B08HR3Y5GQ?ref_=ast_sto_dp',
|
url: 'https://www.amazon.com/EVGA-10G-P5-3897-KR-GeForce-Technology-Backplate/dp/B08HR3Y5GQ?ref_=ast_sto_dp',
|
||||||
oosLabels: ['currently unavailable']
|
oosLabels: ['currently unavailable', 'Enter the characters you see below']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
model: 'xc3',
|
model: 'xc3',
|
||||||
url: 'https://www.amazon.com/EVGA-10G-P5-3885-KR-GeForce-Cooling-Backplate/dp/B08HR55YB5?ref_=ast_sto_dp',
|
url: 'https://www.amazon.com/EVGA-10G-P5-3885-KR-GeForce-Cooling-Backplate/dp/B08HR55YB5?ref_=ast_sto_dp',
|
||||||
oosLabels: ['currently unavailable']
|
oosLabels: ['currently unavailable', 'Enter the characters you see below']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
model: 'windforce',
|
model: 'windforce',
|
||||||
url: 'https://www.amazon.com/GIGABYTE-GeForce-Graphics-WINDFORCE-GV-N3080GAMING/dp/B08HJTH61J?ref_=ast_sto_dp',
|
url: 'https://www.amazon.com/GIGABYTE-GeForce-Graphics-WINDFORCE-GV-N3080GAMING/dp/B08HJTH61J?ref_=ast_sto_dp',
|
||||||
oosLabels: ['currently unavailable']
|
oosLabels: ['currently unavailable', 'Enter the characters you see below']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
model: 'windforce eagle',
|
model: 'windforce eagle',
|
||||||
url: 'https://www.amazon.com/GIGABYTE-GeForce-Graphics-WINDFORCE-GV-N3080EAGLE/dp/B08HJS2JLJ?ref_=ast_sto_dp',
|
url: 'https://www.amazon.com/GIGABYTE-GeForce-Graphics-WINDFORCE-GV-N3080EAGLE/dp/B08HJS2JLJ?ref_=ast_sto_dp',
|
||||||
oosLabels: ['currently unavailable']
|
oosLabels: ['currently unavailable', 'Enter the characters you see below']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
model: 'tuf',
|
model: 'tuf',
|
||||||
url: 'https://www.amazon.com/ASUS-Graphics-DisplayPort-Military-Grade-Certification/dp/B08HH5WF97?ref_=ast_sto_dp',
|
url: 'https://www.amazon.com/ASUS-Graphics-DisplayPort-Military-Grade-Certification/dp/B08HH5WF97?ref_=ast_sto_dp',
|
||||||
oosLabels: ['currently unavailable']
|
oosLabels: ['currently unavailable', 'Enter the characters you see below']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
model: 'ventus',
|
model: 'ventus',
|
||||||
url: 'https://www.amazon.com/MSI-GeForce-RTX-3080-10G/dp/B08HR5SXPS?ref_=ast_sto_dp',
|
url: 'https://www.amazon.com/MSI-GeForce-RTX-3080-10G/dp/B08HR5SXPS?ref_=ast_sto_dp',
|
||||||
oosLabels: ['currently unavailable']
|
oosLabels: ['currently unavailable', 'Enter the characters you see below']
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'amazon'
|
name: 'amazon'
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const BestBuy: Store = {
|
|||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
model: 'xc3 ultra',
|
model: 'xc3 ultra',
|
||||||
url: 'https://www.bestbuy.com/site/asus-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-strix-graphics-card-black/6432445.p?skuId=6432445',
|
url: 'https://www.bestbuy.com/site/evga-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card/6432400.p?skuId=6432400',
|
||||||
oosLabels: ['sold out', 'coming soon']
|
oosLabels: ['sold out', 'coming soon']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user