chore: refactor config and fix audits (#406)

This commit is contained in:
Jef LeCompte
2020-10-03 13:15:39 -04:00
committed by GitHub
parent f006a8595b
commit 8098a31092
28 changed files with 1765 additions and 403 deletions
+15 -9
View File
@@ -1,14 +1,20 @@
import {Link, Store} from '../store/model';
import {Logger, Print} from '../logger';
import {Print, logger} from '../logger';
import {config} from '../config';
import notifier from 'node-notifier';
export function sendDesktopNotification(link: Link, store: Store) {
(async () => {
notifier.notify({
message: link.cartUrl ? link.cartUrl : link.url,
title: Print.inStock(link, store)
});
const desktop = config.notifications.desktop;
Logger.info('✔ desktop notification sent');
})();
export function sendDesktopNotification(link: Link, store: Store) {
if (desktop) {
logger.debug('↗ sending desktop notification');
(async () => {
notifier.notify({
message: link.cartUrl ? link.cartUrl : link.url,
title: Print.inStock(link, store)
});
logger.info('✔ desktop notification sent');
})();
}
}
+35 -30
View File
@@ -1,38 +1,43 @@
import {Link, Store} from '../store/model';
import {MessageBuilder, Webhook} from 'discord-webhook-node';
import {Config} from '../config';
import {Logger} from '../logger';
import {config} from '../config';
import {logger} from '../logger';
const hooks = Config.notifications.discord.webHookUrl;
const notifyGroup = Config.notifications.discord.notifyGroup;
const discord = config.notifications.discord;
const hooks = discord.webHookUrl;
const notifyGroup = discord.notifyGroup;
export function sendDiscordMessage(link: Link, store: Store) {
(async () => {
try {
const embed = new MessageBuilder();
embed.setTitle('Stock Notification');
embed.addField('URL', link.cartUrl ? link.cartUrl : link.url, true);
embed.addField('Store', store.name, true);
embed.addField('Brand', link.brand, true);
embed.addField('Model', link.model, true);
if (discord.webHookUrl.length > 0) {
logger.debug('↗ sending discord message');
if (notifyGroup) {
embed.setText(notifyGroup.join(' '));
(async () => {
try {
const embed = new MessageBuilder();
embed.setTitle('Stock Notification');
embed.addField('URL', link.cartUrl ? link.cartUrl : link.url, true);
embed.addField('Store', store.name, true);
embed.addField('Brand', link.brand, true);
embed.addField('Model', link.model, true);
if (notifyGroup) {
embed.setText(notifyGroup.join(' '));
}
embed.setColor(0x76B900);
embed.setTimestamp();
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) {
logger.error('✖ couldn\'t send discord message', error);
}
embed.setColor(0x76B900);
embed.setTimestamp();
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) {
Logger.error('✖ couldn\'t send discord message', error);
}
})();
})();
}
}
+26 -22
View File
@@ -1,10 +1,10 @@
import {Link, Store} from '../store/model';
import {Logger, Print} from '../logger';
import {Config} from '../config';
import {Print, logger} from '../logger';
import Mail from 'nodemailer/lib/mailer';
import {config} from '../config';
import nodemailer from 'nodemailer';
const email = Config.notifications.email;
const email = config.notifications.email;
const transporter = nodemailer.createTransport({
auth: {
@@ -15,24 +15,28 @@ const transporter = nodemailer.createTransport({
});
export function sendEmail(link: Link, store: Store) {
const mailOptions: Mail.Options = {
attachments: link.screenshot ? [
{
filename: link.screenshot,
path: `./${link.screenshot}`
}
] : undefined,
from: email.username,
subject: Print.inStock(link, store),
text: link.cartUrl ? link.cartUrl : link.url,
to: email.to
};
if (email.username && email.password) {
logger.debug('↗ sending email');
transporter.sendMail(mailOptions, error => {
if (error) {
Logger.error('✖ couldn\'t send email', error);
} else {
Logger.info('✔ email sent');
}
});
const mailOptions: Mail.Options = {
attachments: link.screenshot ? [
{
filename: link.screenshot,
path: `./${link.screenshot}`
}
] : undefined,
from: email.username,
subject: Print.inStock(link, store),
text: link.cartUrl ? link.cartUrl : link.url,
to: email.to
};
transporter.sendMail(mailOptions, error => {
if (error) {
logger.error('✖ couldn\'t send email', error);
} else {
logger.info('✔ email sent');
}
});
}
}
+12 -67
View File
@@ -1,11 +1,9 @@
import {Link, Store} from '../store/model';
import {Config} from '../config';
import {Logger} from '../logger';
import {playSound} from './sound';
import {sendDesktopNotification} from './desktop';
import {sendDiscordMessage} from './discord';
import {sendEmail} from './email';
import {sendPushBulletNotification} from './pushbullet';
import {sendPushbulletNotification} from './pushbullet';
import {sendPushoverNotification} from './pushover';
import {sendSMS} from './sms';
import {sendSlackMessage} from './slack';
@@ -13,69 +11,16 @@ import {sendTelegramMessage} from './telegram';
import {sendTweet} from './twitter';
import {sendTwilioMessage} from './twilio';
const notifications = Config.notifications;
export function sendNotification(link: Link, store: Store) {
if (notifications.email.username && notifications.email.password) {
Logger.debug('↗ sending email');
sendEmail(link, store);
}
if (notifications.phone.number) {
Logger.debug('↗ sending sms');
const carrier = notifications.phone.carrier;
if (carrier && notifications.phone.availableCarriers.has(carrier)) {
sendSMS(link, store);
}
}
if (notifications.playSound) {
Logger.debug('↗ playing sound');
playSound();
}
if (notifications.desktop) {
Logger.debug('↗ sending desktop notification');
sendDesktopNotification(link, store);
}
if (notifications.discord.webHookUrl.length > 0) {
Logger.debug('↗ sending discord message');
sendDiscordMessage(link, store);
}
if (notifications.slack.channel && notifications.slack.token) {
Logger.debug('↗ sending slack message');
sendSlackMessage(link, store);
}
if (notifications.telegram.accessToken && notifications.telegram.chatId) {
Logger.debug('↗ sending telegram message');
sendTelegramMessage(link, store);
}
if (notifications.twilio.accountSid && notifications.twilio.authToken) {
Logger.debug('↗ sending twilio message');
sendTwilioMessage(link, store);
}
if (notifications.pushBulletApiKey) {
Logger.debug('↗ sending pushbullet message');
sendPushBulletNotification(link, store);
}
if (notifications.pushover.token && notifications.pushover.username) {
Logger.debug('↗ sending pushover message');
sendPushoverNotification(link, store);
}
if (
notifications.twitter.accessTokenKey &&
notifications.twitter.accessTokenSecret &&
notifications.twitter.consumerKey &&
notifications.twitter.consumerSecret
) {
Logger.debug('↗ sending twitter message');
sendTweet(link, store);
}
sendEmail(link, store);
sendSMS(link, store);
playSound();
sendDesktopNotification(link, store);
sendDiscordMessage(link, store);
sendSlackMessage(link, store);
sendTelegramMessage(link, store);
sendTwilioMessage(link, store);
sendPushbulletNotification(link, store);
sendPushoverNotification(link, store);
sendTweet(link, store);
}
+21 -17
View File
@@ -1,22 +1,26 @@
import {Link, Store} from '../store/model';
import {Logger, Print} from '../logger';
import {Config} from '../config';
import PushBullet from 'pushbullet';
import {Print, logger} from '../logger';
import PushBullet from '@hijef/pushbullet';
import {config} from '../config';
const pushBulletApiKey = Config.notifications.pushBulletApiKey;
const pushbullet = config.notifications.pushbullet;
export function sendPushBulletNotification(link: Link, store: Store) {
const pusher = new PushBullet(pushBulletApiKey);
export function sendPushbulletNotification(link: Link, store: Store) {
if (pushbullet) {
logger.debug('↗ sending pushbullet message');
pusher.note(
{},
Print.inStock(link, store),
link.cartUrl ? link.cartUrl : link.url,
(error: Error) => {
if (error) {
Logger.error('✖ couldn\'t send pushbullet message', error);
} else {
Logger.info(' pushbullet message sent');
}
});
const pusher = new PushBullet(pushbullet);
pusher.note(
{},
Print.inStock(link, store),
link.cartUrl ? link.cartUrl : link.url,
(error: Error) => {
if (error) {
logger.error('✖ couldn\'t send pushbullet message', error);
} else {
logger.info('✔ pushbullet message sent');
}
});
}
}
+19 -15
View File
@@ -1,26 +1,30 @@
import {Link, Store} from '../store/model';
import {Logger, Print} from '../logger';
import {Config} from '../config';
import {Print, logger} from '../logger';
import Push from 'pushover-notifications';
import {config} from '../config';
const pushover = Config.notifications.pushover;
const pushover = config.notifications.pushover;
const push = new Push({
token: pushover.token,
user: pushover.username
});
export function sendPushoverNotification(link: Link, store: Store) {
const message = {
message: link.cartUrl ? link.cartUrl : link.url,
priority: pushover.priority,
title: Print.inStock(link, store)
};
if (pushover.token && pushover.username) {
logger.debug('↗ sending pushover message');
push.send(message, (error: Error) => {
if (error) {
Logger.error('✖ couldn\'t send pushover message', error);
} else {
Logger.info('✔ pushover message sent');
}
});
const message = {
message: link.cartUrl ? link.cartUrl : link.url,
priority: pushover.priority,
title: Print.inStock(link, store)
};
push.send(message, (error: Error) => {
if (error) {
logger.error('✖ couldn\'t send pushover message', error);
} else {
logger.info('✔ pushover message sent');
}
});
}
}
+25 -20
View File
@@ -1,30 +1,35 @@
import {Link, Store} from '../store/model';
import {Logger, Print} from '../logger';
import {Config} from '../config';
import {Print, logger} from '../logger';
import {WebClient} from '@slack/web-api';
import {config} from '../config';
const channel = Config.notifications.slack.channel;
const token = Config.notifications.slack.token;
const slack = config.notifications.slack;
const channel = slack.channel;
const token = slack.token;
const web = new WebClient(token);
export function sendSlackMessage(link: Link, store: Store) {
(async () => {
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
if (slack.channel && slack.token) {
logger.debug('↗ sending slack message');
try {
const result = await web.chat.postMessage({
channel,
text: `${Print.inStock(link, store)}\n${givenUrl}`
});
(async () => {
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
if (!result.ok) {
Logger.error('✖ couldn\'t send slack message', result);
return;
try {
const result = await web.chat.postMessage({
channel,
text: `${Print.inStock(link, store)}\n${givenUrl}`
});
if (!result.ok) {
logger.error('✖ couldn\'t send slack message', result);
return;
}
logger.info('✔ slack message sent');
} catch (error) {
logger.error('✖ couldn\'t send slack message', error);
}
Logger.info('✔ slack message sent');
} catch (error) {
Logger.error('✖ couldn\'t send slack message', error);
}
})();
})();
}
}
+31 -24
View File
@@ -1,14 +1,14 @@
import {Link, Store} from '../store/model';
import {Logger, Print} from '../logger';
import {Config} from '../config';
import {Print, logger} from '../logger';
import Mail from 'nodemailer/lib/mailer';
import {config} from '../config';
import nodemailer from 'nodemailer';
if (Config.notifications.phone.number && !Config.notifications.email.username) {
Logger.warn('✖ in order to recieve sms alerts, email notifications must also be configured');
if (config.notifications.phone.number && !config.notifications.email.username) {
logger.warn('✖ in order to recieve sms alerts, email notifications must also be configured');
}
const [email, phone] = [Config.notifications.email, Config.notifications.phone];
const [email, phone] = [config.notifications.email, config.notifications.phone];
const transporter = nodemailer.createTransport({
auth: {
@@ -19,26 +19,33 @@ const transporter = nodemailer.createTransport({
});
export function sendSMS(link: Link, store: Store) {
const mailOptions: Mail.Options = {
attachments: link.screenshot ? [
{
filename: link.screenshot,
path: `./${link.screenshot}`
}
] : undefined,
from: email.username,
subject: Print.inStock(link, store, false, true),
text: link.cartUrl ? link.cartUrl : link.url,
to: generateAddress()
};
if (phone.number) {
logger.debug('↗ sending sms');
const carrier = phone.carrier;
transporter.sendMail(mailOptions, error => {
if (error) {
Logger.error('✖ couldn\'t send sms', error);
} else {
Logger.info('✔ sms sent');
if (carrier && phone.availableCarriers.has(carrier)) {
const mailOptions: Mail.Options = {
attachments: link.screenshot ? [
{
filename: link.screenshot,
path: `./${link.screenshot}`
}
] : undefined,
from: email.username,
subject: Print.inStock(link, store, false, true),
text: link.cartUrl ? link.cartUrl : link.url,
to: generateAddress()
};
transporter.sendMail(mailOptions, error => {
if (error) {
logger.error('✖ couldn\'t send sms', error);
} else {
logger.info('✔ sms sent');
}
});
}
});
}
}
function generateAddress() {
@@ -48,5 +55,5 @@ function generateAddress() {
return [phone.number, phone.availableCarriers.get(carrier)].join('@');
}
Logger.error('✖ unknown carrier', carrier);
logger.error('✖ unknown carrier', carrier);
}
+13 -11
View File
@@ -1,35 +1,37 @@
import {Config} from '../config';
import {Logger} from '../logger';
import {config} from '../config';
import fs from 'fs';
import {logger} from '../logger';
import playerLib from 'play-sound';
let player: any;
if (Config.notifications.playSound) {
if (config.notifications.playSound) {
player = playerLib();
if (player.player === null) {
Logger.warn('✖ couldn\'t find sound player');
logger.warn('✖ couldn\'t find sound player');
} else {
const playerName: string = player.player;
Logger.info(`✔ sound player found: ${playerName}`);
logger.info(`✔ sound player found: ${playerName}`);
}
}
export function playSound() {
if (player.player !== null) {
fs.access(Config.notifications.playSound, fs.constants.F_OK, error => {
if (config.notifications.playSound && player.player !== null) {
logger.debug('↗ playing sound');
fs.access(config.notifications.playSound, fs.constants.F_OK, error => {
if (error) {
Logger.error(`✖ error opening sound file: ${error.message}`);
logger.error(`✖ error opening sound file: ${error.message}`);
return;
}
player.play(Config.notifications.playSound, (error: Error) => {
player.play(config.notifications.playSound, (error: Error) => {
if (error) {
Logger.error('✖ couldn\'t play sound', error);
logger.error('✖ couldn\'t play sound', error);
}
Logger.info('✔ played sound');
logger.info('✔ played sound');
});
});
}
+16 -12
View File
@@ -1,23 +1,27 @@
import {Link, Store} from '../store/model';
import {Logger, Print} from '../logger';
import {Config} from '../config';
import {Print, logger} from '../logger';
import {TelegramClient} from 'messaging-api-telegram';
import {config} from '../config';
const telegram = Config.notifications.telegram;
const telegram = config.notifications.telegram;
const client = new TelegramClient({
accessToken: telegram.accessToken
});
export function sendTelegramMessage(link: Link, store: Store) {
(async () => {
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
if (telegram.accessToken && telegram.chatId) {
logger.debug('↗ sending telegram message');
try {
await client.sendMessage(telegram.chatId, `${Print.inStock(link, store)}\n${givenUrl}`);
Logger.info('✔ telegram message sent');
} catch (error) {
Logger.error('✖ couldn\'t send telegram message', error);
}
})();
(async () => {
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
try {
await client.sendMessage(telegram.chatId, `${Print.inStock(link, store)}\n${givenUrl}`);
logger.info('✔ telegram message sent');
} catch (error) {
logger.error('✖ couldn\'t send telegram message', error);
}
})();
}
}
+27 -19
View File
@@ -1,25 +1,33 @@
import {Link, Store} from '../store/model';
import {Logger, Print} from '../logger';
import {Config} from '../config';
import twilio from 'twilio';
import {Print, logger} from '../logger';
import {Twilio} from 'twilio';
import {config} from '../config';
const config = Config.notifications.twilio;
const twilio = config.notifications.twilio;
let client: Twilio;
if (twilio.accountSid && twilio.authToken) {
client = new Twilio(twilio.accountSid, twilio.authToken);
}
export function sendTwilioMessage(link: Link, store: Store) {
(async () => {
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
const message = `${Print.inStock(link, store)}\n${givenUrl}`;
if (client) {
logger.debug('↗ sending twilio message');
try {
const client = twilio(config.accountSid, config.authToken);
await client.messages.create({
body: message,
from: config.from,
to: config.to
});
Logger.info('✔ twilio message sent');
} catch (error) {
Logger.error('✖ couldn\'t send twilio message', error);
}
})();
(async () => {
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
const message = `${Print.inStock(link, store)}\n${givenUrl}`;
try {
await client.messages.create({
body: message,
from: twilio.from,
to: twilio.to
});
logger.info('✔ twilio message sent');
} catch (error) {
logger.error('✖ couldn\'t send twilio message', error);
}
})();
}
}
+17 -13
View File
@@ -1,9 +1,9 @@
import {Link, Store} from '../store/model';
import {Logger, Print} from '../logger';
import {Config} from '../config';
import {Print, logger} from '../logger';
import Twitter from 'twitter';
import {config} from '../config';
const twitter = Config.notifications.twitter;
const twitter = config.notifications.twitter;
const client = new Twitter({
access_token_key: twitter.accessTokenKey,
@@ -13,17 +13,21 @@ const client = new Twitter({
});
export function sendTweet(link: Link, store: Store) {
let status = `${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`;
if (twitter.accessTokenKey && twitter.accessTokenSecret && twitter.consumerKey && twitter.consumerSecret) {
logger.debug('↗ sending twitter message');
if (twitter.tweetTags) {
status += `\n\n${twitter.tweetTags}`;
}
let status = `${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`;
client.post('statuses/update', {status}, error => {
if (error) {
Logger.error('✖ couldn\'t send twitter notification', error);
} else {
Logger.info('✔ twitter notification sent');
if (twitter.tweetTags) {
status += `\n\n${twitter.tweetTags}`;
}
});
client.post('statuses/update', {status}, error => {
if (error) {
logger.error('✖ couldn\'t send twitter notification', error);
} else {
logger.info('✔ twitter notification sent');
}
});
}
}