mirror of
https://github.com/opelly27/streetmerchant.git
synced 2026-05-20 11:07:43 +00:00
feat(notification): add pushbullet, add url with notifications (#226)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
This commit is contained in:
@@ -11,6 +11,7 @@ PAGE_TIMEOUT="30000"
|
|||||||
PHONE_NUMBER="1234567890"
|
PHONE_NUMBER="1234567890"
|
||||||
PHONE_CARRIER="tmobile"
|
PHONE_CARRIER="tmobile"
|
||||||
PLAY_SOUND="notification.mp3"
|
PLAY_SOUND="notification.mp3"
|
||||||
|
PUSHBULLET="o.pushbulletTokendbjVjvJHVhcg"
|
||||||
PUSHOVER_TOKEN="123pushover-token456"
|
PUSHOVER_TOKEN="123pushover-token456"
|
||||||
PUSHOVER_USER="123pushover-user-key"
|
PUSHOVER_USER="123pushover-user-key"
|
||||||
PAGE_SLEEP_MIN="5000"
|
PAGE_SLEEP_MIN="5000"
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ Here is a list of variables that you can use to customize your newly copied `.en
|
|||||||
| `PHONE_NUMBER` | 10 digit phone number | E.g.: `1234567890`, email configuration required |
|
| `PHONE_NUMBER` | 10 digit phone number | E.g.: `1234567890`, email configuration required |
|
||||||
| `PHONE_CARRIER` | [Supported carriers](#supported-carriers) for SMS | Email configuration required |
|
| `PHONE_CARRIER` | [Supported carriers](#supported-carriers) for SMS | Email configuration required |
|
||||||
| `PLAY_SOUND` | Play this sound notification if a card is found | E.g.: `path/to/notification.wav`, relative path accepted, valid formats: wav, mp3, flac, [free sounds available](https://notificationsounds.com/) |
|
| `PLAY_SOUND` | Play this sound notification if a card is found | E.g.: `path/to/notification.wav`, relative path accepted, valid formats: wav, mp3, flac, [free sounds available](https://notificationsounds.com/) |
|
||||||
|
| `PUSHBULLET` | PushBullet API key | Get at https://www.pushbullet.com/#settings/account |
|
||||||
| `PUSHOVER_TOKEN` | Pushover access token | Generate at https://pushover.net/apps/build |
|
| `PUSHOVER_TOKEN` | Pushover access token | Generate at https://pushover.net/apps/build |
|
||||||
| `PUSHOVER_USER` | Pushover username |
|
| `PUSHOVER_USER` | Pushover username |
|
||||||
| `PAGE_SLEEP_MIN` | Minimum sleep time between queries of the same store | Default: `5000` |
|
| `PAGE_SLEEP_MIN` | Minimum sleep time between queries of the same store | Default: `5000` |
|
||||||
|
|||||||
Generated
+61
@@ -879,6 +879,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
|
||||||
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
|
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
|
||||||
},
|
},
|
||||||
|
"async-limiter": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
|
||||||
|
},
|
||||||
"asynckit": {
|
"asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
@@ -1427,6 +1432,11 @@
|
|||||||
"integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
|
"integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"clone": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
||||||
|
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
|
||||||
|
},
|
||||||
"clone-deep": {
|
"clone-deep": {
|
||||||
"version": "0.2.4",
|
"version": "0.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz",
|
||||||
@@ -4821,6 +4831,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||||
},
|
},
|
||||||
|
"node-forge": {
|
||||||
|
"version": "0.7.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz",
|
||||||
|
"integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw=="
|
||||||
|
},
|
||||||
"node-libs-browser": {
|
"node-libs-browser": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
|
||||||
@@ -5636,6 +5651,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pushbullet": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pushbullet/-/pushbullet-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-9CkgzAmBOv/ekxI4oqlFXdFIdKEMQgv1NBUbQYYxo/OsGYdnM2D9xEtWLQLkMAkpZUwbNr9lHq7a27082+eQMw==",
|
||||||
|
"requires": {
|
||||||
|
"clone": "^2.1.2",
|
||||||
|
"mime": "^2.4.0",
|
||||||
|
"node-forge": "^0.7.6",
|
||||||
|
"request": "^2.88.0",
|
||||||
|
"request-promise-native": "^1.0.5",
|
||||||
|
"ws": "^6.1.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ws": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
|
||||||
|
"requires": {
|
||||||
|
"async-limiter": "~1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"pushover-notifications": {
|
"pushover-notifications": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/pushover-notifications/-/pushover-notifications-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/pushover-notifications/-/pushover-notifications-1.2.2.tgz",
|
||||||
@@ -5913,6 +5951,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request-promise-core": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.19"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request-promise-native": {
|
||||||
|
"version": "1.0.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
|
||||||
|
"integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
|
||||||
|
"requires": {
|
||||||
|
"request-promise-core": "1.1.4",
|
||||||
|
"stealthy-require": "^1.1.1",
|
||||||
|
"tough-cookie": "^2.3.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"reserved-words": {
|
"reserved-words": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz",
|
||||||
@@ -6396,6 +6452,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"stealthy-require": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
|
||||||
|
},
|
||||||
"stream-browserify": {
|
"stream-browserify": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
"puppeteer-extra": "^3.1.15",
|
"puppeteer-extra": "^3.1.15",
|
||||||
"puppeteer-extra-plugin-adblocker": "^2.11.6",
|
"puppeteer-extra-plugin-adblocker": "^2.11.6",
|
||||||
"puppeteer-extra-plugin-stealth": "^2.6.1",
|
"puppeteer-extra-plugin-stealth": "^2.6.1",
|
||||||
|
"pushbullet": "^2.4.0",
|
||||||
"pushover-notifications": "^1.2.2",
|
"pushover-notifications": "^1.2.2",
|
||||||
"twitter": "^1.7.1",
|
"twitter": "^1.7.1",
|
||||||
"winston": "^3.3.3"
|
"winston": "^3.3.3"
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ const notifications = {
|
|||||||
number: process.env.PHONE_NUMBER ?? ''
|
number: process.env.PHONE_NUMBER ?? ''
|
||||||
},
|
},
|
||||||
playSound: process.env.PLAY_SOUND ?? '',
|
playSound: process.env.PLAY_SOUND ?? '',
|
||||||
|
pushBulletApiKey: process.env.PUSHBULLET ?? '',
|
||||||
pushover: {
|
pushover: {
|
||||||
token: process.env.PUSHOVER_TOKEN ?? '',
|
token: process.env.PUSHOVER_TOKEN ?? '',
|
||||||
username: process.env.PUSHOVER_USER ?? ''
|
username: process.env.PUSHOVER_USER ?? ''
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {playSound} from './sound';
|
|||||||
import {sendDesktopNotification} from './desktop';
|
import {sendDesktopNotification} from './desktop';
|
||||||
import {sendDiscordMessage} from './discord';
|
import {sendDiscordMessage} from './discord';
|
||||||
import {sendEmail} from './email';
|
import {sendEmail} from './email';
|
||||||
|
import {sendPushBulletNotification} from './pushbullet';
|
||||||
import {sendPushoverNotification} from './pushover';
|
import {sendPushoverNotification} from './pushover';
|
||||||
import {sendSMS} from './sms';
|
import {sendSMS} from './sms';
|
||||||
import {sendSlackMessage} from './slack';
|
import {sendSlackMessage} from './slack';
|
||||||
@@ -36,6 +37,10 @@ export function sendNotification(cartUrl: string, link: Link) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (notifications.pushBulletApiKey) {
|
||||||
|
sendPushBulletNotification(cartUrl, link);
|
||||||
|
}
|
||||||
|
|
||||||
if (notifications.pushover.token && notifications.pushover.username) {
|
if (notifications.pushover.token && notifications.pushover.username) {
|
||||||
sendPushoverNotification(cartUrl);
|
sendPushoverNotification(cartUrl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import {Config} from '../config';
|
||||||
|
import {Link} from '../store/model';
|
||||||
|
import {Logger} from '../logger';
|
||||||
|
import PushBullet from 'pushbullet';
|
||||||
|
|
||||||
|
const pushBulletApiKey = Config.notifications.pushBulletApiKey;
|
||||||
|
|
||||||
|
export function sendPushBulletNotification(cartUrl: string, link: Link) {
|
||||||
|
const pusher = new PushBullet(pushBulletApiKey);
|
||||||
|
const title = `🚨 ${link.brand} ${link.model} ${link.series} 👀`;
|
||||||
|
|
||||||
|
pusher.note({}, title, cartUrl, (err: Error, result: string) => {
|
||||||
|
if (err) {
|
||||||
|
Logger.error(err);
|
||||||
|
} else {
|
||||||
|
Logger.info(`↗ pushbullet notification sent: ${result}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
+2
-2
@@ -88,13 +88,13 @@ async function lookupCard(browser: Browser, store: Store, page: Page, link: Link
|
|||||||
await page.screenshot({path: link.screenshot});
|
await page.screenshot({path: link.screenshot});
|
||||||
}
|
}
|
||||||
|
|
||||||
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
let givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
||||||
|
|
||||||
if (Config.browser.open) {
|
if (Config.browser.open) {
|
||||||
if (link.openCartAction === undefined) {
|
if (link.openCartAction === undefined) {
|
||||||
await open(givenUrl);
|
await open(givenUrl);
|
||||||
} else {
|
} else {
|
||||||
link.openCartAction(browser);
|
givenUrl = await link.openCartAction(browser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,8 +67,11 @@ export function generateSetupAction() {
|
|||||||
const accessToken = data.access_token;
|
const accessToken = data.access_token;
|
||||||
|
|
||||||
Logger.info('[nvidia] you can log into your cart now...');
|
Logger.info('[nvidia] you can log into your cart now...');
|
||||||
Logger.info(checkoutUrl(drLocale, accessToken));
|
const cartUrl = checkoutUrl(drLocale, accessToken);
|
||||||
await open(checkoutUrl(drLocale, accessToken));
|
Logger.info(cartUrl);
|
||||||
|
if (Config.browser.open) {
|
||||||
|
await open(cartUrl);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.debug(error);
|
Logger.debug(error);
|
||||||
Logger.error('✖ [nvidia] cannot generate cart/session token, continuing without, auto-"add to cart" may not work...');
|
Logger.error('✖ [nvidia] cannot generate cart/session token, continuing without, auto-"add to cart" may not work...');
|
||||||
@@ -83,6 +86,7 @@ export function generateOpenCartAction(id: number, nvidiaLocale: string, drLocal
|
|||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, starting auto add to cart... 🚀🚀🚀`);
|
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, starting auto add to cart... 🚀🚀🚀`);
|
||||||
let response: Response | null;
|
let response: Response | null;
|
||||||
|
let cartUrl: string;
|
||||||
try {
|
try {
|
||||||
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, getting access token... 🚀🚀🚀`);
|
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, getting access token... 🚀🚀🚀`);
|
||||||
response = await page.goto(nvidiaSessionUrl(nvidiaLocale), {waitUntil: 'networkidle0'});
|
response = await page.goto(nvidiaSessionUrl(nvidiaLocale), {waitUntil: 'networkidle0'});
|
||||||
@@ -97,15 +101,19 @@ export function generateOpenCartAction(id: number, nvidiaLocale: string, drLocal
|
|||||||
response = await page.goto(addToCartUrl(id, drLocale, accessToken), {waitUntil: 'networkidle0'});
|
response = await page.goto(addToCartUrl(id, drLocale, accessToken), {waitUntil: 'networkidle0'});
|
||||||
|
|
||||||
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, opening checkout page... 🚀🚀🚀`);
|
Logger.info(`🚀🚀🚀 [nvidia] ${cardName}, opening checkout page... 🚀🚀🚀`);
|
||||||
Logger.info(checkoutUrl(drLocale, accessToken));
|
cartUrl = checkoutUrl(drLocale, accessToken);
|
||||||
await open(checkoutUrl(drLocale, accessToken));
|
Logger.info(cartUrl);
|
||||||
|
await open(cartUrl);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.debug(error);
|
Logger.debug(error);
|
||||||
Logger.error(`✖ [nvidia] ${cardName} could not automatically add to cart, opening page`);
|
Logger.error(`✖ [nvidia] ${cardName} could not automatically add to cart, opening page`);
|
||||||
await open(fallbackCartUrl(nvidiaLocale));
|
cartUrl = fallbackCartUrl(nvidiaLocale);
|
||||||
|
await open(cartUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
await page.close();
|
await page.close();
|
||||||
|
|
||||||
|
return cartUrl;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export interface Link {
|
|||||||
model: string;
|
model: string;
|
||||||
url: string;
|
url: string;
|
||||||
cartUrl?: string;
|
cartUrl?: string;
|
||||||
openCartAction?: (browser: Browser) => void;
|
openCartAction?: (browser: Browser) => Promise<string>;
|
||||||
screenshot?: string;
|
screenshot?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
declare module 'pushbullet';
|
||||||
Reference in New Issue
Block a user