Skip to content

Analytics Module

The Analytics Module (@zumito-team/analytics-module) tracks server activity including messages, member joins/leaves, voice channel usage, and command execution. It provides configurable per-guild settings, data retention policies, and optional web dashboard pages with Chart.js visualizations for both the admin panel (global bot stats) and user panel (per-server stats).

Terminal window
npm install @zumito-team/analytics-module

Add to your zumito.config.ts:

bundles: ['@zumito-team/analytics-module/dist']

The core service available via ServiceContainer.getService(AnalyticsCollector). Other modules can query analytics data through its public API.

MethodReturnsDescription
recordMessage(guildId)Promise<void>Track a message
recordMemberJoin(guildId)Promise<void>Track a member join
recordMemberLeave(guildId)Promise<void>Track a member leave
recordVoiceJoin(guildId, channelId, userId)Promise<void>Track voice channel join
recordVoiceLeave(guildId, channelId, userId)Promise<void>Track voice channel leave (auto-calculates duration)
recordCommand(payload)Promise<void>Track a command execution
recordMemberCount(guildId, count)Promise<void>Store current member count
getGuildStats(guildId, daysBack)Promise<GuildDailyStats[]>Daily stats for a guild
getGlobalStatsSummary(daysBack)Promise<object>Aggregated global stats
getGuildGrowth(daysBack)Promise<object[]>Active guilds per day
getMessagesPerDay(daysBack)Promise<object[]>Messages per day (global)
getCommandsPerDay(guildId, daysBack)Promise<object[]>Commands per day
getTopCommands(guildId, daysBack, limit)Promise<CommandDailyStats[]>Most used commands
getSlowestCommands(guildId, daysBack, limit)Promise<object[]>Commands by avg execution time
getVoiceChannelStats(guildId, daysBack)Promise<VoiceChannelDailyStats[]>Per-channel voice stats
getConfig(guildId)Promise<GuildAnalyticsConfig>Get guild configuration
updateConfig(guildId, partial)Promise<void>Update guild configuration
runCleanup()Promise<void>Run data retention cleanup
startCleanupScheduler()voidStart automatic cleanup
stopCleanupScheduler()voidStop automatic cleanup
clearVoiceSessions()voidClear in-memory voice sessions
CommandTypePermissionDescription
/statsSlash + PrefixEveryoneShows server stats embed (last 7 days)
/analytics-configSlash + PrefixAdmin onlyView and toggle analytics settings
/analytics-config enable/disableSubcommandAdmin onlyEnable or disable analytics
/analytics-config messagesSubcommandAdmin onlyToggle message tracking
/analytics-config voiceSubcommandAdmin onlyToggle voice tracking
/analytics-config membersSubcommandAdmin onlyToggle member tracking
/analytics-config commandsSubcommandAdmin onlyToggle command tracking
/analytics-config performanceSubcommandAdmin onlyToggle command performance tracking
/analytics-config retention <days>SubcommandAdmin onlySet data retention days
EventSourceDescription
messageCreateDiscordMessage count per guild (excludes bots)
guildMemberAddDiscordMember join count + member snapshot
guildMemberRemoveDiscordMember leave count + member snapshot
voiceStateUpdateDiscordVoice activity minutes per guild/channel
commandExecutedFrameworkCommand usage + execution time + success/failure
  • /admin/analytics — Global bot statistics dashboard:
    • Overview cards: total guilds, total messages, total commands, joins, voice minutes
    • Charts: guild growth (line), messages per day (bar), commands per day (bar), top commands (horizontal bar)
    • If command performance tracking enabled: slowest commands chart
    • Date range selector: 7 / 30 / 90 days
  • /panel/:guildId/analytics — Per-server statistics dashboard:
    • Overview cards: messages, commands, joins, leaves, voice minutes
    • Charts: messages per day (bar), joins vs leaves (line), voice activity (bar), commands per day (bar), top commands (horizontal bar)
    • If track_command_performance enabled: slowest commands chart
    • If track_per_channel_voice enabled: per-channel voice breakdown
    • Date range selector: 7 / 30 / 90 days

Configure global defaults by importing AnalyticsModuleConfig 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,
});
SettingTypeDefaultDescription
defaultRetentionDaysnumber90Days to keep data before cleanup
cleanupIntervalHoursnumber24How often cleanup runs
defaultTrackMessagesbooleantrueTrack messages by default
defaultTrackVoicebooleantrueTrack voice activity by default
defaultTrackMembersbooleantrueTrack joins/leaves by default
defaultTrackCommandsbooleantrueTrack command usage by default
defaultTrackCommandPerformancebooleanfalseTrack execution time per command
defaultTrackPerChannelVoicebooleanfalseTrack per-channel voice stats

Each guild has a GuildAnalyticsConfig record in the database. Use /analytics-config command or the public API:

const collector = ServiceContainer.getService(AnalyticsCollector);
await collector.updateConfig(guildId, {
enabled: true,
track_command_performance: true,
retention_days: 180, // premium guilds get 6 months
});
FieldTypeDefaultDescription
guild_idstringPrimary key
enabledbooleantrueMaster enable/disable
track_messagesbooleantrueTrack message counts
track_voicebooleantrueTrack voice activity
track_membersbooleantrueTrack joins/leaves
track_commandsbooleantrueTrack command usage
track_command_performancebooleanfalseTrack execution time
track_per_channel_voicebooleanfalseTrack per-channel breakdown
retention_daysnumberglobal defaultData retention period
public_stats_pagebooleanfalseMake stats page publicly accessible

Consuming AnalyticsCollector from other modules

Section titled “Consuming AnalyticsCollector from other modules”
import { AnalyticsCollector } from '@zumito-team/analytics-module';
import { ServiceContainer } from 'zumito-framework';
const collector = ServiceContainer.getService(AnalyticsCollector) as AnalyticsCollector;
// Get top commands across all servers (last 7 days)
const top = await collector.getTopCommands(null, 7, 10);
// Get global stats summary
const summary = await collector.getGlobalStatsSummary(30);
// Get per-guild stats for charts
const stats = await collector.getGuildStats(guildId, 7);

To grant premium guilds extended data retention:

// In your premium/license module
const collector = ServiceContainer.getService(AnalyticsCollector);
await collector.updateConfig(guildId, { retention_days: 180 });
import { AnalyticsCollector } from '@zumito-team/analytics-module';
class MyCommand extends Command {
async execute(params: CommandParameters) {
const collector = ServiceContainer.getService(AnalyticsCollector);
// Track custom event
await collector.recordMessage(params.message.guildId);
// ... your command logic
}
}

Per-guild daily aggregate. Composite key: {guild_id}_{date}

FieldType
idstring (PK)
guild_idstring
datestring (YYYY-MM-DD)
message_countnumber
join_countnumber
leave_countnumber
voice_minutesnumber
command_countnumber
member_countnumber

Per-command daily stats. Composite key: {guild_id}_{command_name}_{date}

FieldType
idstring (PK)
guild_idstring
command_namestring
datestring (YYYY-MM-DD)
usage_countnumber
total_execution_time_msnumber
error_countnumber

Per-channel voice stats. Composite key: {guild_id}_{channel_id}_{date}

FieldType
idstring (PK)
guild_idstring
channel_idstring
datestring (YYYY-MM-DD)
total_minutesnumber
unique_usersnumber
  • zumito-framework
  • ejs — Template rendering for panel pages
  • @zumito-team/admin-module — Optional admin panel integration
  • @zumito-team/user-panel-module — Optional user panel integration
  • Admin — Panel where global bot stats appear
  • User Panel — Panel where per-server stats appear
  • Logger — Complementary event logging