diff --git a/.env.example b/.env.example index 2151df7..8489f8b 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,8 @@ EMAIL_USERNAME="youremail@gmail.com" EMAIL_PASSWORD="secretpassword" -EMAIL_TEST="true" -NOTIFICATION_METHODS="email" +NOTIFICATION_TEST="false" +PAGE_TIMEOUT=30000 +RATE_LIMIT_TIMEOUT=5000 SLACK_CHANNEL="SlackChannelName" SLACK_TOKEN="slack-token" STORES="bestbuy,bandh,nvidia" diff --git a/README.md b/README.md index 16cc695..9913799 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,14 @@ First, you're going to need to copy the `.env.example` to `.env`. The current op | **Environment variable** | **Description** | |:---:|:---:| -| `EMAIL_USERNAME` | Gmail address; e.g. `jensen.robbed.us@gmail.com` | -| `EMAIL_PASSWORD` | Gmail password; see below if you have MFA | +| `EMAIL_USERNAME` | Gmail address (e.g., `jensen.robbed.us@gmail.com`); optional | +| `EMAIL_PASSWORD` | Gmail password; see below if you have MFA; optional | +| `NOTIFICATION_TEST` | Test all the notifications configured; optional, default: `false` | +| `PAGE_TIMEOUT` | Navigation Timeout in milliseconds (`0` for infinite); optional, default: `30000` | +| `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_TOKEN` | Slack API token; optional | `STORES` | List of [stores](#Supported-stores) you want to be scraped; optional, default: `nvidia` | -| `PAGE_TIMEOUT` | Navigation Timeout in milliseconds (0 for infinite, 60000 for 1 minute); optional, default: `0` | > :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. @@ -76,11 +80,11 @@ First, you're going to need to copy the `.env.example` to `.env`. The current op | **Store name** | **Store name environment variable** | |:---:|:---:| | Best Buy | `bestbuy`| +| Amazon | `amazon`| | B&H | `bandh`| | EVGA | `evga`| | Newegg | `newegg`| | Nvidia | `nvidia`| -| Amazon | `amazon`| > :point_right: Look at [`.env.example`](.env.example) for an example for `.env`. diff --git a/src/config.ts b/src/config.ts index f94301d..97bb342 100644 --- a/src/config.ts +++ b/src/config.ts @@ -3,38 +3,32 @@ import {config} from 'dotenv'; config({path: resolve(__dirname, '../.env')}); -const email = { - username: process.env.EMAIL_USERNAME, - password: process.env.EMAIL_PASSWORD, - test: process.env.EMAIL_TEST ?? 'false' -}; - const notifications = { - email: email.username && email.password + email: { + username: process.env.EMAIL_USERNAME ?? '', + password: process.env.EMAIL_PASSWORD ?? '' + }, + slack: { + channel: process.env.SLACK_CHANNEL ?? '', + token: process.env.SLACK_TOKEN ?? '' + }, + test: process.env.NOTIFICATION_TEST ?? 'false' }; const page = { height: 1920, + 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', - width: 1080, - navigationTimeout: Number(process.env.PAGE_TIMEOUT) ?? 30000 + width: 1080 }; +const rateLimitTimeout = Number(process.env.RATE_LIMIT_TIMEOUT) ?? 5000; + const stores = process.env.STORES ?? 'nvidia'; -const notificationMethods = process.env.NOTIFICATION_METHODS ?? 'email'; - -const slack = { - channel: process.env.SLACK_CHANNEL, - token: process.env.SLACK_TOKEN -}; - export const Config = { - email, notifications, + rateLimitTimeout, page, - rateLimitTimeout: 5000, - stores, - slack, - notificationMethods + stores }; diff --git a/src/index.ts b/src/index.ts index 2cd3f15..9c80232 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,7 @@ import {Logger} from './logger'; /** * Send test email. */ -if (Config.email.test === 'true') { +if (Config.notifications.test === 'true') { sendNotification('test'); } @@ -25,7 +25,7 @@ async function main() { await Promise.all(results); Logger.info('↗ trying stores again'); - setTimeout(main, Config.rateLimitTimeout); + setTimeout(main, Config.page.rateLimitTimeout); } /** diff --git a/src/notification/index.ts b/src/notification/index.ts index 7bfc41e..1598bb9 100644 --- a/src/notification/index.ts +++ b/src/notification/index.ts @@ -3,11 +3,11 @@ import sendEmail from './email'; import sendSlaskMessage from './slack'; export default function sendNotification(cartUrl: string) { - if (Config.notificationMethods.toLocaleLowerCase().includes('email')) { + if (Config.notifications.email.username && Config.notifications.email.password) { sendEmail(cartUrl); } - if (Config.notificationMethods.toLocaleLowerCase().includes('slack')) { + if (Config.notifications.slack.channel && Config.notifications.slack.token) { sendSlaskMessage(cartUrl); } } diff --git a/src/notification/slack.ts b/src/notification/slack.ts index d9c3252..a4d8bfa 100644 --- a/src/notification/slack.ts +++ b/src/notification/slack.ts @@ -2,8 +2,8 @@ import {WebClient} from '@slack/web-api'; import {Config} from '../config'; import {Logger} from '../logger'; -const channel = Config.slack.channel ?? ''; -const token = Config.slack.token ?? ''; +const channel = Config.notifications.slack.channel; +const token = Config.notifications.slack.token; const web = new WebClient(token); export default function sendSlackMessage(text: string) {