Skip to content

Commit

Permalink
feat: multiple discord roles and webhooks, qol for envs
Browse files Browse the repository at this point in the history
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
  • Loading branch information
jef committed Sep 24, 2020
1 parent 9f470f0 commit 1cfccb9
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 41 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ At any point you want the program to stop, use <kbd>Ctrl</kbd> + <kbd>C</kbd>.
### Customization

To customize `nvidia-snatcher`, make a copy of `.env-example` as `.env` and make any changes to your liking. _Note that all environment variables are **optional**._
To customize `nvidia-snatcher`, make a copy of `.env-example` as `.env` and make any changes to your liking. _All environment variables are **optional**._

Here is a list of variables that you can use to customize your newly copied `.env` file:

| **Environment variable** | **Description** | **Notes** |
|:---:|---|---|
| `BROWSER_TRUSTED` | Skip Chromium Sandbox | Useful for containerized environments, default: `false` |
| `DESKTOP_NOTIFICATIONS` | Display desktop notifications using [node-notifier](https://www.npmjs.com/package/node-notifier); optional | Default: `false` |
| `DISCORD_NOTIFY_GROUP` | Discord group you would like to notify; optional | E.g.: `<@2834729847239842>` |
| `DISCORD_WEB_HOOK` | Discord Web Hook URL | |
| `DESKTOP_NOTIFICATIONS` | Display desktop notifications using [node-notifier](https://www.npmjs.com/package/node-notifier) | Default: `false` |
| `DISCORD_NOTIFY_GROUP` | Discord group you would like to notify | Can be comma separated, use role ID, E.g.: `<@2834729847239842>` |
| `DISCORD_WEB_HOOK` | Discord Web Hook URL | Can be comma separated, use whole webhook URL |
| `EMAIL_USERNAME` | Gmail address | E.g.: `jensen.robbed.us@gmail.com` |
| `EMAIL_PASSWORD` | Gmail password | See below if you have MFA |
| `HEADLESS` | Puppeteer to run headless or not | Debugging related, default: `true` |
Expand Down
81 changes: 48 additions & 33 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,41 @@ import path from 'path';

config({path: path.resolve(__dirname, '../.env')});

function envOrArray(environment: string | undefined, array?: string[]): string[] {
return environment ? environment.split(',') : (array ?? []);
}

function envOrBoolean(environment: string | undefined, boolean?: boolean): boolean {
return environment ? environment === 'true' : (boolean ?? true);
}

function envOrString(environment: string | undefined, string?: string): string {
return environment ? environment : (string ?? '');
}

function envOrNumber(environment: string | undefined, number?: number): number {
return Number(environment ?? (number ?? 0));
}

const browser = {
isHeadless: process.env.HEADLESS ? process.env.HEADLESS === 'true' : true,
isTrusted: process.env.BROWSER_TRUSTED ? process.env.BROWSER_TRUSTED === 'true' : false,
maxSleep: Number(process.env.PAGE_SLEEP_MAX ?? 10000),
minSleep: Number(process.env.PAGE_SLEEP_MIN ?? 5000),
open: process.env.OPEN_BROWSER ? process.env.OPEN_BROWSER === 'true' : true
isHeadless: envOrBoolean(process.env.HEADLESS),
isTrusted: envOrBoolean(process.env.BROWSER_TRUSTED, false),
maxSleep: envOrNumber(process.env.PAGE_SLEEP_MAX, 10000),
minSleep: envOrNumber(process.env.PAGE_SLEEP_MIN, 5000),
open: envOrBoolean(process.env.OPEN_BROWSER)
};

const logLevel = process.env.LOG_LEVEL ?? 'info';

const notifications = {
desktop: process.env.DESKTOP_NOTIFICATIONS === 'true',
discord: {
notifyGroup: process.env.DISCORD_NOTIFY_GROUP ?? '',
webHookUrl: process.env.DISCORD_WEB_HOOK ?? ''
notifyGroup: envOrArray(process.env.DISCORD_NOTIFY_GROUP),
webHookUrl: envOrArray(process.env.DISCORD_WEB_HOOK)
},
email: {
password: process.env.EMAIL_PASSWORD ?? '',
username: process.env.EMAIL_USERNAME ?? ''
password: envOrString(process.env.EMAIL_PASSWORD),
username: envOrString(process.env.EMAIL_USERNAME)
},
phone: {
availableCarriers: new Map([
Expand All @@ -36,47 +52,46 @@ const notifications = {
['tmobile', 'tmomail.net'],
['verizon', 'vtext.com']
]),
carrier: process.env.PHONE_CARRIER ?? '',
number: process.env.PHONE_NUMBER ?? ''
carrier: envOrString(process.env.PHONE_CARRIER),
number: envOrString(process.env.PHONE_NUMBER)
},
playSound: process.env.PLAY_SOUND ?? '',
pushBulletApiKey: process.env.PUSHBULLET ?? '',
playSound: envOrString(process.env.PLAY_SOUND),
pushBulletApiKey: envOrString(process.env.PUSHBULLET),
pushover: {
token: process.env.PUSHOVER_TOKEN ?? '',
username: process.env.PUSHOVER_USER ?? ''
token: envOrString(process.env.PUSHOVER_TOKEN),
username: envOrString(process.env.PUSHOVER_USER)
},
slack: {
channel: process.env.SLACK_CHANNEL ?? '',
token: process.env.SLACK_TOKEN ?? ''
channel: envOrString(process.env.SLACK_CHANNEL),
token: envOrString(process.env.SLACK_TOKEN)
},
telegram: {
accessToken: process.env.TELEGRAM_ACCESS_TOKEN ?? '',
chatId: process.env.TELEGRAM_CHAT_ID ?? ''
accessToken: envOrString(process.env.TELEGRAM_ACCESS_TOKEN),
chatId: envOrString(process.env.TELEGRAM_CHAT_ID)
},
test: process.env.NOTIFICATION_TEST === 'true',
twitter: {
accessTokenKey: process.env.TWITTER_ACCESS_TOKEN_KEY ?? '',
accessTokenSecret: process.env.TWITTER_ACCESS_TOKEN_SECRET ?? '',
consumerKey: process.env.TWITTER_CONSUMER_KEY ?? '',
consumerSecret: process.env.TWITTER_CONSUMER_SECRET ?? '',
tweetTags: process.env.TWITTER_TWEET_TAGS ?? ''
accessTokenKey: envOrString(process.env.TWITTER_ACCESS_TOKEN_KEY),
accessTokenSecret: envOrString(process.env.TWITTER_ACCESS_TOKEN_SECRET),
consumerKey: envOrString(process.env.TWITTER_CONSUMER_KEY),
consumerSecret: envOrString(process.env.TWITTER_CONSUMER_SECRET),
tweetTags: envOrString(process.env.TWITTER_TWEET_TAGS)
}
};

const page = {
capture: process.env.SCREENSHOT ? process.env.SCREENSHOT === 'true' : 'true',
height: 1080,
inStockWaitTime: Number(process.env.IN_STOCK_WAIT_TIME ?? 0),
navigationTimeout: Number(process.env.PAGE_TIMEOUT ?? 30000),
userAgent: process.env.USER_AGENT ?? 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
inStockWaitTime: envOrNumber(process.env.IN_STOCK_WAIT_TIME),
navigationTimeout: envOrNumber(process.env.PAGE_TIMEOUT, 30000),
screenshot: envOrBoolean(process.env.SCREENSHOT),
userAgent: envOrString(process.env.USER_AGENT, 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'),
width: 1920
};

const store = {
country: process.env.COUNTRY ?? 'usa',
showOnlyBrands: process.env.SHOW_ONLY_BRANDS ? process.env.SHOW_ONLY_BRANDS.split(',') : [],
showOnlySeries: process.env.SHOW_ONLY_SERIES ? process.env.SHOW_ONLY_SERIES.split(',') : ['3070', '3080', '3090'],
stores: process.env.STORES ? process.env.STORES.split(',') : ['nvidia']
country: envOrString(process.env.COUNTRY, 'usa'),
showOnlyBrands: envOrArray(process.env.SHOW_ONLY_BRANDS),
showOnlySeries: envOrArray(process.env.SHOW_ONLY_SERIES, ['3070', '3080', '3090']),
stores: envOrArray(process.env.STORES, ['nvidia'])
};

export const Config = {
Expand Down
12 changes: 9 additions & 3 deletions src/notification/discord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {MessageBuilder, Webhook} from 'discord-webhook-node';
import {Config} from '../config';
import {Logger} from '../logger';

const hook = new Webhook(Config.notifications.discord.webHookUrl);
const hooks = Config.notifications.discord.webHookUrl;
const notifyGroup = Config.notifications.discord.notifyGroup;

export function sendDiscordMessage(link: Link, store: Store) {
Expand All @@ -17,12 +17,18 @@ export function sendDiscordMessage(link: Link, store: Store) {
embed.addField('Model', link.model, true);

if (notifyGroup) {
embed.setText(notifyGroup);
embed.setText(notifyGroup.join(' '));
}

embed.setColor(0x76B900);
embed.setTimestamp();
await hook.send(embed);

const promises = [];
for (const hook of hooks) {
promises.push(new Webhook(hook).send(embed));
}

await Promise.all(promises);

Logger.info('✔ discord message sent');
} catch (error) {
Expand Down
3 changes: 2 additions & 1 deletion src/store/lookup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ function filterSeries(series: Link['series']) {
* Responsible for looking up information about a each product within
* a `Store`. It's important that we ignore `no-await-in-loop` here
* because we don't want to get rate limited within the same store.
*
* @param browser Puppeteer browser.
* @param store Vendor of graphics cards.
*/
Expand Down Expand Up @@ -94,7 +95,7 @@ async function lookupCard(browser: Browser, store: Store, page: Page, link: Link
}, 1000 * Config.page.inStockWaitTime);
}

if (Config.page.capture) {
if (Config.page.screenshot) {
Logger.debug('ℹ saving screenshot');

link.screenshot = `success-${Date.now()}.png`;
Expand Down

0 comments on commit 1cfccb9

Please sign in to comment.