← back to Dear Bubbe Nextjs

scripts/twitter-report.js

97 lines

#!/usr/bin/env node

const fs = require('fs').promises;
const path = require('path');

const LOGS_DIR = path.join(__dirname, '..', 'logs');
const STATS_FILE = path.join(LOGS_DIR, 'twitter-stats.json');
const POSTED_FILE = path.join(LOGS_DIR, 'posted-tweets.json');

async function generateReport() {
  try {
    // Load stats
    const statsData = await fs.readFile(STATS_FILE, 'utf-8');
    const stats = JSON.parse(statsData);
    
    // Load posted tweets
    const postedData = await fs.readFile(POSTED_FILE, 'utf-8');
    const posted = JSON.parse(postedData);
    
    console.log('═══════════════════════════════════════════════════════════════');
    console.log('           🐦 DEAR BUBBE TWITTER PERFORMANCE REPORT 🐦           ');
    console.log('═══════════════════════════════════════════════════════════════');
    console.log();
    
    // Overall stats
    console.log('📊 OVERALL STATISTICS');
    console.log('─────────────────────');
    console.log(`📅 Started: ${new Date(stats.startDate).toLocaleString()}`);
    console.log(`📝 Total Posts: ${stats.totalPosts}`);
    console.log(`🕐 Last Post: ${stats.lastPostTime ? new Date(stats.lastPostTime).toLocaleString() : 'Never'}`);
    console.log();
    
    // Daily breakdown
    console.log('📈 DAILY BREAKDOWN');
    console.log('─────────────────');
    const days = Object.keys(stats.dailyPosts).sort();
    days.forEach(day => {
      const count = stats.dailyPosts[day];
      const percentage = (count / 100 * 100).toFixed(1);
      const bar = '█'.repeat(Math.floor(count / 2));
      console.log(`${day}: ${bar} ${count}/100 (${percentage}%)`);
    });
    console.log();
    
    // Engagement tracking
    console.log('🎯 ENGAGEMENT FEATURES USED');
    console.log('────────────────────────');
    const withMentions = stats.engagementTracking.filter(e => e.hasMention).length;
    const withHashtags = stats.engagementTracking.filter(e => e.hasHashtags).length;
    console.log(`@ Celebrity Mentions: ${withMentions} tweets`);
    console.log(`# Viral Hashtags: ${withHashtags} tweets`);
    console.log();
    
    // Recent tweets
    console.log('📝 LAST 5 TWEETS');
    console.log('────────────────');
    const recentTweets = posted.slice(-5).reverse();
    recentTweets.forEach((tweet, i) => {
      console.log(`${i + 1}. ${new Date(tweet.timestamp).toLocaleString()}`);
      console.log(`   ${tweet.text.substring(0, 100)}...`);
      console.log(`   ID: ${tweet.id}`);
      console.log();
    });
    
    // Recommendations
    console.log('💡 RECOMMENDATIONS');
    console.log('─────────────────');
    const avgPostsPerDay = stats.totalPosts / Math.max(1, days.length);
    
    if (avgPostsPerDay < 50) {
      console.log('⚠️  Posting below 50% capacity - increase frequency');
    } else if (avgPostsPerDay < 80) {
      console.log('✅ Good posting rate - aim for 80+ posts/day');
    } else {
      console.log('🌟 Excellent posting rate! Maximizing API usage');
    }
    
    if (withMentions < stats.totalPosts * 0.1) {
      console.log('📢 Increase celebrity mentions for viral potential');
    }
    
    console.log('🎯 Continue posting during peak hours (7-9pm EST)');
    console.log('📊 Monitor engagement metrics on Twitter Analytics');
    console.log();
    
    console.log('═══════════════════════════════════════════════════════════════');
    console.log('         Report generated at', new Date().toLocaleString());
    console.log('═══════════════════════════════════════════════════════════════');
    
  } catch (error) {
    console.log('No stats available yet. Twitter poster needs to run first.');
    console.log('Error:', error.message);
  }
}

// Run report
generateReport().catch(console.error);