- Added integration with Discord Webhooks - Added daily report summaries - Other fixes and improvements
73 lines
2.6 KiB
JavaScript
73 lines
2.6 KiB
JavaScript
const { CronJob } = require('cron');
|
|
const fs = require('node:fs/promises');
|
|
const discordWebhooks = require('./discord.js');
|
|
const log = require('../utils/log.js');
|
|
const { CACHE_FILE } = require('../config.js').MAIN;
|
|
|
|
const formatHourRange = hour => `${hour.toString().padStart(2, '0')}:00-${hour.toString().padStart(2, '0')}:59`;
|
|
const pluralizeReport = count => (count === 1 ? 'report' : 'reports');
|
|
|
|
const sendWebhook = async () => {
|
|
try {
|
|
await fs.access(CACHE_FILE);
|
|
} catch {
|
|
return log(2, `Cache file not found: ${CACHE_FILE}`);
|
|
}
|
|
|
|
let data;
|
|
try {
|
|
data = (await fs.readFile(CACHE_FILE, 'utf8')).trim();
|
|
} catch (err) {
|
|
return log(2, `Error reading file: ${err.message}`);
|
|
}
|
|
|
|
if (!data) {
|
|
log(0, `Cache file is empty: ${CACHE_FILE}`);
|
|
return discordWebhooks(4, `Cache file is empty: \`${CACHE_FILE}\``);
|
|
}
|
|
|
|
try {
|
|
const yesterday = new Date();
|
|
yesterday.setUTCDate(yesterday.getUTCDate() - 1);
|
|
const yesterdayString = yesterday.toISOString().split('T')[0];
|
|
|
|
const hourlySummary = {};
|
|
const uniqueEntries = new Set();
|
|
|
|
data.split('\n').forEach((line) => {
|
|
const [ip, timestamp] = line.split(' ');
|
|
if (!ip || isNaN(timestamp)) return;
|
|
|
|
const entryKey = `${ip}_${timestamp}`;
|
|
if (uniqueEntries.has(entryKey)) return;
|
|
uniqueEntries.add(entryKey);
|
|
|
|
const dateObj = new Date(parseInt(timestamp, 10) * 1000);
|
|
if (dateObj.toISOString().split('T')[0] !== yesterdayString) return;
|
|
|
|
const hour = dateObj.getUTCHours();
|
|
hourlySummary[hour] = (hourlySummary[hour] || 0) + 1;
|
|
});
|
|
|
|
const totalReports = Object.values(hourlySummary).reduce((sum, count) => sum + count, 0);
|
|
const sortedEntries = Object.entries(hourlySummary).sort((a, b) => b[1] - a[1]);
|
|
const maxReports = sortedEntries.length > 0 ? sortedEntries[0][1] : 0;
|
|
const topHours = sortedEntries
|
|
.filter(([, count]) => count === maxReports && count > 1)
|
|
.map(([hour]) => parseInt(hour));
|
|
|
|
const summaryString = Object.entries(hourlySummary)
|
|
.map(([hour, count]) => `${formatHourRange(parseInt(hour))}: ${count} ${pluralizeReport(count)}${topHours.includes(parseInt(hour)) ? ' 🔥' : ''}`)
|
|
.join('\n');
|
|
|
|
await discordWebhooks(7, `Midnight. Summary of IP address reports (${totalReports}) from yesterday (${yesterdayString}).\nGood night to you, sleep well! 😴\n\`\`\`${summaryString}\`\`\``);
|
|
log(0, `Reported IPs yesterday by hour:\n${summaryString}\nTotal reported IPs: ${totalReports} ${pluralizeReport(totalReports)}`);
|
|
} catch (err) {
|
|
log(2, err);
|
|
}
|
|
};
|
|
|
|
module.exports = async () => {
|
|
await sendWebhook();
|
|
new CronJob('0 0 * * *', sendWebhook, null, true, 'UTC');
|
|
};
|