From 3c9220d8c78019a7a4385efbcbc52dd01d0b7b0b Mon Sep 17 00:00:00 2001 From: Byren Higgin Date: Thu, 4 Oct 2018 08:42:52 +1000 Subject: [PATCH 1/4] Add Logging support and reduce overnight posting. Added winston to add file and console logging, as well as adding a feature to reduce overnight posting, unless a checkbox field on the Airtable with the column name 'Force At Night' is set to true --- announcer.js | 100 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 23 deletions(-) diff --git a/announcer.js b/announcer.js index 63f12b5..27b8507 100644 --- a/announcer.js +++ b/announcer.js @@ -1,12 +1,24 @@ +require('dotenv').config() const Airtable = require('airtable'); const hook_url = "https://hooks.slack.com/services/" + process.env.SLACK_TOKEN; const CronJob = require('cron').CronJob; const Slack = require('node-slack'); +const winston = require('winston'); const slack = new Slack(hook_url); const base = new Airtable({ apiKey: process.env.AIRTABLE_API_KEY }).base(process.env.AIRTABLE_BASE); +const logger = winston.createLogger({ + level: 'info', + format: winston.format.json(), + transports: [ + new winston.transports.File({ filename: 'error.log', level: 'error' }), + new winston.transports.File({ filename: 'combined.log' }), + new winston.transports.Console(), + ] +}); + var airtableCronJobs = []; function refreshCronTable () { @@ -25,9 +37,8 @@ function refreshCronTable () { }).eachPage(function page(records, fetchNextPage) { // This function (`page`) will get called for each page of records. - records.forEach(function (record) { - + var name = record.get('Name'); var sec = record.get('Second'); var min = record.get('Minute'); @@ -35,31 +46,59 @@ function refreshCronTable () { var dom = record.get('Day of Month'); var mon = record.get('Month'); var dow = record.get('Day of Week'); + var fan = record.get('Force At Night'); + fan = (fan === true) ? true: false; if (min > 1 && min < 5) { min = 5; console.log(`job ${name} was modified to run outside of the CRON table refresh window`); + logger.log({ + level: 'info', + message: `job ${name} was modified to run outside of the CRON table refresh window` + }) } + + logger.log({ + level: 'info', + message: `Forcing at Night ${fan}` + }); var airtable_cron = (sec + ' ' + min + ' ' + hor + ' ' + dom + ' ' + mon + ' ' + dow); - + airtableCronJobs.push(new CronJob(airtable_cron, function () { - console.log(`Running job ${name}`); - - // See what channels are associated with this entry. - record.get('Channels').forEach(function (channel) { - - slack.send({ - text: record.get('Text'), - channel: channel.toString(), - username: record.get('Announcer Name') - }); - - }) + //Makes the bot not post overnight unless the post is forced. + var OutsideNormalHours = ((new Date().getUTCHours() >= 6 && new Date().getUTCHours() <= 13)) ? true : false; + logger.log({ + level: 'info', + message: `Current local server date ${new Date().getUTCHours()}` + }); + if(!OutsideNormalHours || fan) { + record.get('Channels').forEach(function (channel) { + logger.log({ + level: 'info', + message: `Successfully sent '` +record.get('Text').substring(0,30) + `' message to channel ${channel}` + }) + try { + slack.send({ + text: record.get('Text'), + channel: channel.toString(), + username: record.get('Announcer Name') + }); + logger.log({ + level: 'info', + message: `Successfully sent '` +record.get('Text').substring(0,30) + `' message to channel ${channel}` + }) + } catch (ex) { + logger.log({ + level: 'error', + message: `Unable to run job ${name}: ${ex}` + }) + } + + }) + } }, null, true, 'America/Los_Angeles')); - - }); - + // To fetch the next page of records, call `fetchNextPage`. // If there are more records, `page` will get called again. // If there are no more records, `done` will get called. @@ -67,18 +106,29 @@ function refreshCronTable () { }, function done(error) { if (error) { - console.log(error); + //console.log("Error Occured: ", error); + logger.log({ + level: 'info', + message: `Error Ocurred: ${error}` + }) } }); -} +}); +}; // Refresh the CRON table immediately upon npm start try { refreshCronTable(); } catch (ex) { - console.log(`Error refreshing Cron Table: ${ex}`); + logger.log({ + level: 'error', + message: `Error refreshing Cron Table: ${ex}` + }) } +function OnComplete() { + +} // and then flush and reload the CRON table at 3 minutes and 3 seconds past every hour // This is specifically offset from 5, 10, 15 minute intervals to ensure that // a CRON job is not set to fire whe the CRON table is being refreshed @@ -86,8 +136,12 @@ try { const update_cron = '3 3 * * * *'; try { - new CronJob(update_cron, refreshCronTable, null, true, 'America/Los_Angeles'); + + //new CronJob(update_cron, refreshCronTable, null, true, 'America/Los_Angeles'); } catch (ex) { - console.log(`Invalid Cron Pattern: ${ex}`); + logger.log({ + level: 'error', + message: `Invalid Cron Pattern: ${ex}` + }) } From 2af8a67264ca35296576b20be37f71f942f3fbee Mon Sep 17 00:00:00 2001 From: Byren Higgin Date: Thu, 4 Oct 2018 08:44:26 +1000 Subject: [PATCH 2/4] Update package.json --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e491b60..8d779fd 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "dependencies": { "airtable": "^0.4.3", "cron": "^1.2.1", - "node-slack": "0.0.7" + "node-slack": "0.0.7", + "winston": "3.1.0" }, "devDependencies": { "dotenv": "^2.0.0", From 30591447cc1238f16bcd71f3496f8e2fe8cf3479 Mon Sep 17 00:00:00 2001 From: Byren Higgin Date: Thu, 4 Oct 2018 08:44:55 +1000 Subject: [PATCH 3/4] Update announcer.js --- announcer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/announcer.js b/announcer.js index 27b8507..3d13626 100644 --- a/announcer.js +++ b/announcer.js @@ -1,4 +1,3 @@ -require('dotenv').config() const Airtable = require('airtable'); const hook_url = "https://hooks.slack.com/services/" + process.env.SLACK_TOKEN; const CronJob = require('cron').CronJob; From 1b50d95c4b180137a3ff095ba81c6e1730f97e85 Mon Sep 17 00:00:00 2001 From: Byren Higgin Date: Thu, 4 Oct 2018 08:54:59 +1000 Subject: [PATCH 4/4] Update announcer.js --- announcer.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/announcer.js b/announcer.js index 3d13626..3cdf07b 100644 --- a/announcer.js +++ b/announcer.js @@ -2,20 +2,24 @@ const Airtable = require('airtable'); const hook_url = "https://hooks.slack.com/services/" + process.env.SLACK_TOKEN; const CronJob = require('cron').CronJob; const Slack = require('node-slack'); -const winston = require('winston'); +const { createLogger, format, transports } = require('winston'); +const { combine, timestamp, label, prettyPrint } = format; const slack = new Slack(hook_url); const base = new Airtable({ apiKey: process.env.AIRTABLE_API_KEY }).base(process.env.AIRTABLE_BASE); -const logger = winston.createLogger({ - level: 'info', - format: winston.format.json(), +const logger = createLogger({ + format: combine( + timestamp(), + prettyPrint() + ), transports: [ - new winston.transports.File({ filename: 'error.log', level: 'error' }), - new winston.transports.File({ filename: 'combined.log' }), - new winston.transports.Console(), - ] + new transports.File({ filename: 'error.log', level: 'error' }), + new transports.File({ filename: 'combined.log' }), + new transports.Console(), + ], + level: 'info' }); var airtableCronJobs = []; @@ -68,7 +72,7 @@ function refreshCronTable () { //Makes the bot not post overnight unless the post is forced. var OutsideNormalHours = ((new Date().getUTCHours() >= 6 && new Date().getUTCHours() <= 13)) ? true : false; logger.log({ - level: 'info', + level: 'debug', message: `Current local server date ${new Date().getUTCHours()}` }); if(!OutsideNormalHours || fan) { @@ -97,6 +101,7 @@ function refreshCronTable () { }) } }, null, true, 'America/Los_Angeles')); + }, null, true, 'America/Los_Angeles')); // To fetch the next page of records, call `fetchNextPage`. // If there are more records, `page` will get called again. @@ -105,9 +110,8 @@ function refreshCronTable () { }, function done(error) { if (error) { - //console.log("Error Occured: ", error); logger.log({ - level: 'info', + level: 'crit', message: `Error Ocurred: ${error}` }) } @@ -120,7 +124,7 @@ try { refreshCronTable(); } catch (ex) { logger.log({ - level: 'error', + level: 'crit', message: `Error refreshing Cron Table: ${ex}` }) } @@ -136,11 +140,10 @@ const update_cron = '3 3 * * * *'; try { - //new CronJob(update_cron, refreshCronTable, null, true, 'America/Los_Angeles'); + new CronJob(update_cron, refreshCronTable, null, true, 'America/Los_Angeles'); } catch (ex) { logger.log({ - level: 'error', + level: 'crit', message: `Invalid Cron Pattern: ${ex}` }) } -