@zumito-team/analytics-module
Analytics Module
@zumito-team/analytics-module provides configurable server analytics for your Zumito bot. Tracks messages, members, voice activity, and command usage with per-guild granularity. Includes optional web dashboard pages with Chart.js for both the admin and user panels.
Installation
npm install @zumito-team/analytics-module
Add to your zumito.config.ts:
Modules (recommended)
import { defineConfig } from 'zumito-framework';
import { analyticsModule } from '@zumito-team/analytics-module';
export default defineConfig({
modules: [
analyticsModule({
defaultTrackCommandPerformance: true,
}),
]
});
Or with plain string:
import { defineConfig } from 'zumito-framework';
export default defineConfig({
modules: ['@zumito-team/analytics-module']
});
Legacy bundles
{
path: path.join(__dirname, "node_modules", "@zumito-team", "analytics-module", "dist"),
}
What it provides
AnalyticsCollector service
Available via ServiceContainer.getService(AnalyticsCollector). Other modules can query analytics data.
| Method | Description |
|---|---|
recordMessage(guildId) |
Track a message sent in a guild |
recordMemberJoin(guildId) |
Track a member joining |
recordMemberLeave(guildId) |
Track a member leaving |
recordVoiceJoin(guildId, channelId, userId) |
Track voice channel join |
recordVoiceLeave(guildId, channelId, userId) |
Track voice channel leave (auto-calculates duration) |
recordCommand(payload) |
Track a command execution (success/failure + execution time) |
recordMemberCount(guildId, count) |
Store current member count snapshot |
getGuildStats(guildId, daysBack) |
Get daily stats for a guild |
getGlobalStatsSummary(daysBack) |
Get aggregated global stats |
getGuildGrowth(daysBack) |
Get active guilds per day |
getMessagesPerDay(daysBack) |
Get messages per day (global) |
getCommandsPerDay(guildId, daysBack) |
Get commands per day |
getTopCommands(guildId, daysBack, limit) |
Get most used commands |
getSlowestCommands(guildId, daysBack, limit) |
Get commands sorted by avg execution time |
getVoiceChannelStats(guildId, daysBack) |
Get per-channel voice stats |
getConfig(guildId) |
Get guild analytics configuration |
updateConfig(guildId, partial) |
Update guild analytics configuration |
runCleanup() |
Run data retention cleanup manually |
startCleanupScheduler() |
Start automatic cleanup scheduler |
stopCleanupScheduler() |
Stop automatic cleanup scheduler |
clearVoiceSessions() |
Clear in-memory voice session tracking |
Events tracked
| Event | Source | Description |
|---|---|---|
messageCreate |
discord | Message count per guild |
guildMemberAdd |
discord | Join count + member snapshot |
guildMemberRemove |
discord | Leave count + member snapshot |
voiceStateUpdate |
discord | Voice activity (minutes) per guild/channel |
commandExecuted |
framework | Command usage + execution time |
Commands
| Command | Type | Description |
|---|---|---|
/stats |
Slash + Prefix | Shows server stats embed (last 7 days) |
/analytics-config |
Slash + Prefix (admin-only) | View/toggle analytics settings per guild |
Admin Panel
/admin/analytics— Global bot statistics: guild growth, messages/day, commands/day, top commands, slowest commands- Date range selector: 7 / 30 / 90 days
- Chart.js visualizations (line, bar, horizontal bar charts)
User Panel
/panel/:guildId/analytics— Per-server statistics: messages, joins/leaves, voice activity, commands, top commands- If
track_command_performanceenabled: slowest commands chart - If
track_per_channel_voiceenabled: per-channel voice breakdown - Date range selector: 7 / 30 / 90 days
Configuration
Global defaults
Import and configure global defaults before the module initializes:
import { AnalyticsModuleConfig } from '@zumito-team/analytics-module';
AnalyticsModuleConfig.configure({
defaultRetentionDays: 90,
cleanupIntervalHours: 24,
defaultTrackMessages: true,
defaultTrackVoice: true,
defaultTrackMembers: true,
defaultTrackCommands: true,
defaultTrackCommandPerformance: false,
defaultTrackPerChannelVoice: false,
});
| Setting | Default | Description |
|---|---|---|
defaultRetentionDays |
90 |
Days to keep data before auto-deletion |
cleanupIntervalHours |
24 |
How often cleanup runs |
defaultTrackMessages |
true |
Track messages by default |
defaultTrackVoice |
true |
Track voice activity by default |
defaultTrackMembers |
true |
Track joins/leaves by default |
defaultTrackCommands |
true |
Track command usage by default |
defaultTrackCommandPerformance |
false |
Track execution time per command |
defaultTrackPerChannelVoice |
false |
Track per-channel voice stats |
Per-guild configuration
Use /analytics-config or the public API:
const collector = ServiceContainer.getService(AnalyticsCollector);
await collector.updateConfig(guildId, {
enabled: true,
track_commands: true,
track_command_performance: true, // enable execution time tracking
retention_days: 180, // 6 months for premium
});
Per-guild DB fields:
| Field | Type | Default |
|---|---|---|
guild_id |
string |
Primary key |
enabled |
boolean |
true |
track_messages |
boolean |
true |
track_voice |
boolean |
true |
track_members |
boolean |
true |
track_commands |
boolean |
true |
track_command_performance |
boolean |
false |
track_per_channel_voice |
boolean |
false |
retention_days |
number |
Globally configured default (90) |
public_stats_page |
boolean |
false |
Extending
Consuming AnalyticsCollector in other modules
import { AnalyticsCollector, type CommandExecutedPayload } from '@zumito-team/analytics-module';
import { ServiceContainer } from 'zumito-framework';
const collector = ServiceContainer.getService(AnalyticsCollector) as AnalyticsCollector;
// Query stats
const stats = await collector.getGuildStats(guildId, 30);
// Get top commands
const top = await collector.getTopCommands(null, 7, 5);
// Get global summary
const summary = await collector.getGlobalStatsSummary(7);
Tracking custom events
// Track custom event as a message
await collector.recordMessage(guildId);
// Track a custom metric directly via DB
const db = ServiceContainer.getService(DatabaseManager);
const repo = db.getRepository(GuildDailyStats);
await repo.insert({ id: `${guildId}_${today()}`, guild_id: guildId, date: today(), message_count: 1 });
Premium integration
Set a higher retention for premium guilds:
// In your premium module
await collector.updateConfig(guildId, { retention_days: 180 });
Data models
GuildDailyStats
Per-guild daily aggregate: id = {guild_id}_{date}
| Field | Type |
|---|---|
id |
string (PK) |
guild_id |
string |
date |
string (YYYY-MM-DD) |
message_count |
number |
join_count |
number |
leave_count |
number |
voice_minutes |
number |
command_count |
number |
member_count |
number |
CommandDailyStats
Per-command daily stats: id = {guild_id}_{command_name}_{date}
| Field | Type |
|---|---|
id |
string (PK) |
guild_id |
string |
command_name |
string |
date |
string (YYYY-MM-DD) |
usage_count |
number |
total_execution_time_ms |
number |
error_count |
number |
VoiceChannelDailyStats
Per-channel voice stats: id = {guild_id}_{channel_id}_{date}
| Field | Type |
|---|---|
id |
string (PK) |
guild_id |
string |
channel_id |
string |
date |
string (YYYY-MM-DD) |
total_minutes |
number |
unique_users |
number |
Dependencies
zumito-frameworkejs— Template rendering@zumito-team/admin-module— Optional admin panel integration@zumito-team/user-panel-module— Optional user panel integration
Related modules
- Admin Module — Panel where global bot stats appear
- User Panel — Panel where per-server stats appear
- Logger — Complementary event logging