Files
broccolini-bot/handlers/analytics.js
root 519788c633 Initial commit
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 08:22:19 -06:00

90 lines
2.3 KiB
JavaScript

/**
* In-memory analytics and error tracking.
*/
const { logError } = require('../services/debugLog');
const analytics = {
commands: {},
buttons: {},
modals: {},
contextMenus: {},
errors: [],
startTime: Date.now()
};
function trackInteraction(type, name, userId = 'unknown') {
analytics[type][name] = (analytics[type][name] || 0) + 1;
console.log(`📊 Analytics: ${type}/${name} by ${userId}`);
}
function getTotalInteractions() {
let total = 0;
for (const type of ['commands', 'buttons', 'modals', 'contextMenus']) {
for (const key in analytics[type]) {
total += analytics[type][key];
}
}
return total;
}
function trackError(context, error, interaction = null) {
const errorEntry = {
context,
message: error.message,
stack: error.stack,
timestamp: Date.now(),
user: interaction?.user?.tag || 'system',
command: interaction?.commandName || 'N/A'
};
analytics.errors.push(errorEntry);
if (analytics.errors.length > 100) {
analytics.errors.shift();
}
console.error(`❌ Error tracked: ${context}:`, error.message);
logError(context, error, interaction);
const recentErrors = analytics.errors.filter(e =>
Date.now() - e.timestamp < 3600000
);
const errorRate = recentErrors.length / Math.max(1, getTotalInteractions());
if (errorRate > 0.05) {
console.warn(`⚠️ HIGH ERROR RATE: ${(errorRate * 100).toFixed(2)}% in last hour`);
}
}
function getAnalyticsSummary() {
const uptime = Math.floor((Date.now() - analytics.startTime) / 1000);
const totalInteractions = getTotalInteractions();
const recentErrors = analytics.errors.filter(e =>
Date.now() - e.timestamp < 3600000
);
return {
uptime: `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m`,
totalInteractions,
commandsUsed: Object.keys(analytics.commands).length,
mostUsedCommand: Object.entries(analytics.commands)
.sort((a, b) => b[1] - a[1])[0]?.[0] || 'None',
errorsLastHour: recentErrors.length,
errorRate: `${((recentErrors.length / Math.max(1, totalInteractions)) * 100).toFixed(2)}%`,
topCommands: Object.entries(analytics.commands)
.sort((a, b) => b[1] - a[1])
.slice(0, 5)
.map(([cmd, count]) => `${cmd}: ${count}`)
};
}
module.exports = {
analytics,
trackInteraction,
trackError,
getTotalInteractions,
getAnalyticsSummary
};