From a3fc07daf0a3f33f18e03d4cfc13d3477a9c4fa0 Mon Sep 17 00:00:00 2001 From: bmalaski <5288648+bmalaski@users.noreply.github.com> Date: Sun, 20 Sep 2020 12:36:05 -0400 Subject: [PATCH] feat(notification): discord integration (#82) Co-authored-by: Jef LeCompte --- .env-example | 2 ++ README.md | 4 ++++ package-lock.json | 23 +++++++++++++++++++++++ package.json | 3 ++- src/config.ts | 4 ++++ src/index.ts | 2 +- src/notification/discord.ts | 30 ++++++++++++++++++++++++++++++ src/notification/notification.ts | 8 +++++++- src/store/lookup.ts | 2 +- src/store/model/store.ts | 2 +- 10 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 src/notification/discord.ts diff --git a/.env-example b/.env-example index a542141c7b..991a917f2d 100644 --- a/.env-example +++ b/.env-example @@ -18,3 +18,5 @@ STORES="bestbuy,bandh,nvidia" SCREENSHOT="true" TELEGRAM_ACCESS_TOKEN="" TELEGRAM_CHAT_ID="1234" +DISCORD_WEB_HOOK="https://discordapp.com/api/webhooks/23123123123/5dfsdfh3h2j5hdfhsdfsdhj55jf" +DISCORD_NOTIFY_GROUP="@here" diff --git a/README.md b/README.md index b21e6a4ac3..e957fa435b 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,11 @@ To customize `nvidia-snatcher`, make a copy of `.env-example` as `.env` and make Here is a list of variables that you can use to customize your newly copied `.env` file: + | **Environment variable** | **Description** | **Notes** | |:---:|---|---| +| `DISCORD_WEB_HOOK` | Discord Web Hook URL | +| `DISCORD_NOTIFY_GROUP` | Discord group you would like to notify; optional | E.g.: @here | | `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` | @@ -82,6 +85,7 @@ Here is a list of variables that you can use to customize your newly copied `.en | `SCREENSHOT` | Capture screenshot of page if a card is found | Default: `true` | | `TELEGRAM_ACCESS_TOKEN` | Telegram access token | | `TELEGRAM_CHAT_ID` | Telegram chat ID | + > :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. #### Supported stores diff --git a/package-lock.json b/package-lock.json index a08070da0f..ac213d9570 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1745,6 +1745,29 @@ } } }, + "discord-webhook-node": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/discord-webhook-node/-/discord-webhook-node-1.1.8.tgz", + "integrity": "sha512-3u0rrwywwYGc6HrgYirN/9gkBYqmdpvReyQjapoXARAHi0P0fIyf3W5tS5i3U3cc7e44E+e7dIHYUeec7yWaug==", + "dev": true, + "requires": { + "form-data": "^3.0.0", + "node-fetch": "^2.6.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", + "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", diff --git a/package.json b/package.json index f5b4f78b96..7e234b6595 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "play-sound": "^1.1.3", "rimraf": "^3.0.2", "typescript": "^4.0.2", - "xo": "^0.33.1" + "xo": "^0.33.1", + "discord-webhook-node": "^1.1.8" } } diff --git a/src/config.ts b/src/config.ts index f612a2f5a3..df6a238a64 100644 --- a/src/config.ts +++ b/src/config.ts @@ -42,6 +42,10 @@ const notifications = { accessToken: process.env.TELEGRAM_ACCESS_TOKEN ?? '', chatId: process.env.TELEGRAM_CHAT_ID ?? '' }, + discord: { + webHookUrl: process.env.DISCORD_WEB_HOOK ?? '', + notifyGroup: process.env.DISCORD_NOTIFY_GROUP ?? '' + }, test: process.env.NOTIFICATION_TEST === 'true' }; diff --git a/src/index.ts b/src/index.ts index 4036335591..f2a4efd4e4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -55,7 +55,7 @@ async function main() { * Send test email. */ if (Config.notifications.test) { - sendNotification('test'); + sendNotification('http://test.com/', {brand: 'THE BEST BRAND', model: 'VENTUS', oosLabels: [], url: '', cartUrl: ''}); } /** diff --git a/src/notification/discord.ts b/src/notification/discord.ts new file mode 100644 index 0000000000..8d6e8d849a --- /dev/null +++ b/src/notification/discord.ts @@ -0,0 +1,30 @@ +import {Webhook, MessageBuilder} from 'discord-webhook-node'; +import {Config} from '../config'; +import {Logger} from '../logger'; +import {Link} from '../store/model'; + +const hook = new Webhook(Config.notifications.discord.webHookUrl); +const notifyGroup = Config.notifications.discord.notifyGroup; + +export function sendDiscordMessage(cartUrl: string, link: Link) { + (async () => { + try { + const embed = new MessageBuilder(); + embed.setTitle('Stock Notification'); + embed.addField('URL', cartUrl, true); + embed.addField('Brand', link.brand, true); + embed.addField('Model', link.model, true); + + if (notifyGroup !== '') { + embed.addField('Attention', notifyGroup, true); + } + + embed.setColor(0x76B900); + embed.setTimestamp(); + await hook.send(embed); + Logger.info(`✔ discord message sent: ${cartUrl}`); + } catch (error) { + Logger.error(error); + } + })(); +} diff --git a/src/notification/notification.ts b/src/notification/notification.ts index 82a4c4f714..9d74890544 100644 --- a/src/notification/notification.ts +++ b/src/notification/notification.ts @@ -5,10 +5,12 @@ import {playSound} from './sound'; import {sendSlackMessage} from './slack'; import {sendPushoverNotification} from './pushover'; import {sendTelegramMessage} from './telegram'; +import {sendDiscordMessage} from './discord'; +import {Link} from '../store/model'; const notifications = Config.notifications; -export function sendNotification(cartUrl: string) { +export function sendNotification(cartUrl: string, link: Link) { if (notifications.email.username && notifications.email.password) { sendEmail(cartUrl); } @@ -21,6 +23,10 @@ export function sendNotification(cartUrl: string) { sendTelegramMessage(cartUrl); } + if (notifications.discord.webHookUrl) { + sendDiscordMessage(cartUrl, link); + } + if (notifications.phone.number) { const carrier = notifications.phone.carrier.toLowerCase(); if (carrier && notifications.phone.availableCarriers.has(carrier)) { diff --git a/src/store/lookup.ts b/src/store/lookup.ts index 38fccde0dd..3d7530e1a2 100644 --- a/src/store/lookup.ts +++ b/src/store/lookup.ts @@ -74,7 +74,7 @@ export async function lookup(browser: Browser, store: Store) { await open(givenUrl); } - sendNotification(givenUrl); + sendNotification(givenUrl, link); } await page.close(); diff --git a/src/store/model/store.ts b/src/store/model/store.ts index d018d4db99..9ee79029ab 100644 --- a/src/store/model/store.ts +++ b/src/store/model/store.ts @@ -1,4 +1,4 @@ -interface Link { +export interface Link { cartUrl?: string; brand: string; model: string;