-
Notifications
You must be signed in to change notification settings - Fork 5
/
bot.js
117 lines (98 loc) · 3.56 KB
/
bot.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
const TelegramBot = require('node-telegram-bot-api');
const Querier = require('./querier');
const Promise = require('bluebird');
const moment = require('moment');
const FirebaseSync = require('./fbsync');
const fetch = require('node-fetch');
fetch.Promise = Promise;
const SECONDS_IN_MINUTE = 60;
const LIMIT_MESSAGES_PER_MINUTE = 10;
const MILLISECONDS_IN_SECOND = 1000;
let bot = null;
function log(...args) {
console.log(...args);
}
class Bot {
constructor(firebase, querier, telegramBot, config, process) {
this.config = config;
this.lastDiscloseDate = null;
this.process = process;
this.firebase = firebase;
this.querier = querier;
this.telegramBot = telegramBot;
this.standardTimeoutInMs = (SECONDS_IN_MINUTE / LIMIT_MESSAGES_PER_MINUTE) * MILLISECONDS_IN_SECOND;
}
formatDate(strDate) {
return moment(strDate).utc().format('YYYY-MM-DD HH:mm:ss UTC+0');
}
escapeChars(text) {
return text.replace(/([\\\`\*\_\{\}\[\]\(\)\#\+\-\.\!])/g, '\\$1');
}
createMessage(node) {
return `_Hacktivity_ from *${this.escapeChars(node.reporter.username)}*
\`\`\`text \n${this.escapeChars(node.title)}\`\`\`
${node.url}
*Disclosed at:* ${this.formatDate(node.disclosed_at)}
*Created at:* ${this.formatDate(node.created_at)}`
}
async go() {
log('Bot not sleeping!');
if (!this.lastDiscloseDate) {
this.lastDiscloseDate = await this.firebase.get('hackerone/last_disclose_date');
}
log(`lastDiscloseDate: ${this.lastDiscloseDate}`);
const response = await this.querier.queryReports({
disclosed_at: this.lastDiscloseDate
});
if (!response.data) {
log(`[WARNING] No response data: ${JSON.stringify(response)}`);
return;
}
log(`Received: ${response.data.reports.edges.length} records`);
response.data.reports.edges.sort(
(a, b) => ((a.node.disclosed_at < b.node.disclosed_at) ? -1 : ((a.node.disclosed_at > b.node.disclosed_at) ? 1 : 0))
);
const reports = response.data.reports.edges.filter(r => r.node.disclosed_at !== this.lastDiscloseDate);
log(`But ${reports.length ? 'found' : 'not found'} new records!`);
if (reports.length > 0) {
this.lastDiscloseDate = reports[reports.length - 1].node.disclosed_at;
await this.firebase.put('hackerone/last_disclose_date', this.lastDiscloseDate);
}
await Promise.mapSeries(reports, (report) => {
return new Promise(async (resolve) => {
await this.telegramBot.sendMessage(
this.config.chatId,
this.createMessage(report.node), {
parse_mode: 'Markdown'
}
);
log('[BOT]: ', this.createMessage(report.node));
Promise.delay(this.standardTimeoutInMs).then(resolve);
});
});
}
}
async function start(config) {
const querier = new Querier(config);
const firebase = new FirebaseSync(config);
const telegramBot = new TelegramBot(config.token, {
polling: true
});
if (!bot) {
bot = new Bot(
firebase,
querier,
telegramBot,
config,
process
);
}
log('-------------------------- running bot loop ------------------------');
function loop() {
return bot.go().then(() => setTimeout(loop, 1000 * config.intervalInSeconds));
}
await loop();
}
module.exports = {
start,
};