2020-08-14 22:31:55 +00:00
|
|
|
// Require the Bolt package (github.com/slackapi/bolt)
|
|
|
|
const { App } = require("@slack/bolt");
|
|
|
|
const keep_alive = require('./keep_alive.js')
|
|
|
|
const schedule = require('node-schedule');
|
|
|
|
const moment = require('moment');
|
2020-10-14 04:21:07 +00:00
|
|
|
const main = "CDJMS683D";
|
|
|
|
const thread = "C01BZ7V0207";
|
2020-08-14 22:31:55 +00:00
|
|
|
const token = process.env.SLACK_BOT_TOKEN;
|
|
|
|
const Airtable = require('airtable');
|
|
|
|
Airtable.configure({
|
|
|
|
endpointUrl: 'https://api.airtable.com',
|
|
|
|
apiKey: process.env.AIRTABLE_API_KEY
|
|
|
|
});
|
|
|
|
const base = Airtable.base('appogmRaVRo5ElVH7');
|
|
|
|
let speedArr = [];
|
|
|
|
let latest;
|
|
|
|
let averageSpeed;
|
|
|
|
|
|
|
|
const app = new App({
|
|
|
|
token: token,
|
|
|
|
signingSecret: process.env.SLACK_SIGNING_SECRET
|
|
|
|
});
|
|
|
|
|
|
|
|
function extractNumber(txt) {
|
|
|
|
let array = ["\n", " ", "-"]
|
|
|
|
for (let i of array) {
|
|
|
|
if (txt.includes(i)) {
|
|
|
|
return txt.split(i)[0]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return txt;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function fetchLatest(id) {
|
|
|
|
try {
|
2020-10-19 04:15:19 +00:00
|
|
|
if (id == "CDJMS683D") {
|
|
|
|
result = await app.client.conversations.history({
|
|
|
|
token: token,
|
|
|
|
channel: id,
|
|
|
|
limit: 1
|
|
|
|
});
|
|
|
|
} else if (id == "C01BZ7V0207") {
|
|
|
|
result = await app.client.conversations.replies({
|
|
|
|
token: token,
|
|
|
|
channel: id,
|
|
|
|
ts: '1602496865.003000',
|
|
|
|
// thread_ts: 1602496865,
|
|
|
|
limit: 1
|
|
|
|
});
|
|
|
|
}
|
|
|
|
let index = id == "CDJMS683D" ? 0 : 1
|
|
|
|
const number = extractNumber(result.messages[index].text);
|
|
|
|
// console.log(number);
|
2020-08-14 22:31:55 +00:00
|
|
|
return number;
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function fetchOldest(id) {
|
|
|
|
try {
|
|
|
|
let last24Hrs;
|
2020-10-19 04:15:19 +00:00
|
|
|
let result;
|
|
|
|
if (id == "CDJMS683D") {
|
|
|
|
result = await app.client.conversations.history({
|
|
|
|
token: token,
|
|
|
|
channel: id,
|
|
|
|
oldest: Math.floor(Date.now() / 1000) - 86400, //debug: 1596326400, actual: Math.floor(Date.now() / 1000) - 86400
|
|
|
|
inclusive: false
|
|
|
|
});
|
|
|
|
} else if (id == "C01BZ7V0207") {
|
|
|
|
result = await app.client.conversations.replies({
|
|
|
|
token: token,
|
|
|
|
channel: id,
|
|
|
|
ts: '1602496865.003000',
|
|
|
|
limit: 10,
|
|
|
|
oldest: Math.floor(Date.now() / 1000) - 86400, //debug: 1596326400, actual: Math.floor(Date.now() / 1000) - 86400
|
|
|
|
inclusive: false
|
|
|
|
});
|
|
|
|
// console.log(result);
|
|
|
|
}
|
|
|
|
let index = id == "CDJMS683D" ? result.messages.length - 2 : 2
|
|
|
|
const number = extractNumber(result.messages[index].text);
|
2020-08-14 22:31:55 +00:00
|
|
|
return number - 1;
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function publishMessage(id, text) {
|
|
|
|
try {
|
2020-10-14 04:21:07 +00:00
|
|
|
let options = {
|
2020-10-19 04:15:19 +00:00
|
|
|
token: token,
|
|
|
|
channel: id,
|
|
|
|
text: text
|
|
|
|
}
|
|
|
|
if (id == "C01BZ7V0207") {
|
|
|
|
options['thread_ts'] = '1602496865.003000'
|
2020-10-14 04:21:07 +00:00
|
|
|
}
|
|
|
|
const result = await app.client.chat.postMessage(options);
|
2020-08-14 22:31:55 +00:00
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function postReaction(id, emoji, ts) {
|
|
|
|
try {
|
|
|
|
const result = await app.client.reactions.add({
|
|
|
|
token: token,
|
|
|
|
channel: id,
|
|
|
|
name: emoji,
|
|
|
|
timestamp: ts
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function pinMessage(id, ts) {
|
|
|
|
try {
|
|
|
|
const result = await app.client.pins.add({
|
|
|
|
token: token,
|
|
|
|
channel: id,
|
|
|
|
timestamp: ts
|
|
|
|
})
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function findMean(arr) {
|
|
|
|
let totalSum = 0;
|
|
|
|
for (let i of arr) {
|
|
|
|
totalSum += i;
|
|
|
|
}
|
|
|
|
return totalSum / arr.length;
|
|
|
|
}
|
|
|
|
|
2020-08-18 01:15:00 +00:00
|
|
|
async function addData(db, object) {
|
2020-10-14 04:21:07 +00:00
|
|
|
base(db).create(object, function(err, record) {
|
2020-08-17 23:15:49 +00:00
|
|
|
if (err) {
|
|
|
|
console.error(err);
|
|
|
|
return;
|
|
|
|
}
|
2020-08-18 01:15:00 +00:00
|
|
|
// console.log(record.getId());
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-10-14 04:21:07 +00:00
|
|
|
async function getStats(id) {
|
2020-08-18 01:15:00 +00:00
|
|
|
try {
|
2020-10-19 04:15:19 +00:00
|
|
|
let obj;
|
2020-10-14 04:21:07 +00:00
|
|
|
if (id == "CDJMS683D") {
|
2020-10-19 04:15:19 +00:00
|
|
|
obj = await base('stats').find('rec2XI8QAsPr7EMVB');
|
2020-10-14 04:21:07 +00:00
|
|
|
} else if (id == "C01BZ7V0207") {
|
2020-10-19 04:15:19 +00:00
|
|
|
obj = await base('thread_stats').find('recBljY8vBdaNK8kq');
|
2020-10-14 04:21:07 +00:00
|
|
|
}
|
2020-08-18 01:15:00 +00:00
|
|
|
return {
|
2020-10-14 04:21:07 +00:00
|
|
|
id: obj.id,
|
|
|
|
fields: obj.fields,
|
|
|
|
};
|
2020-08-18 01:15:00 +00:00
|
|
|
} catch (error) {
|
|
|
|
console.error(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-14 04:21:07 +00:00
|
|
|
async function report(channel) {
|
2020-08-18 01:15:00 +00:00
|
|
|
let oldest = await fetchOldest(channel);
|
2020-09-29 00:13:31 +00:00
|
|
|
let latest = await fetchLatest(channel);
|
2020-08-18 01:15:00 +00:00
|
|
|
let diff = latest - oldest;
|
2020-10-14 04:21:07 +00:00
|
|
|
let db = channel == "CDJMS683D" ? 'increase' : 'thread';
|
2020-10-19 04:15:19 +00:00
|
|
|
let dataArray = {
|
2020-10-14 04:21:07 +00:00
|
|
|
"Date": moment().subtract(1, "days").format("YYYY-MM-DD"),
|
2020-10-19 04:15:19 +00:00
|
|
|
"increase": diff
|
|
|
|
}
|
|
|
|
if (channel == "CDJMS683D") {
|
|
|
|
dataArray.stats = [
|
2020-10-14 04:21:07 +00:00
|
|
|
"rec2XI8QAsPr7EMVB"
|
|
|
|
]
|
2020-10-19 04:15:19 +00:00
|
|
|
} else if (channel == "C01BZ7V0207") {
|
|
|
|
dataArray.thread_stats = [
|
|
|
|
"recBljY8vBdaNK8kq"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
addData(db, dataArray);
|
2020-10-14 04:21:07 +00:00
|
|
|
let newStats = await getStats(channel);
|
2020-08-18 01:15:00 +00:00
|
|
|
averageSpeed = newStats.fields.average.toFixed(3);
|
2020-08-14 22:31:55 +00:00
|
|
|
let thousandsGoal = Math.ceil(latest / 1000) * 1000;
|
2020-09-30 00:35:47 +00:00
|
|
|
let thousandsTime = predictTime(thousandsGoal, latest);
|
2020-08-14 22:31:55 +00:00
|
|
|
let tenThousandsGoal = Math.ceil(latest / 5000) * 5000;
|
|
|
|
let pastThousandsGoal = Math.floor(latest / 1000) * 1000;
|
2020-09-30 00:35:47 +00:00
|
|
|
let tenThousandsTime = predictTime(tenThousandsGoal, latest);
|
2020-08-14 22:31:55 +00:00
|
|
|
let message =
|
|
|
|
"Nice! Today we've went from *" +
|
|
|
|
oldest +
|
|
|
|
"* to *" +
|
|
|
|
latest +
|
|
|
|
"*! \n - :arrow_upper_right: The day's progress: *+" +
|
|
|
|
diff +
|
|
|
|
"*\n - :chart_with_upwards_trend: Average daily speed: *" +
|
|
|
|
averageSpeed +
|
|
|
|
"*\n - :round_pushpin: At the avg speed, we'll reach " +
|
|
|
|
thousandsGoal +
|
|
|
|
" *" +
|
|
|
|
thousandsTime +
|
|
|
|
"*\n - :calendar: At the avg speed, we'll reach " +
|
|
|
|
tenThousandsGoal +
|
|
|
|
" *" +
|
|
|
|
tenThousandsTime +
|
|
|
|
"* \n :fastparrot: KEEP IT GOING GUYS!";
|
2020-09-29 00:13:31 +00:00
|
|
|
if (pastThousandsGoal > oldest && pastThousandsGoal <= latest) {
|
2020-08-17 23:15:49 +00:00
|
|
|
let messageWithCelebration = ":tada: YAY! We've went past " + pastThousandsGoal + "! :tada: \n" + message;
|
2020-10-19 04:15:19 +00:00
|
|
|
|
|
|
|
publishMessage(channel, messageWithCelebration);
|
|
|
|
// publishMessage('C017W4PHYKS', messageWithCelebration);
|
|
|
|
|
|
|
|
//'C017W4PHYKS' for debugging, channel for actual
|
2020-08-17 23:15:49 +00:00
|
|
|
} else {
|
2020-10-19 04:15:19 +00:00
|
|
|
// publishMessage('C017W4PHYKS', message);
|
|
|
|
publishMessage(channel, message);
|
|
|
|
|
|
|
|
//'C017W4PHYKS' for debugging, channel for actual
|
2020-08-17 23:15:49 +00:00
|
|
|
}
|
|
|
|
|
2020-08-18 01:15:00 +00:00
|
|
|
};
|
2020-08-14 22:31:55 +00:00
|
|
|
|
2020-09-30 00:35:47 +00:00
|
|
|
function predictTime(goal, recent) {
|
|
|
|
let daysLeft = (goal - recent) / averageSpeed;
|
|
|
|
let unix = new Date(Date.now() + daysLeft * 86400000);
|
|
|
|
return moment(unix).fromNow();
|
|
|
|
}
|
|
|
|
|
2020-08-14 22:31:55 +00:00
|
|
|
app.event('message', async (body) => {
|
|
|
|
try {
|
|
|
|
let e = body.event;
|
|
|
|
if (typeof e.subtype === "undefined" && /\d/.test(e.text[0])) {
|
|
|
|
let number = extractNumber(e.text);
|
|
|
|
let ts = e.ts;
|
|
|
|
let c = e.channel;
|
|
|
|
if (number % 1000 === 0) {
|
|
|
|
postReaction(c, "tada", ts);
|
|
|
|
}
|
|
|
|
if (number % 5000 === 0) {
|
|
|
|
pinMessage(c, ts);
|
|
|
|
}
|
|
|
|
let l = number.length;
|
|
|
|
if (number[l - 2] == 6 && number[l - 1] == 9) {
|
|
|
|
postReaction(c, "ok_hand", ts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
(async (req, res) => {
|
|
|
|
// Start your app
|
|
|
|
try {
|
|
|
|
await app.start(process.env.PORT || 3000);
|
2020-10-19 04:15:19 +00:00
|
|
|
let j = schedule.scheduleJob('0 0 * * *', () => { report(main) });
|
|
|
|
// let j = schedule.scheduleJob('*/15 * * * * *', () => { report(main) });
|
|
|
|
|
2020-10-14 04:21:07 +00:00
|
|
|
let k = schedule.scheduleJob('0 0 * * *', () => { report(thread) });
|
2020-10-19 04:15:19 +00:00
|
|
|
// let k = schedule.scheduleJob('*/15 * * * * *', () => { report(thread) });
|
|
|
|
|
|
|
|
// */15 * * * * * for debugging, 0 0 * * * actual
|
2020-08-14 22:31:55 +00:00
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
2020-10-14 04:21:07 +00:00
|
|
|
publishMessage('C017W4PHYKS', error)
|
2020-08-14 22:31:55 +00:00
|
|
|
}
|
|
|
|
})();
|