Skip to main content
Track your Telegram bot’s performance with comprehensive statistics and analytics. Monitor subscriber growth, revenue, and user engagement.

Bot Stats Command

View real-time statistics from Telegram:
/botstats
Only the admin (defined in ADMIN_ID config) can use this command.

Sample Output

📊 Bot Usage Statistics (Admin)

━━━━━━━━━━━━━━━━━━━

👥 Users:
• Total Bot Users: 450
• Unique Subscribers: 180
• Non-paying Users: 270

💎 Subscriptions:
• Active VIP Members: 85
• Active MT5 Copiers: 22

💰 Financials:
• Total Revenue: ₦2,340,000

📅 Latest Active Subscribers:
• John Doe (@johndoe) - PREMIUM (Ends: 12/31/2024)
• Jane Smith (@janesmith) - MONTHLY (Ends: 12/25/2024)
• Bob Wilson (@bobwilson) - BASIC (Ends: 12/20/2024)
... and 82 more

━━━━━━━━━━━━━━━━━━━

Note: "Total Bot Users" includes everyone who ever 
clicked /start or messaged the bot since tracking was enabled.

Metrics Explained

1

Total Bot Users

Every unique user who has:
  • Clicked /start
  • Sent any message to the bot
  • Interacted with bot commands
This represents your total reach, including free users.
2

Unique Subscribers

Number of users who have made at least one payment. Includes:
  • Active subscriptions
  • Expired subscriptions
  • All plan types
This is your conversion rate denominator.
3

Non-paying Users

Users who interacted but never subscribed. These are:
  • Potential customers
  • Targets for remarketing
  • Conversion optimization opportunity
Formula: Total Bot Users - Unique Subscribers
4

Active VIP Members

Current paying subscribers with:
  • expiresAt > current date
  • isRemoved: false
  • Any plan type
Your current MRR is based on these users.
5

Active MT5 Copiers

Premium users with:
  • Completed MT5 setup
  • setupStatus: 'active'
  • Active subscription
Represents high-value customers.
6

Total Revenue

Lifetime revenue across all transactions:
  • Sum of all amountKobo / 100
  • Includes expired subscriptions
  • Excludes refunds (if any)

API Analytics Endpoint

Get detailed statistics via the API:
curl https://your-domain.com/api/admin/broadcast \
  -H "Authorization: Bearer YOUR_ADMIN_SECRET"

Response Format

{
  "stats": {
    "totalUniqueUsers": 450,
    "totalSubscribers": [
      {
        "planType": "basic",
        "_count": {"telegramUserId": 80}
      },
      {
        "planType": "biweekly",
        "_count": {"telegramUserId": 45}
      },
      {
        "planType": "monthly",
        "_count": {"telegramUserId": 120}
      },
      {
        "planType": "premium",
        "_count": {"telegramUserId": 55}
      }
    ],
    "activeSubscribers": [
      {
        "planType": "basic",
        "_count": {"telegramUserId": 20}
      },
      {
        "planType": "biweekly",
        "_count": {"telegramUserId": 15}
      },
      {
        "planType": "monthly",
        "_count": {"telegramUserId": 40}
      },
      {
        "planType": "premium",
        "_count": {"telegramUserId": 22}
      }
    ]
  }
}

Key Performance Indicators

Conversion Rate

Conversion Rate = (Unique Subscribers / Total Bot Users) × 100
Example:
  • Total Bot Users: 450
  • Unique Subscribers: 180
  • Conversion Rate: 40%
Industry benchmark: 15-25% for paid subscription bots. 40%+ is excellent.

Monthly Recurring Revenue (MRR)

Calculate based on active subscribers:
const activeSubs = await prisma.subscription.findMany({
  where: {
    expiresAt: { gt: new Date() },
    isRemoved: false
  }
})

// Calculate MRR
let mrr = 0
activeSubs.forEach(sub => {
  const planDays = PLANS[sub.planType].durationDays
  const monthlyValue = (sub.amountKobo / 100) * (30 / planDays)
  mrr += monthlyValue
})

console.log(`MRR: ₦${mrr.toFixed(2)}`)

Churn Rate

Churn Rate = (Expired Subs Last Month / Active Subs Start of Month) × 100
Example Calculation:
const startOfMonth = new Date('2024-12-01')
const endOfMonth = new Date('2024-12-31')

// Active at start of month
const activeStart = await prisma.subscription.count({
  where: {
    startedAt: { lt: startOfMonth },
    expiresAt: { gte: startOfMonth },
    isRemoved: false
  }
})

// Expired during month
const churned = await prisma.subscription.count({
  where: {
    expiresAt: { gte: startOfMonth, lt: endOfMonth },
    isRemoved: false
  }
})

const churnRate = (churned / activeStart) * 100
console.log(`Churn Rate: ${churnRate.toFixed(1)}%`)
Target churn rate: <10% monthly. Above 20% indicates serious retention issues.

Premium Adoption Rate

Premium Rate = (Premium Subscribers / Total Subscribers) × 100
Higher premium adoption = higher revenue per user.

Average Revenue Per User (ARPU)

ARPU = Total Revenue / Unique Subscribers
Example:
  • Total Revenue: ₦2,340,000
  • Unique Subscribers: 180
  • ARPU: ₦13,000
This tells you the average lifetime value of a customer.

Database Queries for Analytics

Revenue by Plan Type

const revenueByPlan = await prisma.subscription.groupBy({
  by: ['planType'],
  _sum: { amountKobo: true },
  _count: { id: true }
})

revenueByPlan.forEach(plan => {
  console.log(`${plan.planType}: ₦${(plan._sum.amountKobo || 0) / 100} (${plan._count.id} subs)`)
})
Output:
basic: ₦400,000 (80 subs)
biweekly: ₦450,000 (45 subs)
monthly: ₦1,800,000 (120 subs)
premium: ₦1,210,000 (55 subs)

Subscription Growth Over Time

const monthlyGrowth = await prisma.subscription.groupBy({
  by: ['startedAt'],
  _count: { id: true },
  orderBy: { startedAt: 'asc' }
})

// Group by month
const byMonth = {}
monthlyGrowth.forEach(record => {
  const month = record.startedAt.toISOString().substring(0, 7)
  byMonth[month] = (byMonth[month] || 0) + record._count.id
})

console.log(byMonth)
// { "2024-10": 45, "2024-11": 62, "2024-12": 73 }

User Retention Cohorts

// Users who renewed at least once
const renewals = await prisma.subscription.groupBy({
  by: ['telegramUserId'],
  _count: { id: true },
  having: {
    id: { _count: { gt: 1 } }
  }
})

const renewalRate = (renewals.length / uniqueSubscribers) * 100
console.log(`Renewal Rate: ${renewalRate.toFixed(1)}%`)
Target renewal rate: 30-50% is healthy for subscription businesses.

MT5 Setup Completion Rate

const premiumUsers = await prisma.subscription.count({
  where: {
    hasCopierAccess: true,
    expiresAt: { gt: new Date() }
  }
})

const mt5Setups = await prisma.mt5Setup.count({
  where: { setupStatus: 'active' }
})

const setupRate = (mt5Setups / premiumUsers) * 100
console.log(`MT5 Setup Rate: ${setupRate.toFixed(1)}%`)
Low setup rates indicate onboarding friction.

Custom Reports

Daily Revenue Report

const today = new Date()
today.setHours(0, 0, 0, 0)

const todayRevenue = await prisma.subscription.aggregate({
  where: {
    startedAt: { gte: today }
  },
  _sum: { amountKobo: true },
  _count: { id: true }
})

console.log(`Today: ₦${(todayRevenue._sum.amountKobo || 0) / 100} from ${todayRevenue._count.id} sales`)

Top Spending Users

const topUsers = await prisma.subscription.groupBy({
  by: ['telegramUserId', 'telegramName'],
  _sum: { amountKobo: true },
  _count: { id: true },
  orderBy: { _sum: { amountKobo: 'desc' } },
  take: 10
})

topUsers.forEach((user, i) => {
  console.log(`${i+1}. ${user.telegramName}: ₦${(user._sum.amountKobo || 0) / 100} (${user._count.id} purchases)`)
})

Expiring Subscriptions

const nextWeek = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)

const expiringSoon = await prisma.subscription.findMany({
  where: {
    expiresAt: { gte: new Date(), lte: nextWeek },
    isRemoved: false
  },
  orderBy: { expiresAt: 'asc' }
})

console.log(`${expiringSoon.length} subscriptions expiring in next 7 days`)
Use this for retention campaigns.

Monitoring & Alerts

Set Up Daily Alerts

Create a cron job to send daily stats:
// Run daily at 9 AM
cron.schedule('0 9 * * *', async () => {
  const stats = await getBotStats()
  
  await sendMessage(ADMIN_ID, `
📊 <b>Daily Report</b>

💰 Revenue (24h): ₦${stats.dailyRevenue}
📈 New Subs: ${stats.newSubscribers}
⏰ Expiring Today: ${stats.expiringToday}
👥 Active Users: ${stats.activeUsers}
  `)
})

Alert on Low Conversion

if (conversionRate < 15) {
  await sendMessage(ADMIN_ID, `
⚠️ <b>Alert: Low Conversion Rate</b>

Conversion Rate: ${conversionRate.toFixed(1)}%

Check marketing funnel and pricing.
  `)
}

Alert on High Churn

if (churnRate > 20) {
  await sendMessage(ADMIN_ID, `
🚨 <b>Alert: High Churn Rate</b>

Churn Rate: ${churnRate.toFixed(1)}%

Review content quality and user satisfaction.
  `)
}

Visualization & Dashboards

Export Data for Charts

Export to JSON for visualization tools:
const analyticsData = {
  overview: {
    totalUsers: 450,
    subscribers: 180,
    revenue: 2340000,
    mrr: 850000
  },
  byPlan: revenueByPlan,
  growth: monthlyGrowth,
  churnRate: 12.5,
  conversionRate: 40
}

fs.writeFileSync('analytics.json', JSON.stringify(analyticsData, null, 2))
Import into Google Sheets, Excel, or BI tools.

Create Visual Reports

Use libraries like Chart.js or D3.js to create dashboards:
// Example: Revenue trend chart
const chartData = {
  labels: ['Oct', 'Nov', 'Dec'],
  datasets: [{
    label: 'Revenue',
    data: [780000, 920000, 1200000]
  }]
}

Build docs developers (and LLMs) love