A Spotify Wrapped-style statistics bot for Telegram groups. Analyzes chat exports and presents personalized statistics through an engaging 12-card text-based visual experience.
- 📊 Comprehensive Statistics: Message counts, active days, streaks, and more
- 📝 Text-Based Visual Cards: Rich HTML-formatted cards that load instantly
- 🏆 Achievement System: 70+ badges to unlock based on chat behavior
- 📈 Rankings & Percentiles: See how you compare to other group members
- 😊 Personality Analysis: Communication style, emoji personality, and more
- 🔄 Multiple Export Support: Process multiple JSON files for the same chat
- 🚀 High Performance: Handles large chat exports (1M+ messages) efficiently using streaming parsing
lhc-stats-bot/
├── src/
│ ├── bot.py # Main Telegram bot with conversation handlers
│ ├── stats_processor.py # Process Telegram exports → SQLite database
│ ├── achievements.py # Badge definitions and checking logic
│ ├── wrapped_text_cards.py # HTML-based card formatters
│ ├── utils.py # Shared utility functions
│ └── config.py # Configuration management
├── data/ # Data directory for DB and exports
├── docs/ # Documentation
├── scripts/ # Helper scripts
├── process_data.py # Unified data processing script
├── requirements.txt # Python dependencies
├── .env.example # Environment variables template
└── README.md # This file
- Python 3.10 or higher
- A Telegram bot token (get from @BotFather)
- Telegram chat export in JSON format
pip install -r requirements.txtCopy .env.example to .env and fill in your settings:
cp .env.example .envEdit .env:
TELEGRAM_BOT_TOKEN=your_bot_token_from_botfather
DB_PATH=data/chat_stats.db
GROUP_ID= # Optional: for group membership verification- Open Telegram Desktop
- Go to your group chat
- Click the three dots menu → Export chat history
- Select JSON format
- Uncheck "Photos" and other media to keep file size small
- Export to your project directory (e.g., inside
data/)
You should get a file like result.json.
Use the unified processing script to parse data and calculate achievements in one go:
# Single file
python process_data.py data/result.json
# Multiple files (for same chat across different time periods)
python process_data.py data/export1.json data/export2.json
# Or use wildcards
python process_data.py "data/*.json"This will:
- Parse all messages using efficient streaming (
ijson) - Calculate comprehensive statistics for each user
- Store everything in SQLite (
data/chat_stats.dbby default) - Compute rankings and percentiles
- Calculate achievements for all users
Start the Telegram bot:
python -m src.botThe bot will start polling and respond to commands.
- Open Telegram and find your bot
- Send
/startto see the menu - Click "🎁 Get My Wrapped" to start your personalized experience
- Tap through all 12 cards to see your stats!
| Command | Description |
|---|---|
/start |
Welcome message with menu buttons |
/wrapped |
Start the full Wrapped experience (12 cards) |
/leaderboard |
Top 10 users by message count, consistency, etc. |
/cancel |
Cancel the current Wrapped session |
Your personalized Wrapped consists of 12 cards presented as rich HTML messages:
- Welcome Card - "Your Chat Wrapped is ready!"
- Year Overview - Timeline of your activity
- Volume Stats - Total messages and daily average
- Consistency - Active days and streaks
- Content Mix - Breakdown of message types
- Communication Style - Your personality (Storyteller, Chatter, etc.)
- Emoji DNA - Your top emojis and emoji personality
- Reactions - Reactions given and received
- Top Words - Your most-used vocabulary
- Link Behavior - Link sharing stats and top domains
- Rankings - How you compare to others (percentiles)
- Achievements - Badges you've earned with rarity %
- Grand Finale - Summary and celebration
The bot features 70+ badges across 8 categories:
- Volume (8 badges): Message count milestones
- Consistency (13 badges): Streaks and dedication
- Communication Style (10 badges): Writing patterns
- Content Type (13 badges): Photos, links, stickers, etc.
- Emoji Expertise (7 badges): Emoji usage
- Reactions (8 badges): Giving and receiving reactions
- Rankings (9 badges): Top positions and percentiles
- Special Behaviors (10 badges): Single-day records, etc.
The bot matches users by Telegram user ID. The format in the database is user{telegram_id}.
If users aren't being matched correctly:
- Check the
from_idfield in your JSON export - The bot automatically handles usernames with special characters by escaping them for HTML.
Edit src/achievements.py and add to BADGE_DEFINITIONS:
"my_badge_id": {
"name": "Badge Name",
"icon": "🎯",
"category": "Category",
"description": "How to earn it",
"check": lambda s: s.get('some_stat', 0) >= 100
}Then re-run processing to update the database.
Edit src/wrapped_text_cards.py to change the text, emojis, or formatting of the cards. The system uses standard HTML formatting supported by Telegram.
The SQLite database contains:
user_stats: Main statistics for each userdaily_activity: Message counts per day per useruser_rankings: Precomputed percentile rankingsuser_achievements: Earned badgesbadge_stats: Global unlock percentagesgroup_stats: Group-level aggregates
Set up a cron job to:
- Re-export chat data (if automated)
- Re-run
process_data.py - Restart the bot (if needed)
Credit:
Word Exclude list came from @erickhammersmark https://github.com/erickhammersmark/tg_dump_anal/blob/master/exclude.txt