require("dotenv").config(); const cron = require("node-cron"); const os = require("os"); const Discord = require('discord.js'); const mysql = require('mysql'); const { TimeSpan } = require("./timeSpan"); const { DateBuilder } = require("./dateBuilder"); const { CallStats } = require("./callStats"); const { CallRecord, Records } = require("./records"); const fs = require('fs').promises; const fsSync = require('fs'); const hook = !!process.env.DISCORD_WEBHOOK_URL ? new Discord.WebhookClient({ url: process.env.DISCORD_WEBHOOK_URL }) : null; const JSON_FILE = process.env.JSON_FILE || "records.json"; const records = fsSync.existsSync(JSON_FILE) ? Records.fromJSONFile(JSON_FILE) : new Records(); function getYesterday() { return new TimeSpan( new DateBuilder().addDays(-1).atStartOfDay().build().getTime(), new DateBuilder().addDays(-1).atEndOfDay().build().getTime() ); } /** * Fetch call statistics * @returns {Promise} */ async function getPreviousDayData() { return new Promise(async (resolve, reject) => { const yesterday = getYesterday(); const connection = await mysql.createConnection({ host: process.env.DATABASE_HOST, user: process.env.DATABASE_USER, password: process.env.DATABASE_PASSWORD, database: process.env.DATABASE_NAME, multipleStatements: true }); await connection.connect(); await connection.query(` SELECT COUNT(DISTINCT uniqueid) AS call_count FROM cdr WHERE calldate BETWEEN ? AND ?; SELECT COUNT(DISTINCT uniqueid) AS call_count FROM cdr WHERE MONTH (calldate) = MONTH (?) AND YEAR (calldate) = YEAR (?); SELECT COUNT(DISTINCT uniqueid) AS call_count FROM cdr; `, [ yesterday.start, yesterday.end, yesterday.start, yesterday.start ], (err, res) => { if (err) { reject(err); } connection.end(); // let output = { // "Calls Made": res[0][0].call_count, // "Monthly Total": res[1][0].call_count, // "Total Calls Ever Placed": res[2][0].call_count, // "System Uptime": getSystemUptime().toString(false, false), // "All Time Record": null, // Placeholder // } const stats = new CallStats({ callsMadeToday: res[0][0].call_count, totalCallsThisMonth: res[1][0].call_count, totalCallsEverPlaced: res[2][0].call_count, allTimeRecord: null // Placeholder }); console.log(stats); resolve(stats); }); }); } function getSystemUptime() { const uptime = os.uptime(); const now = new Date(); return new TimeSpan(now - (uptime * 1000), now.getTime()); } /** * Update records with new data * @param {CallStats} callStats * @param {Records} records * @returns {CallStats} */ function updateRecords(callStats, records) { const yesterday = getYesterday().startDate; const yesterdayDateString = yesterday.toISOString().split('T')[0]; let isNewRecord = false; // Update all-time record const allTimeRecord = records.callRecord || new CallRecord({ date: yesterdayDateString, count: 0 }); if (!records.callRecord) { records.callRecord = { date: yesterdayDateString, count: callStats.totalCallsMade }; isNewRecord = true; } else if (allTimeRecord.count < callStats.totalCallsThisMonth) { allTimeRecord.count = callStats.totalCallsThisMonth; isNewRecord = true; } callStats.allTimeRecord = `${allTimeRecord.count} calls on ${allTimeRecord.date}`; // Update total calls ever placed records.totalCallsEverPlaced = callStats.totalCallsEverPlaced; // Update monthly totals records.monthlyTotals[yesterday.getFullYear().toString()][yesterday.getMonth().toString()] = callStats.totalCallsThisMonth; if (isNewRecord) { callStats.isNewRecord = true; } return callStats; } async function sendSummary() { console.log("Preparing summary."); const data = await getPreviousDayData(); console.log("Updating records..."); const updatedData = await updateRecords(data, records); console.log("Saving."); await records.toJSONFile(JSON_FILE); const yesterday = getYesterday(); const makeField = (name, value) => ({ name, value: value.toString(), inline: false }); let embed = { title: `Summary from to `, color: 0x1E90FF, fields: [ makeField("Calls Made", updatedData.totalCallsMade), makeField("Monthly Total", updatedData.totalCallsThisMonth), makeField("Total Calls Ever Placed", updatedData.totalCallsEverPlaced), makeField("System Uptime", getSystemUptime().toString(false, false)), makeField("All Time Record", updatedData.allTimeRecord) ], timestamp: new Date(), footer: {} } if (updatedData.isNewRecord) { embed.color = 0xFFD700; // Gold color for new record embed.fields.push(makeField("🎉 NEW RECORD! 🎉", `A new record has been set, at ${updatedData.totalCallsMade}!`)); } const payload = { embeds: [ embed ] }; console.log("Sending Discord message:", payload); if (hook) await hook.send(payload); } if (process.env.NOOP) { sendSummary(); return; } console.log("Scheduling..."); const schedule = cron.schedule("0 1 * * *", sendSummary);