mirror of
https://github.com/opelly27/streetmerchant.git
synced 2026-05-20 08:47:43 +00:00
feat: fix metadata in logging, lint prettier, typed Models (#747)
This commit is contained in:
@@ -25,7 +25,7 @@ export function sendDiscordMessage(link: Link, store: Store) {
|
||||
embed.setText(notifyGroup.join(' '));
|
||||
}
|
||||
|
||||
embed.setColor(0x76B900);
|
||||
embed.setColor(0x76b900);
|
||||
embed.setTimestamp();
|
||||
|
||||
const promises = [];
|
||||
@@ -37,7 +37,7 @@ export function sendDiscordMessage(link: Link, store: Store) {
|
||||
|
||||
logger.info('✔ discord message sent');
|
||||
} catch (error) {
|
||||
logger.error('✖ couldn\'t send discord message', error);
|
||||
logger.error("✖ couldn't send discord message", error);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -30,21 +30,23 @@ export function sendEmail(link: Link, store: Store) {
|
||||
logger.debug('↗ sending email');
|
||||
|
||||
const mailOptions: Mail.Options = {
|
||||
attachments: link.screenshot ? [
|
||||
{
|
||||
filename: link.screenshot,
|
||||
path: `./${link.screenshot}`
|
||||
}
|
||||
] : undefined,
|
||||
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 => {
|
||||
transporter.sendMail(mailOptions, (error) => {
|
||||
if (error) {
|
||||
logger.error('✖ couldn\'t send email', error);
|
||||
logger.error("✖ couldn't send email", error);
|
||||
} else {
|
||||
logger.info('✔ email sent');
|
||||
}
|
||||
|
||||
+20
-13
@@ -8,15 +8,20 @@ let client: MqttClient.Client;
|
||||
|
||||
if (mqtt.broker) {
|
||||
if (checkInsecureUsage(mqtt.password, mqtt.broker)) {
|
||||
logger.warn('✖ Insecure transport of password - Only use credentials with MQTT brokers on private networks.');
|
||||
logger.warn(
|
||||
'✖ Insecure transport of password - Only use credentials with MQTT brokers on private networks.'
|
||||
);
|
||||
} else {
|
||||
const clientOptions: IClientOptions = {
|
||||
clean: (mqtt.clientId === ''),
|
||||
clean: mqtt.clientId === '',
|
||||
clientId: mqtt.clientId === '' ? undefined : mqtt.clientId,
|
||||
password: mqtt.password === '' ? undefined : mqtt.password,
|
||||
username: mqtt.username === '' ? undefined : mqtt.username
|
||||
};
|
||||
client = MqttClient.connect(`mqtt://${mqtt.broker}:${mqtt.port}`, clientOptions);
|
||||
client = MqttClient.connect(
|
||||
`mqtt://${mqtt.broker}:${mqtt.port}`,
|
||||
clientOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +31,10 @@ export function sendMqttMessage(link: Link, store: Store) {
|
||||
|
||||
(async () => {
|
||||
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
||||
const message = `{"msg":"${Print.inStock(link, store)}", "url":"${givenUrl}"}`;
|
||||
const message = `{"msg":"${Print.inStock(
|
||||
link,
|
||||
store
|
||||
)}", "url":"${givenUrl}"}`;
|
||||
const topic = generateTopic(link, store, mqtt.topic);
|
||||
const pubOptions: IClientPublishOptions = {
|
||||
qos: mqtt.qos as 0 | 1 | 2,
|
||||
@@ -34,14 +42,10 @@ export function sendMqttMessage(link: Link, store: Store) {
|
||||
};
|
||||
|
||||
try {
|
||||
client.publish(
|
||||
topic,
|
||||
message,
|
||||
pubOptions
|
||||
);
|
||||
client.publish(topic, message, pubOptions);
|
||||
logger.info('✔ mqtt message sent');
|
||||
} catch (error) {
|
||||
logger.error('✖ couldn\'t send mqtt message', error);
|
||||
logger.error("✖ couldn't send mqtt message", error);
|
||||
}
|
||||
})();
|
||||
}
|
||||
@@ -50,7 +54,8 @@ export function sendMqttMessage(link: Link, store: Store) {
|
||||
function generateTopic(link: Link, store: Store, topic: string): string {
|
||||
topic.trim();
|
||||
topic = topic.replace(/^\//, '');
|
||||
topic = topic.replace(/%series%/g, link.series)
|
||||
topic = topic
|
||||
.replace(/%series%/g, link.series)
|
||||
.replace(/%brand%/g, link.brand)
|
||||
.replace(/%model%/g, link.model)
|
||||
.replace(/%store%/g, store.name);
|
||||
@@ -68,10 +73,12 @@ function generateTopic(link: Link, store: Store, topic: string): string {
|
||||
*/
|
||||
function checkInsecureUsage(pass: string, address: string): boolean {
|
||||
if (pass !== '') {
|
||||
if (isClassANet(address) ||
|
||||
if (
|
||||
isClassANet(address) ||
|
||||
isClassBNet(address) ||
|
||||
isClassCNet(address) ||
|
||||
isLinkLocal(address)) {
|
||||
isLinkLocal(address)
|
||||
) {
|
||||
logger.debug(`MQTT using private network broker: ${address}`);
|
||||
} else {
|
||||
logger.debug(`MQTT using public network broker: ${address}`);
|
||||
|
||||
@@ -8,12 +8,11 @@ const pd = new PDClient('');
|
||||
export function sendPagerDutyNotification(link: Link, store: Store) {
|
||||
if (config.notifications.pagerduty.integrationKey) {
|
||||
logger.debug('↗ sending pagerduty message');
|
||||
const links = [
|
||||
{href: link.url, text: 'Visit Store'}
|
||||
];
|
||||
const links = [{href: link.url, text: 'Visit Store'}];
|
||||
if (link.cartUrl) {
|
||||
links.push({
|
||||
href: link.cartUrl, text: 'Add to Cart'
|
||||
href: link.cartUrl,
|
||||
text: 'Add to Cart'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -43,29 +43,37 @@ const adjustLightsWithAPI = (hueBridge: Api) => {
|
||||
// If we've been given light IDs, then only adjust those IDs
|
||||
if (lightIds) {
|
||||
const arrayOfIDs = lightIds.split(',');
|
||||
arrayOfIDs.forEach(light => {
|
||||
arrayOfIDs.forEach((light) => {
|
||||
logger.debug('adjusting all hue lights');
|
||||
(hueBridge.lights.setLightState(light, lightState) as Promise<any>).catch((error: Error) => {
|
||||
logger.error('Failed to adjust all lights.');
|
||||
(hueBridge.lights.setLightState(light, lightState) as Promise<any>).catch(
|
||||
(error: Error) => {
|
||||
logger.error('Failed to adjust all lights.');
|
||||
logger.error(error);
|
||||
throw error;
|
||||
}
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Adjust all light IDs
|
||||
hueBridge.lights
|
||||
.getAll()
|
||||
.then((allLights: any[]) => {
|
||||
allLights.forEach((light: any) => {
|
||||
logger.debug('adjusting specified lights');
|
||||
(hueBridge.lights.setLightState(light, lightState) as Promise<
|
||||
any
|
||||
>).catch((error: Error) => {
|
||||
logger.error('Failed to adjust specified lights.');
|
||||
logger.error(error);
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
logger.error('Failed to get all lights.');
|
||||
logger.error(error);
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
} else { // Adjust all light IDs
|
||||
hueBridge.lights.getAll().then((allLights: any[]) => {
|
||||
allLights.forEach((light: any) => {
|
||||
logger.debug('adjusting specified lights');
|
||||
(hueBridge.lights.setLightState(light, lightState) as Promise<any>).catch((error: Error) => {
|
||||
logger.error('Failed to adjust specified lights.');
|
||||
logger.error(error);
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
}).catch((error: Error) => {
|
||||
logger.error('Failed to get all lights.');
|
||||
logger.error(error);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -74,15 +82,21 @@ export function adjustPhilipsHueLights() {
|
||||
if (hue.apiKey && hue.bridgeIp) {
|
||||
logger.info('↗ adjusting Philips Hue lights over LAN');
|
||||
(async () => {
|
||||
logger.debug('Attempting to connect to Philips Hue bridge at ' + bridgeIp);
|
||||
hueAPI.api.createLocal(bridgeIp).connect(apiKey).then(
|
||||
hueBridge => {
|
||||
adjustLightsWithAPI(hueBridge);
|
||||
logger.info('✔ adjusted Philips Hue lights over LAN');
|
||||
},
|
||||
(error: Error) => {
|
||||
logger.error('✖ couldn\'t adjust hue lights.', error);
|
||||
});
|
||||
logger.debug(
|
||||
'Attempting to connect to Philips Hue bridge at ' + bridgeIp
|
||||
);
|
||||
hueAPI.api
|
||||
.createLocal(bridgeIp)
|
||||
.connect(apiKey)
|
||||
.then(
|
||||
(hueBridge) => {
|
||||
adjustLightsWithAPI(hueBridge);
|
||||
logger.info('✔ adjusted Philips Hue lights over LAN');
|
||||
},
|
||||
(error: Error) => {
|
||||
logger.error("✖ couldn't adjust hue lights.", error);
|
||||
}
|
||||
);
|
||||
})();
|
||||
} else if (hue.apiKey && hue.clientId && hue.clientSecret) {
|
||||
logger.info('↗ adjusting Philips Hue lights over cloud');
|
||||
@@ -90,16 +104,21 @@ export function adjustPhilipsHueLights() {
|
||||
logger.debug('Attempting to connect to Philips Hue bridge over cloud');
|
||||
const remoteBootstrap = hueAPI.api.createRemote(clientId, clientSecret);
|
||||
if (hue.accessToken && hue.refreshToken) {
|
||||
remoteBootstrap.connectWithTokens(accessToken, refreshToken, remoteApiUsername)
|
||||
.then(hueBridge => {
|
||||
adjustLightsWithAPI(hueBridge);
|
||||
logger.info('✔ adjusted Philips Hue lights over cloud');
|
||||
},
|
||||
(error: Error) => {
|
||||
logger.error('Failed to get a remote Philips Hue connection using supplied tokens.');
|
||||
logger.error(error);
|
||||
throw error;
|
||||
});
|
||||
remoteBootstrap
|
||||
.connectWithTokens(accessToken, refreshToken, remoteApiUsername)
|
||||
.then(
|
||||
(hueBridge) => {
|
||||
adjustLightsWithAPI(hueBridge);
|
||||
logger.info('✔ adjusted Philips Hue lights over cloud');
|
||||
},
|
||||
(error: Error) => {
|
||||
logger.error(
|
||||
'Failed to get a remote Philips Hue connection using supplied tokens.'
|
||||
);
|
||||
logger.error(error);
|
||||
throw error;
|
||||
}
|
||||
);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -17,10 +17,11 @@ export function sendPushbulletNotification(link: Link, store: Store) {
|
||||
link.cartUrl ? link.cartUrl : link.url,
|
||||
(error: Error) => {
|
||||
if (error) {
|
||||
logger.error('✖ couldn\'t send pushbullet message', error);
|
||||
logger.error("✖ couldn't send pushbullet message", error);
|
||||
} else {
|
||||
logger.info('✔ pushbullet message sent');
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export function sendPushoverNotification(link: Link, store: Store) {
|
||||
|
||||
push.send(message, (error: Error) => {
|
||||
if (error) {
|
||||
logger.error('✖ couldn\'t send pushover message', error);
|
||||
logger.error("✖ couldn't send pushover message", error);
|
||||
} else {
|
||||
logger.info('✔ pushover message sent');
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@ export function sendSlackMessage(link: Link, store: Store) {
|
||||
});
|
||||
|
||||
if (!result.ok) {
|
||||
logger.error('✖ couldn\'t send slack message', result);
|
||||
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.error("✖ couldn't send slack message", error);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
+28
-14
@@ -4,18 +4,27 @@ import Mail from 'nodemailer/lib/mailer';
|
||||
import {config} from '../config';
|
||||
import {transporter} from './email';
|
||||
|
||||
if (config.notifications.phone.number && !config.notifications.email.username) {
|
||||
logger.warn('✖ in order to receive sms alerts, email notifications must also be configured');
|
||||
}
|
||||
|
||||
const [email, phone] = [config.notifications.email, config.notifications.phone];
|
||||
|
||||
if (phone.number.length > 0 && (!email.username || !email.password)) {
|
||||
logger.warn(
|
||||
'✖ in order to receive sms alerts, email notifications must also be configured'
|
||||
);
|
||||
}
|
||||
|
||||
if (phone.carrier.length !== phone.number.length) {
|
||||
logger.warn('✖ the number of carriers must match the number of phone numbers');
|
||||
logger.warn(
|
||||
'✖ the number of carriers must match the number of phone numbers',
|
||||
{carrier: phone.carrier, number: phone.number}
|
||||
);
|
||||
}
|
||||
|
||||
export function sendSms(link: Link, store: Store) {
|
||||
for (let i = 0; i < Math.max(phone.number.length, phone.carrier.length); i++) {
|
||||
for (
|
||||
let i = 0;
|
||||
i < Math.max(phone.number.length, phone.carrier.length);
|
||||
i++
|
||||
) {
|
||||
const currentNumber = phone.number[i];
|
||||
const currentCarrier = phone.carrier[i];
|
||||
|
||||
@@ -35,21 +44,26 @@ export function sendSms(link: Link, store: Store) {
|
||||
logger.debug('↗ sending sms');
|
||||
|
||||
const mailOptions: Mail.Options = {
|
||||
attachments: link.screenshot ? [
|
||||
{
|
||||
filename: link.screenshot,
|
||||
path: `./${link.screenshot}`
|
||||
}
|
||||
] : undefined,
|
||||
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(currentNumber, currentCarrier)
|
||||
};
|
||||
|
||||
transporter.sendMail(mailOptions, error => {
|
||||
transporter.sendMail(mailOptions, (error) => {
|
||||
if (error) {
|
||||
logger.error(`✖ couldn't send sms to ${currentNumber} for carrier ${currentCarrier}`, error);
|
||||
logger.error(
|
||||
`✖ couldn't send sms to ${currentNumber} for carrier ${currentCarrier}`,
|
||||
error
|
||||
);
|
||||
} else {
|
||||
logger.info('✔ sms sent');
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ 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 = player.player;
|
||||
logger.info(`✔ sound player found: ${playerName}`);
|
||||
@@ -20,7 +20,7 @@ export function playSound() {
|
||||
if (config.notifications.playSound && player.player !== null) {
|
||||
logger.debug('↗ playing sound');
|
||||
|
||||
fs.access(config.notifications.playSound, fs.constants.F_OK, error => {
|
||||
fs.access(config.notifications.playSound, fs.constants.F_OK, (error) => {
|
||||
if (error) {
|
||||
logger.error(`✖ error opening sound file: ${error.message}`);
|
||||
return;
|
||||
@@ -28,7 +28,7 @@ export function playSound() {
|
||||
|
||||
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');
|
||||
|
||||
@@ -19,10 +19,15 @@ export function sendTelegramMessage(link: Link, store: Store) {
|
||||
|
||||
for (const chatId of telegram.chatId) {
|
||||
try {
|
||||
results.push(client.sendMessage(chatId, `${Print.inStock(link, store)}\n${givenUrl}`));
|
||||
results.push(
|
||||
client.sendMessage(
|
||||
chatId,
|
||||
`${Print.inStock(link, store)}\n${givenUrl}`
|
||||
)
|
||||
);
|
||||
logger.info('✔ telegram message sent');
|
||||
} catch (error) {
|
||||
logger.error('✖ couldn\'t send telegram message', error);
|
||||
logger.error("✖ couldn't send telegram message", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ export function sendTwilioMessage(link: Link, store: Store) {
|
||||
});
|
||||
logger.info('✔ twilio message sent');
|
||||
} catch (error) {
|
||||
logger.error('✖ couldn\'t send twilio message', error);
|
||||
logger.error("✖ couldn't send twilio message", error);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
+33
-10
@@ -17,7 +17,10 @@ let tokenData = {
|
||||
};
|
||||
|
||||
if (existsSync('./twitch.json')) {
|
||||
tokenData = {...JSON.parse(readFileSync('./twitch.json', 'utf-8')), ...tokenData};
|
||||
tokenData = {
|
||||
...JSON.parse(readFileSync('./twitch.json', 'utf-8')),
|
||||
...tokenData
|
||||
};
|
||||
}
|
||||
|
||||
const chatClient: ChatClient = new ChatClient(
|
||||
@@ -25,13 +28,25 @@ const chatClient: ChatClient = new ChatClient(
|
||||
new StaticAuthProvider(twitch.clientId, tokenData.accessToken),
|
||||
{
|
||||
clientSecret: twitch.clientSecret,
|
||||
expiry: tokenData.expiryTimestamp === null ? null : new Date(tokenData.expiryTimestamp),
|
||||
expiry:
|
||||
tokenData.expiryTimestamp === null
|
||||
? null
|
||||
: new Date(tokenData.expiryTimestamp),
|
||||
onRefresh: async ({accessToken, refreshToken, expiryDate}) => {
|
||||
return promises.writeFile('./twitch.json', JSON.stringify({
|
||||
accessToken,
|
||||
expiryTimestamp: expiryDate === null ? null : expiryDate.getTime(),
|
||||
refreshToken
|
||||
}, null, 4), 'utf-8');
|
||||
return promises.writeFile(
|
||||
'./twitch.json',
|
||||
JSON.stringify(
|
||||
{
|
||||
accessToken,
|
||||
expiryTimestamp:
|
||||
expiryDate === null ? null : expiryDate.getTime(),
|
||||
refreshToken
|
||||
},
|
||||
null,
|
||||
4
|
||||
),
|
||||
'utf-8'
|
||||
);
|
||||
},
|
||||
refreshToken: tokenData.refreshToken
|
||||
}
|
||||
@@ -51,7 +66,7 @@ chatClient.onJoin((channel: string, user: string) => {
|
||||
chatClient.say(channel, message);
|
||||
logger.info('✔ twitch message sent');
|
||||
} catch (error) {
|
||||
logger.error('✖ couldn\'t send twitch message', error);
|
||||
logger.error("✖ couldn't send twitch message", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,10 +80,18 @@ chatClient.onDisconnect(() => {
|
||||
});
|
||||
|
||||
export function sendTwitchMessage(link: Link, store: Store) {
|
||||
if (tokenData.accessToken && twitch.channel && twitch.clientId && twitch.clientSecret && tokenData.refreshToken) {
|
||||
if (
|
||||
tokenData.accessToken &&
|
||||
twitch.channel &&
|
||||
twitch.clientId &&
|
||||
twitch.clientSecret &&
|
||||
tokenData.refreshToken
|
||||
) {
|
||||
logger.debug('↗ sending twitch message');
|
||||
|
||||
messages.push(`${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`);
|
||||
messages.push(
|
||||
`${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`
|
||||
);
|
||||
|
||||
if (!alreadySaying) {
|
||||
alreadySaying = true;
|
||||
|
||||
@@ -13,18 +13,25 @@ const client = new Twitter({
|
||||
});
|
||||
|
||||
export function sendTweet(link: Link, store: Store) {
|
||||
if (twitter.accessTokenKey && twitter.accessTokenSecret && twitter.consumerKey && twitter.consumerSecret) {
|
||||
if (
|
||||
twitter.accessTokenKey &&
|
||||
twitter.accessTokenSecret &&
|
||||
twitter.consumerKey &&
|
||||
twitter.consumerSecret
|
||||
) {
|
||||
logger.debug('↗ sending twitter message');
|
||||
|
||||
let status = `${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`;
|
||||
let status = `${Print.inStock(link, store)}\n${
|
||||
link.cartUrl ? link.cartUrl : link.url
|
||||
}`;
|
||||
|
||||
if (twitter.tweetTags) {
|
||||
status += `\n\n${twitter.tweetTags}`;
|
||||
}
|
||||
|
||||
client.post('statuses/update', {status}, error => {
|
||||
client.post('statuses/update', {status}, (error) => {
|
||||
if (error) {
|
||||
logger.error('✖ couldn\'t send twitter notification', error);
|
||||
logger.error("✖ couldn't send twitter notification", error);
|
||||
} else {
|
||||
logger.info('✔ twitter notification sent');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user