ANALYTICS PLUGIN - nself-org/nchat GitHub Wiki
Version: 1.0.0 Category: infrastructure Port: 3106 Status: Production Ready
The Analytics & Insights plugin provides comprehensive business intelligence and data analytics capabilities for ɳChat. It collects, aggregates, and visualizes platform metrics to help administrators understand user behavior, platform health, and business performance.
- Active users (online, hourly, daily, monthly, yearly)
- Message volume and trends
- Channel activity heatmaps
- User engagement scores
- Platform health indicators
- User lifecycle tracking (new, active, returning, churned)
- Retention cohorts
- Feature adoption rates
- User journey mapping
- Login/activity patterns
- Channel growth trends
- Message distribution across channels
- Peak activity times
- Average response times
- Channel participation rates
- Most shared files and media
- Popular topics (keyword extraction)
- Emoji usage statistics
- Link sharing patterns
- Hashtag trending
- Custom dashboard builder
- Scheduled reports (PDF/Excel)
- Data export API (CSV, JSON)
- Webhook notifications for milestones
- Comparative analytics (time periods)
- nself CLI v0.9.8+
- Docker and Docker Compose
- ClickHouse (for time-series data)
- Redis (for caching)
- PostgreSQL (for metadata)
cd backend
nself plugin install analyticsAdd to .env.plugins:
ANALYTICS_ENABLED=true
ANALYTICS_PORT=3106
ANALYTICS_ROUTE=analytics.${BASE_DOMAIN:-localhost}
ANALYTICS_MEMORY=512M
# Storage
ANALYTICS_CLICKHOUSE_HOST=clickhouse
ANALYTICS_CLICKHOUSE_PORT=8123
ANALYTICS_CLICKHOUSE_DATABASE=nchat_analytics
ANALYTICS_CLICKHOUSE_USER=default
ANALYTICS_CLICKHOUSE_PASSWORD=
# Features
ANALYTICS_RETENTION_DAYS=365
ANALYTICS_AGGREGATION_INTERVAL=300 # 5 minutes
ANALYTICS_ENABLE_ML_INSIGHTS=true
ANALYTICS_ENABLE_ANOMALY_DETECTION=true
# Performance
ANALYTICS_BATCH_SIZE=1000
ANALYTICS_FLUSH_INTERVAL=30000 # 30 seconds
ANALYTICS_CACHE_TTL=300 # 5 minutesnself restartcurl http://analytics.localhost:3106/health
# Should return: {"status":"healthy","version":"1.0.0"}Event Sources → Redis Streams → Aggregator → ClickHouse → API → Frontend
↓
Cache (Redis)
-
Event Collector
- Listens to application events
- Validates and enriches event data
- Batches events for performance
-
Data Aggregator
- Processes raw events every 5 minutes
- Calculates metrics (counts, averages, percentiles)
- Stores aggregated data in ClickHouse
-
Query Engine
- Serves dashboard requests
- Generates custom reports
- Handles real-time queries
-
Cache Layer
- Caches frequently accessed metrics
- Reduces database load
- Improves response times
-
Alert Manager
- Monitors metric thresholds
- Sends notifications
- Triggers webhooks
GET /api/analytics/dashboard?period=30dResponse:
{
"overview": {
"activeUsers": {
"current": 1234,
"previous": 1100,
"change": "+12.2%"
},
"messages": {
"total": 45678,
"average": 1522,
"trend": "up"
},
"channels": {
"total": 156,
"active": 89,
"engagement": "57%"
}
},
"charts": {
"activeUsers": [...],
"messageVolume": [...],
"channelActivity": [...]
}
}GET /api/analytics/users?period=7d&metric=engagementQuery Parameters:
-
period: Time range (1d, 7d, 30d, 90d, 365d, all) -
metric: Metric type (engagement, retention, adoption, activity) -
groupBy: Group by dimension (day, week, month) -
limit: Number of results (default: 100)
Response:
{
"period": "7d",
"metric": "engagement",
"data": [
{
"userId": "user-123",
"name": "Alice Johnson",
"messageCount": 245,
"channelsActive": 12,
"engagementScore": 87,
"lastActive": "2026-02-03T10:30:00Z"
}
],
"summary": {
"totalUsers": 1234,
"activeUsers": 789,
"averageEngagement": 72
}
}GET /api/analytics/channels?sort=activity&limit=20Response:
{
"channels": [
{
"channelId": "channel-456",
"name": "general",
"memberCount": 234,
"messageCount": 1234,
"messagesPerDay": 176,
"peakHour": "14:00",
"engagementRate": "68%",
"growth": "+15%"
}
]
}GET /api/analytics/messages?period=30dResponse:
{
"total": 45678,
"byType": {
"text": 38456,
"image": 4567,
"file": 1890,
"video": 567,
"voice": 198
},
"averagePerDay": 1522,
"peakDay": "2026-02-01",
"peakDayCount": 2345,
"trends": {
"images": "+23%",
"videos": "+45%",
"voice": "-5%"
}
}POST /api/analytics/reports
Content-Type: application/json
{
"name": "Weekly Executive Summary",
"period": "7d",
"metrics": [
"activeUsers",
"messageVolume",
"channelGrowth",
"engagement"
],
"format": "pdf",
"schedule": "0 9 * * 1", # Every Monday at 9am
"recipients": ["[email protected]"]
}GET /api/analytics/export?format=csv&period=30d&metrics=users,messagesFormats: csv, json, excel
POST /api/analytics/track
Content-Type: application/json
{
"event": "feature_used",
"userId": "user-123",
"properties": {
"feature": "voice_message",
"duration": 45,
"quality": "high"
}
}GET /api/analytics/insights?period=30dResponse:
{
"insights": [
{
"type": "trend",
"severity": "info",
"message": "Message volume increased 23% this week",
"recommendation": "Consider adding more channels"
},
{
"type": "anomaly",
"severity": "warning",
"message": "User churn rate increased 15%",
"recommendation": "Review user feedback"
}
]
}- Online: Currently connected (WebSocket active)
- Hourly: Active in last 60 minutes
- Daily: Active in last 24 hours (DAU)
- Weekly: Active in last 7 days (WAU)
- Monthly: Active in last 30 days (MAU)
Calculated as: (messages_sent * 2 + reactions * 1 + files_shared * 3) / days_active
- 0-30: Low engagement
- 31-60: Medium engagement
- 61-100: High engagement
- Day 1: Percentage of users active 1 day after signup
- Day 7: Percentage of users active 7 days after signup
- Day 30: Percentage of users active 30 days after signup
- Active Channels: Channels with messages in last 7 days
- Dormant Channels: Channels with no messages in last 30 days
- Growing Channels: Channels with +20% message volume
Access at /admin/analytics
Sections:
- Overview Cards (active users, messages, channels, files)
- Activity Trends (line chart)
- Top Channels (table)
- Top Users (table)
- Recent Activity (timeline)
Access at /admin/analytics/users
Views:
- User List (sortable, filterable)
- Cohort Analysis
- Retention Curves
- Engagement Heatmap
Access at /admin/analytics/channels
Views:
- Channel Activity Grid
- Growth Trends
- Message Distribution
- Peak Hours Heatmap
Access at /admin/analytics/reports
Features:
- Visual report builder
- Saved report templates
- Scheduled delivery
- Export options
SELECT
user_id,
COUNT(*) as message_count,
COUNT(DISTINCT channel_id) as channels_active,
MIN(timestamp) as first_message,
MAX(timestamp) as last_message
FROM analytics_events
WHERE
event_type = 'message_sent'
AND timestamp >= NOW() - INTERVAL 7 DAY
GROUP BY user_id
ORDER BY message_count DESC
LIMIT 20;SELECT
DATE(timestamp) as date,
COUNT(DISTINCT user_id) as dau
FROM analytics_events
WHERE timestamp >= NOW() - INTERVAL 30 DAY
GROUP BY DATE(timestamp)
ORDER BY date;WITH current_week AS (
SELECT channel_id, COUNT(*) as count
FROM analytics_events
WHERE event_type = 'message_sent'
AND timestamp >= NOW() - INTERVAL 7 DAY
GROUP BY channel_id
),
previous_week AS (
SELECT channel_id, COUNT(*) as count
FROM analytics_events
WHERE event_type = 'message_sent'
AND timestamp >= NOW() - INTERVAL 14 DAY
AND timestamp < NOW() - INTERVAL 7 DAY
GROUP BY channel_id
)
SELECT
c.channel_id,
c.count as current_count,
p.count as previous_count,
ROUND((c.count - p.count) * 100.0 / p.count, 2) as growth_rate
FROM current_week c
LEFT JOIN previous_week p ON c.channel_id = p.channel_id
ORDER BY growth_rate DESC;import { useAnalytics } from '@/hooks/use-analytics'
function DashboardPage() {
const { data, loading, error } = useAnalytics({
period: '30d',
metrics: ['activeUsers', 'messages', 'channels']
})
if (loading) return <Loading />
if (error) return <Error message={error.message} />
return (
<div>
<h1>Analytics Dashboard</h1>
<MetricsOverview data={data.overview} />
<ActivityChart data={data.charts.activeUsers} />
</div>
)
}import { trackEvent } from '@/services/analytics'
function FeatureComponent() {
const handleFeatureUse = () => {
trackEvent('feature_used', {
feature: 'voice_message',
duration: 45
})
}
return <button onClick={handleFeatureUse}>Send Voice</button>
}- Use materialized views for aggregations
- Partition tables by date
- Add indexes on frequently queried columns
-- Create materialized view
CREATE MATERIALIZED VIEW analytics_daily_metrics AS
SELECT
DATE(timestamp) as date,
COUNT(DISTINCT user_id) as dau,
COUNT(*) as total_events,
COUNT(CASE WHEN event_type = 'message' THEN 1 END) as messages
FROM analytics_events
GROUP BY DATE(timestamp);
-- Partition table
ALTER TABLE analytics_events
PARTITION BY toYYYYMM(timestamp);
-- Add indexes
ALTER TABLE analytics_events
ADD INDEX idx_user_time (user_id, timestamp);# Increase cache TTL for static metrics
ANALYTICS_CACHE_TTL=600 # 10 minutes
# Enable query result caching
ANALYTICS_CLICKHOUSE_QUERY_CACHE=true# Increase batch size for bulk inserts
ANALYTICS_BATCH_SIZE=5000
# Reduce flush frequency
ANALYTICS_FLUSH_INTERVAL=60000 # 1 minuteSymptoms: Plugin using >1GB RAM
Solutions:
- Reduce retention period
- Increase aggregation interval
- Enable query result caching
ANALYTICS_RETENTION_DAYS=180 # Reduce from 365
ANALYTICS_AGGREGATION_INTERVAL=600 # 10 minutesSymptoms: Dashboard taking >5 seconds to load
Solutions:
- Create materialized views
- Add indexes
- Use query profiling
-- Profile slow query
EXPLAIN ANALYZE
SELECT ...;
-- Create covering index
CREATE INDEX idx_covering ON analytics_events(user_id, timestamp, event_type);Symptoms: Gaps in analytics data
Solutions:
- Check event collector is running
- Verify Redis connection
- Review aggregation logs
# Check collector status
nself logs analytics | grep "Collector"
# Verify Redis
redis-cli ping
# Review logs
nself logs analytics --tail 100- Data Retention: Keep 90-365 days based on storage capacity
- Aggregation: Use 5-minute intervals for real-time, hourly for historical
- Sampling: Sample high-volume events (e.g., views) at 10% for large platforms
- Caching: Cache dashboard queries for 5-10 minutes
- Indexes: Add indexes on frequently filtered columns (user_id, channel_id, timestamp)
- Machine learning insights
- Anomaly detection improvements
- Predictive analytics
- User behavior modeling
- Real-time dashboards (WebSocket)
- Custom metric definitions
- A/B testing framework
- Attribution tracking
-
Documentation:
/docs/plugins/ANALYTICS-PLUGIN.md - Issues: https://github.com/nself-org/plugins/issues
- Discord: https://discord.gg/nself
Last Updated: 2026-02-03 Version: 1.0.0