A Telegram bot that summarizes group chat conversations using Google's Gemini AI.
- π Smart Summaries: Get concise summaries of group discussions using AI
- β° Time-Based: Summarize the last hour, 6 hours, day, or week (max 7 days)
- π¬ Reply to Summarize: Reply to any message to summarize from that point
- π Auto-Summarization: Messages are automatically summarized before deletion (48 hours)
- π Summary History: Summaries are kept for 2 weeks before permanent deletion
- π Per-Group API Keys: Each group uses its own Gemini API key
- π Encrypted Storage: API keys are encrypted at rest
- βοΈ Customizable: Customize summary style, filters, and scheduled summaries
- π PostgreSQL: Uses PostgreSQL for reliable data storage
- ποΈ Auto-Delete: Messages are automatically deleted after 48 hours
- Node.js 18+
- PostgreSQL database (Supabase, Neon, Railway, etc.)
- Telegram Bot Token (from @BotFather)
- Google Gemini API Key (from Google AI Studio)
- Clone the repository:
git clone <your-repo-url>
cd tldreply-bot- Install dependencies:
npm install- Create a
.envfile based onenv.example:
cp env.example .env- Configure your environment variables:
TELEGRAM_TOKEN=your_telegram_bot_token
DATABASE_URL=postgresql://user:password@host:port/database
ENCRYPTION_SECRET=your_random_secret_min_32_chars- Set up the database:
# Connect to your PostgreSQL database and run:
psql $DATABASE_URL < src/db/schema.sql- Run the bot:
# Development
npm run dev
# Production
npm run build
npm startPublic Groups (have @username):
- Add the bot to your Telegram group
- Disable privacy mode: Go to @BotFather β
/setprivacyβ Select your bot β Choose "Disable" - Open a private chat with the bot
- Run
/setup_group @your_group_username - Provide your Gemini API key when prompted
- Start using
/tldrin your group!
Private Groups (no @username):
- Add the bot to your Telegram group
- Disable privacy mode: Go to @BotFather β
/setprivacyβ Select your bot β Choose "Disable" - Run
/setupdirectly in your group (the bot automatically detects the chat ID!) - Open a private chat with your bot
- Run
/continue_setupand provide your Gemini API key when prompted - Start using
/tldrin your group!
Alternative Method (if needed):
If you prefer the manual method, you can still use /setup_group <chat_id> in private chat. To get the chat ID:
- Add @userinfobot to your group
- Forward any message from your group to @userinfobot to get the chat ID
- Use that ID with
/setup_group(e.g.,/setup_group -123456789)
Private Chat:
/start- Welcome message and help/help- Show detailed help with examples/continue_setup- Complete a pending group setup/setup_group @groupor/setup_group chat_id- Configure a group manually (alternative method)/list_groups- List all your configured groups/update_api_key <chat_id>- Update API key for a group/remove_group <chat_id>- Remove a group configuration
Group Chat:
/setup- Start group setup (easiest method - auto-detects chat ID!)/tldr [range] [@user] [style] [topic]- Get summary with the Standard Command RuleReply to message+/tldr- Summarize from that message to now/tldr_info- Show group configuration and status/tldr_helpor/help- Show help for group commands/tldr_settings- Manage summary settings (admin only)- Customize summary style (default, detailed, brief, bullet, timeline)
- Set custom prompts
- Configure message filtering
- Set up scheduled summaries
/schedule- Set up automatic daily/weekly summaries (admin only)/filter- Configure message filtering (admin only)- Exclude bot messages
- Exclude commands
- Exclude specific users
/enable- Enable TLDR bot for this group (admin only)/disable- Disable TLDR bot for this group (admin only)
Time-based summaries:
/tldr # Summarize last hour (default)
/tldr 1h # Summarize last hour
/tldr 6h # Summarize last 6 hours
/tldr day # Summarize last day
/tldr week # Summarize last week
/tldr 3d # Summarize last 3 days (max 7 days)
/tldr 30h # Summarize last 30 hoursCount-based summaries:
/tldr 300 # Summarize last 300 messages
/tldr 1000 # Summarize last 1000 messages
/tldr 50 # Summarize last 50 messagesFocused & User summaries:
/tldr @username # Summarize only messages from @username
/tldr 1d @username # @username's talk in the last day
/tldr Secret Santa # Focus on a specific topic (semantic search)
/tldr 500 meeting # Focus on "meeting" in last 500 messages
/tldr 6h brief @user party # Combined: last 6h, brief style, from @user, about "party"To make usage predictable, follow this standard order:
/tldr [range] [@username] [style] [topic]
- Range:
1h,6h,day, or message count100 - @username: Filter messages from a specific user
- Style:
brief,detailed,bullet, ortimeline - Topic: Any words to focus the summary on a specific subject
Reply-based summaries:
Reply to any message with: /tldr
This summarizes from that message to now
Settings (admin only):
/tldr_settings # Open settings menu
/schedule # Configure automatic summaries
/filter # Configure message filtering
/enable # Enable bot
/disable # Disable bot
π Important Privacy Information:
- Messages are temporarily cached in the database to enable historical summaries
- Automatic deletion: All cached messages are deleted after 48 hours
- No permanent storage: The bot never stores messages permanently
- API keys: Your Gemini API keys are encrypted at rest using AES-256
- Bot privacy mode: Make sure to disable privacy mode via @BotFather (
/setprivacy) so the bot can read all messages in the group
The bot only stores messages it receives after being added to a group. It cannot access messages sent before it joined.
- Fork this repository
- Go to railway.app and create an account
- Click "New Project" β "Deploy from GitHub"
- Select your fork
- Add environment variables:
TELEGRAM_TOKEN- Your bot tokenDATABASE_URL- PostgreSQL connection string (use Supabase for free DB)ENCRYPTION_SECRET- Generate withopenssl rand -hex 32NODE_ENV- Set toproduction
- Bot will auto-deploy!
Free hosting stack:
- Supabase (free PostgreSQL tier)
- Google Gemini (free AI tier)
This project includes a GitHub Actions workflow for automated deployment to a VPS server.
- A VPS server with SSH access
- Node.js and PM2 installed on the VPS
- The project directory
/var/www/tldreply(will be created automatically)
-
Configure GitHub Secrets: Go to your repository β Settings β Secrets and variables β Actions β New repository secret
Add the following secrets:
VPS_HOST: Your VPS IP address (e.g.,111.xxx.x.x)VPS_USERNAME: Your VPS username (e.g.,username)VPS_PASSWORD: Your VPS password
-
Initial VPS Setup: SSH into your VPS and run:
# Install Node.js (if not already installed) curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs # Install PM2 globally sudo npm install -g pm2 # Create project directory (if needed) sudo mkdir -p /var/www/tldreply sudo chown -R $USER:$USER /var/www/tldreply
-
Configure Environment Variables: On your VPS, create a
.envfile in/var/www/tldreply:cd /var/www/tldreply cp env.example .env nano .env # Edit with your actual values
-
Deploy:
- Push to the
mainbranch to trigger automatic deployment - Or manually trigger via GitHub Actions β Deploy to VPS β Run workflow
- Push to the
The workflow will:
- Build the TypeScript project
- Deploy to
/var/www/tldreplyon your VPS - Install production dependencies
- Restart the PM2 process automatically
Note: Make sure your VPS user has sudo access and password authentication is enabled for SSH (or configure SSH keys for better security).
- Bot Framework: grammY
- AI: Google Gemini
- Database: PostgreSQL
- Encryption: AES-256-CBC with PBKDF2 key derivation
- API keys: Encrypted using AES-256-CBC with PBKDF2 key derivation
- Isolated keys: Each group uses its own isolated API key
- No plain text: API keys are never stored in plain text
- SSL connections: All database connections use SSL in production
- SQL Injection Protection: All database queries use parameterized statements
- User messages containing SQL strings are safely stored as text data
- SQL commands in messages are never executed
- Example: A message like
"'; DROP TABLE messages; --"will be stored as text, not executed
- Input Validation: Timeframe inputs are validated and limited (max 7 days)
- Rate Limiting: Commands are rate-limited to prevent abuse
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License
For issues or questions, please open an issue on GitHub.