From 5a3636bcb639bb33bc586af96264f5df2f3a8307 Mon Sep 17 00:00:00 2001 From: Alexandru Gutu Date: Fri, 18 Sep 2020 19:54:59 -0400 Subject: [PATCH] feat: sms notification for usa carriers (#40) Co-authored-by: Jef LeCompte --- .env.example | 6 +++-- README.md | 2 ++ src/config.ts | 5 ++++ src/notification/index.ts | 7 ++++++ src/notification/sms.ts | 49 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/notification/sms.ts diff --git a/.env.example b/.env.example index 8489f8b281..3ff82b9b8b 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,10 @@ EMAIL_USERNAME="youremail@gmail.com" EMAIL_PASSWORD="secretpassword" NOTIFICATION_TEST="false" -PAGE_TIMEOUT=30000 -RATE_LIMIT_TIMEOUT=5000 +PAGE_TIMEOUT="30000" +RATE_LIMIT_TIMEOUT="5000" SLACK_CHANNEL="SlackChannelName" SLACK_TOKEN="slack-token" STORES="bestbuy,bandh,nvidia" +PHONE_NUMBER="1234567890" +CARRIER="tmobile" \ No newline at end of file diff --git a/README.md b/README.md index 9913799f24..bc120bc184 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ First, you're going to need to copy the `.env.example` to `.env`. The current op | `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` | +| `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 | | `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 diff --git a/src/config.ts b/src/config.ts index 97bb342090..7aba1d3e5a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -8,6 +8,11 @@ const notifications = { username: process.env.EMAIL_USERNAME ?? '', password: process.env.EMAIL_PASSWORD ?? '' }, + phone: { + availableCarriers: ['sprint', 'verizon', 'tmobile', 'att'], + carrier: process.env.PHONE_CARRIER, + number: process.env.PHONE_NUMBER + }, slack: { channel: process.env.SLACK_CHANNEL ?? '', token: process.env.SLACK_TOKEN ?? '' diff --git a/src/notification/index.ts b/src/notification/index.ts index 1598bb9710..764c4dbde2 100644 --- a/src/notification/index.ts +++ b/src/notification/index.ts @@ -1,6 +1,7 @@ import {Config} from '../config'; import sendEmail from './email'; import sendSlaskMessage from './slack'; +import sendSMS from './sms'; export default function sendNotification(cartUrl: string) { if (Config.notifications.email.username && Config.notifications.email.password) { @@ -10,4 +11,10 @@ export default function sendNotification(cartUrl: string) { if (Config.notifications.slack.channel && Config.notifications.slack.token) { sendSlaskMessage(cartUrl); } + + if (Config.notifications.phone.number && Config.notifications.phone.carrier) { + if (Config.notifications.availableCarriers.includes(Config.notifications.phone.carrier.toLowerCase())) { + sendSMS(cartUrl); + } + } } diff --git a/src/notification/sms.ts b/src/notification/sms.ts new file mode 100644 index 0000000000..797a73935b --- /dev/null +++ b/src/notification/sms.ts @@ -0,0 +1,49 @@ +import nodemailer from 'nodemailer'; +import Mail from 'nodemailer/lib/mailer'; +import {Config} from '../config'; +import {Logger} from '../logger'; + +const subject = 'NVIDIA - BUY NOW'; + +enum carrierAddress { + sprint = 'messaging.sprintpcs.com', + verizon = 'vtext.com', + tmobile = 'tmomail.net', + att = 'txt.att.net' +} + +const transporter = nodemailer.createTransport({ + service: 'gmail', + auth: { + user: Config.email.username, + pass: Config.email.password + } +}); + +const mailOptions: Mail.Options = { + from: Config.email.username, + to: generateAddress(), + subject +}; + +export default function sendSMS(text: string) { + mailOptions.text = text; + + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + Logger.error(error); + } else { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + Logger.info(`✔ email sent: ${info.response}`); + } + }); +} + +function generateAddress() { + for (const carrier of Object.keys(carrierAddress)) { + if (Config.phone.carrier && carrier === Config.phone.carrier.toLowerCase()) { + // @ts-expect-error + return [Config.phone.number, carrierAddress[carrier]].join('@'); + } + } +}