This repository has been archived by the owner on Aug 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathannouncer.js
131 lines (105 loc) · 3.76 KB
/
announcer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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 slack = new Slack(hook_url);
const base = new Airtable({
apiKey: process.env.AIRTABLE_API_KEY
}).base(process.env.AIRTABLE_BASE);
var airtableCronJobs = [];
const DIVIDER = '<divider>'
const generateTitleLinks = (text) => {
if (/<.+\|.+>/.test(text)) {
return {
title: text.match(/<(.+)\|/)[1],
title_link: text.match(/\|(.+)>/)[1],
text: text.replace(/<.+\|.+>/, '\n')
}
}
return { text }
}
const createAttachment = (text) => ({
...generateTitleLinks(text),
color: "#3ed6f0",
type: "section"
})
const createDividedAttachment = (text) => {
return [
createAttachment(text),
{
"type": "divider"
}
]
}
const generateAttachments = (text) => {
if (text.includes(DIVIDER)) {
return text.split(DIVIDER).flatMap(createDividedAttachment)
} else {
return [createAttachment(text)]
}
}
function refreshCronTable () {
console.log("Refreshing the CRON Table");
// Explicitly stop all airtable CRON jobs
airtableCronJobs.forEach(function (job) {
job.stop();
})
// Flush all CronJob instances
airtableCronJobs = [];
// Refresh and start all CronJob instances from airtable
base('Slack Announcer').select({
view: "Announcer Filter"
}).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');
var hor = record.get('Hour');
var dom = record.get('Day of Month');
var mon = record.get('Month');
var dow = record.get('Day of Week');
if (min > 1 && min < 5) {
min = 5;
console.log(`job ${name} was modified to run outside of the CRON table refresh window`);
}
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) {
const attachmentContent = record.get("Text")
slack.send({
text: " ",
attachments: generateAttachments(attachmentContent),
channel: channel.toString(),
username: record.get('Announcer Name')
});
})
}, 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.
fetchNextPage();
}, function done(error) {
if (error) {
console.log(error);
}
});
}
// Refresh the CRON table immediately upon npm start
try {
refreshCronTable();
} catch (ex) {
console.log(`Error refreshing Cron Table: ${ex}`);
}
// 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
const update_cron = '3 3 * * * *';
try {
new CronJob(update_cron, refreshCronTable, null, true, 'America/Los_Angeles');
} catch (ex) {
console.log(`Invalid Cron Pattern: ${ex}`);
}