Add Gladiator Telegram bot with menu system and DM privacy #1

Merged
derekslenk merged 11 commits from feature/telegram-bot-implementation into main 2026-01-21 23:27:10 +02:00
derekslenk commented 2026-01-15 02:05:10 +02:00 (Migrated from github.com)

Summary

  • Implement full-featured Telegram bot using Grammy framework with interactive menu system
  • Add 5 menu categories (Pricing, Setup & Installation, Troubleshooting, Support & Info, Payment Options) with reply keyboard
  • Enable private DM responses in group chats to keep groups clean while providing info to users

Test plan

  • Run npm install and npm run dev to start the bot
  • Test /start command to see welcome message and reply keyboard
  • Test /, /m, or /menu commands to open the main menu
  • Test menu navigation in a private chat (should show inline)
  • Test menu navigation in a group chat (should send to DMs)
  • Test admin commands (/broadcast, /subscribers, /stats) with admin user
  • Verify video and photo album content loads correctly

🤖 Generated with Claude Code

## Summary - Implement full-featured Telegram bot using Grammy framework with interactive menu system - Add 5 menu categories (Pricing, Setup & Installation, Troubleshooting, Support & Info, Payment Options) with reply keyboard - Enable private DM responses in group chats to keep groups clean while providing info to users ## Test plan - [ ] Run `npm install` and `npm run dev` to start the bot - [ ] Test `/start` command to see welcome message and reply keyboard - [ ] Test `/`, `/m`, or `/menu` commands to open the main menu - [ ] Test menu navigation in a private chat (should show inline) - [ ] Test menu navigation in a group chat (should send to DMs) - [ ] Test admin commands (`/broadcast`, `/subscribers`, `/stats`) with admin user - [ ] Verify video and photo album content loads correctly 🤖 Generated with [Claude Code](https://claude.com/claude-code)
derekslenk commented 2026-01-15 02:10:43 +02:00 (Migrated from github.com)

Check this out @claude

Check this out @claude
claude[bot] commented 2026-01-15 02:11:01 +02:00 (Migrated from github.com)

Claude finished @derekslenk's task in 1m 53s —— View job


Code Review Complete

I've reviewed the PR and here's my comprehensive feedback:


🎯 Overall Assessment

This is a well-structured Telegram bot with impressive features. The code is clean, organized, and demonstrates good TypeScript practices. However, there are several security issues, bugs, and improvement opportunities that should be addressed.


🔴 Critical Issues

1. Hardcoded Admin IDs in Source Code (src/index.ts:26-29)

const ADMIN_IDS: number[] = [
  1042594927,
  705908928,
];

Issue: Admin user IDs are hardcoded and will be publicly visible in the repository.

Recommendation: Move to environment variables:

const ADMIN_IDS: number[] = process.env.ADMIN_IDS 
  ? process.env.ADMIN_IDS.split(',').map(id => parseInt(id.trim()))
  : [];

Fix this →

2. Sensitive URLs Exposed (src/index.ts:521-534)

Backend URLs for the IPTV services are hardcoded in menu content and will be publicly visible.

Recommendation: Consider if these URLs need protection. If they're meant to be private, move to environment variables or a separate config file that's gitignored.

3. Missing Input Validation on Broadcast Command (src/index.ts:1359-1438)

The /broadcast command doesn't sanitize or validate message content before sending to all users/groups.

Risk: Could be used to send malicious content if an admin account is compromised.

Recommendation: Add content validation and consider adding a confirmation step for broadcasts.


🟡 Moderate Issues

4. Race Condition in File ID Cache (src/index.ts:892-909)

Multiple concurrent requests could cause race conditions when reading/writing the file ID cache.

Issue: saveFileIdCache() is called asynchronously without locking, potentially corrupting the cache file.

Recommendation: Use a proper database or implement file locking, or use the existing SQLite database for file ID caching.

Fix this →

5. Inefficient Session Storage Schema (src/index.ts:79-89)

Sessions are stored as JSON TEXT in SQLite, requiring full deserialization on every read.

Impact: Performance degradation as user base grows.

Recommendation: Consider using Grammy's built-in FileAdapter or normalize the session data into proper SQL columns for better query performance.

6. Missing Error Handling in Menu Handlers

Menu handlers like those in src/index.ts:1069-1102 don't have try-catch blocks.

Risk: Unhandled errors could crash the bot or leave users with unresponsive menus.

Recommendation: Wrap menu handlers in try-catch blocks or use Grammy's error boundary patterns.

7. Potential Memory Leak in Upload Functions (src/index.ts:932-960)

The setInterval for chat actions could leak if the function throws before reaching the finally block.

Fix: Move clearInterval to a more defensive position or use a wrapper that ensures cleanup.


🟢 Minor Issues & Improvements

8. Inconsistent Error Messages

Some error handlers use "⚠️", others use "", and user-facing messages aren't always clear about what action to take.

Recommendation: Standardize error message format and always provide actionable next steps.

9. Database Not Closed on Shutdown (src/index.ts:1675-1684)

The SQLite database connection isn't explicitly closed during graceful shutdown.

Recommendation: Add storage.db.close() in shutdown handlers.

Fix this →

10. TypeScript Strictness Could Be Higher

TypeScript is in strict mode, but there are several any types that could be more specific:

  • err: any in multiple catch blocks (lines 816, 824, 864, 1396, 1416, etc.)

Recommendation: Define proper error types or use unknown and type guards.

11. Magic Numbers

  • Delay values (50ms, 4000ms) are hardcoded without explanation
  • File path constants could be centralized

Recommendation: Extract to named constants with comments explaining the values.

12. Missing Validation for Asset Files

The bot assumes asset files exist at startup but doesn't validate this.

Recommendation: Add startup validation to check all required asset files exist and log warnings if missing.

13. No Rate Limiting

The broadcast feature sends messages with only 50ms delays, which could trigger Telegram's rate limits.

Recommendation: Implement exponential backoff and respect Telegram's rate limits (30 messages/second to different users).


📋 Code Quality Observations

Strengths:

  • Well-organized menu structure with clear separation of concerns
  • Good use of TypeScript types and interfaces
  • Proper session management with persistence
  • Clean helper functions with single responsibilities
  • Graceful shutdown handling
  • File ID caching for performance (good idea, needs improvement in implementation)
  • DM privacy feature is well-implemented
  • Comprehensive menu content covering all service information

Architecture:

  • The single-file approach (1684 lines) works for now but consider splitting into modules as it grows:
    • menus/ - Menu definitions
    • handlers/ - Command handlers
    • database/ - Database logic
    • utils/ - Helper functions
    • constants/ - Menu content and config

🔒 Security Recommendations

  1. Environment Variables: Move all sensitive data to .env
  2. Input Sanitization: Validate all user inputs, especially in admin commands
  3. Principle of Least Privilege: Consider if all admin commands need to be admin-only or if some can be user-specific
  4. Audit Logging: Log all admin actions (broadcasts, etc.) for accountability
  5. Content Security: Validate file paths before accessing to prevent path traversal

📝 Documentation Issues

  1. README is outdated - Still shows basic template commands, doesn't mention:

    • Menu system
    • Admin commands
    • Subscriber system
    • Asset requirements
  2. Missing JSDoc comments for complex functions like sendMenuVideo, sendMenuPhotoAlbum

  3. No deployment guide for production environments


Test Plan Coverage

The test plan in the PR description is good but missing:

  • Test error cases (missing assets, invalid credentials, etc.)
  • Test rate limiting with multiple rapid menu clicks
  • Test with blocked users to verify cleanup
  • Test concurrent broadcast to large user base
  • Test file ID cache invalidation scenarios

🎯 Priority Recommendations

Before Merge:

  1. Fix Critical Issue #1 (hardcoded admin IDs)
  2. Add database close in shutdown handlers (#9)
  3. Update README to match actual functionality

Soon After:
4. Fix race condition in file ID cache (#4)
5. Add error handling in menu handlers (#6)
6. Implement rate limiting (#13)

Future Improvements:
7. Refactor into modular structure
8. Add comprehensive error types
9. Add startup validation for assets
10. Consider adding unit tests


Great work on this implementation! The bot has a solid foundation with excellent features. Addressing the critical security issues and the race condition will make it production-ready. 🚀


**Claude finished @derekslenk's task in 1m 53s** —— [View job](https://github.com/derekslenk/gladiator_telegram_bot/actions/runs/21014562041) --- ### Code Review Complete ✅ I've reviewed the PR and here's my comprehensive feedback: --- ### 🎯 Overall Assessment This is a **well-structured Telegram bot** with impressive features. The code is clean, organized, and demonstrates good TypeScript practices. However, there are several **security issues, bugs, and improvement opportunities** that should be addressed. --- ### 🔴 Critical Issues #### 1. **Hardcoded Admin IDs in Source Code** (src/index.ts:26-29) ```typescript const ADMIN_IDS: number[] = [ 1042594927, 705908928, ]; ``` **Issue:** Admin user IDs are hardcoded and will be publicly visible in the repository. **Recommendation:** Move to environment variables: ```typescript const ADMIN_IDS: number[] = process.env.ADMIN_IDS ? process.env.ADMIN_IDS.split(',').map(id => parseInt(id.trim())) : []; ``` [Fix this →](https://claude.ai/code?q=Move%20ADMIN_IDS%20from%20hardcoded%20values%20in%20src%2Findex.ts%3A26-29%20to%20environment%20variables.%20Update%20.env.example%20to%20include%20ADMIN_IDS%20example&repo=derekslenk/gladiator_telegram_bot&branch=feature/telegram-bot-implementation) #### 2. **Sensitive URLs Exposed** (src/index.ts:521-534) Backend URLs for the IPTV services are hardcoded in menu content and will be publicly visible. **Recommendation:** Consider if these URLs need protection. If they're meant to be private, move to environment variables or a separate config file that's gitignored. #### 3. **Missing Input Validation on Broadcast Command** (src/index.ts:1359-1438) The `/broadcast` command doesn't sanitize or validate message content before sending to all users/groups. **Risk:** Could be used to send malicious content if an admin account is compromised. **Recommendation:** Add content validation and consider adding a confirmation step for broadcasts. --- ### 🟡 Moderate Issues #### 4. **Race Condition in File ID Cache** (src/index.ts:892-909) Multiple concurrent requests could cause race conditions when reading/writing the file ID cache. **Issue:** `saveFileIdCache()` is called asynchronously without locking, potentially corrupting the cache file. **Recommendation:** Use a proper database or implement file locking, or use the existing SQLite database for file ID caching. [Fix this →](https://claude.ai/code?q=Move%20file%20ID%20cache%20from%20JSON%20file%20to%20SQLite%20database%20in%20src%2Findex.ts%20to%20prevent%20race%20conditions&repo=derekslenk/gladiator_telegram_bot&branch=feature/telegram-bot-implementation) #### 5. **Inefficient Session Storage Schema** (src/index.ts:79-89) Sessions are stored as JSON TEXT in SQLite, requiring full deserialization on every read. **Impact:** Performance degradation as user base grows. **Recommendation:** Consider using Grammy's built-in FileAdapter or normalize the session data into proper SQL columns for better query performance. #### 6. **Missing Error Handling in Menu Handlers** Menu handlers like those in src/index.ts:1069-1102 don't have try-catch blocks. **Risk:** Unhandled errors could crash the bot or leave users with unresponsive menus. **Recommendation:** Wrap menu handlers in try-catch blocks or use Grammy's error boundary patterns. #### 7. **Potential Memory Leak in Upload Functions** (src/index.ts:932-960) The `setInterval` for chat actions could leak if the function throws before reaching the `finally` block. **Fix:** Move `clearInterval` to a more defensive position or use a wrapper that ensures cleanup. --- ### 🟢 Minor Issues & Improvements #### 8. **Inconsistent Error Messages** Some error handlers use "⚠️", others use "⛔", and user-facing messages aren't always clear about what action to take. **Recommendation:** Standardize error message format and always provide actionable next steps. #### 9. **Database Not Closed on Shutdown** (src/index.ts:1675-1684) The SQLite database connection isn't explicitly closed during graceful shutdown. **Recommendation:** Add `storage.db.close()` in shutdown handlers. [Fix this →](https://claude.ai/code?q=Add%20database.close()%20call%20in%20SIGINT%2FSIGTERM%20handlers%20at%20src%2Findex.ts%3A1675-1684&repo=derekslenk/gladiator_telegram_bot&branch=feature/telegram-bot-implementation) #### 10. **TypeScript Strictness Could Be Higher** TypeScript is in strict mode, but there are several `any` types that could be more specific: - `err: any` in multiple catch blocks (lines 816, 824, 864, 1396, 1416, etc.) **Recommendation:** Define proper error types or use `unknown` and type guards. #### 11. **Magic Numbers** - Delay values (50ms, 4000ms) are hardcoded without explanation - File path constants could be centralized **Recommendation:** Extract to named constants with comments explaining the values. #### 12. **Missing Validation for Asset Files** The bot assumes asset files exist at startup but doesn't validate this. **Recommendation:** Add startup validation to check all required asset files exist and log warnings if missing. #### 13. **No Rate Limiting** The broadcast feature sends messages with only 50ms delays, which could trigger Telegram's rate limits. **Recommendation:** Implement exponential backoff and respect Telegram's rate limits (30 messages/second to different users). --- ### 📋 Code Quality Observations #### **Strengths:** - ✅ Well-organized menu structure with clear separation of concerns - ✅ Good use of TypeScript types and interfaces - ✅ Proper session management with persistence - ✅ Clean helper functions with single responsibilities - ✅ Graceful shutdown handling - ✅ File ID caching for performance (good idea, needs improvement in implementation) - ✅ DM privacy feature is well-implemented - ✅ Comprehensive menu content covering all service information #### **Architecture:** - The single-file approach (1684 lines) works for now but consider splitting into modules as it grows: - `menus/` - Menu definitions - `handlers/` - Command handlers - `database/` - Database logic - `utils/` - Helper functions - `constants/` - Menu content and config --- ### 🔒 Security Recommendations 1. **Environment Variables:** Move all sensitive data to `.env` 2. **Input Sanitization:** Validate all user inputs, especially in admin commands 3. **Principle of Least Privilege:** Consider if all admin commands need to be admin-only or if some can be user-specific 4. **Audit Logging:** Log all admin actions (broadcasts, etc.) for accountability 5. **Content Security:** Validate file paths before accessing to prevent path traversal --- ### 📝 Documentation Issues 1. **README is outdated** - Still shows basic template commands, doesn't mention: - Menu system - Admin commands - Subscriber system - Asset requirements 2. **Missing JSDoc comments** for complex functions like `sendMenuVideo`, `sendMenuPhotoAlbum` 3. **No deployment guide** for production environments --- ### ✅ Test Plan Coverage The test plan in the PR description is good but missing: - [ ] Test error cases (missing assets, invalid credentials, etc.) - [ ] Test rate limiting with multiple rapid menu clicks - [ ] Test with blocked users to verify cleanup - [ ] Test concurrent broadcast to large user base - [ ] Test file ID cache invalidation scenarios --- ### 🎯 Priority Recommendations **Before Merge:** 1. Fix Critical Issue #1 (hardcoded admin IDs) 2. Add database close in shutdown handlers (#9) 3. Update README to match actual functionality **Soon After:** 4. Fix race condition in file ID cache (#4) 5. Add error handling in menu handlers (#6) 6. Implement rate limiting (#13) **Future Improvements:** 7. Refactor into modular structure 8. Add comprehensive error types 9. Add startup validation for assets 10. Consider adding unit tests --- Great work on this implementation! The bot has a solid foundation with excellent features. Addressing the critical security issues and the race condition will make it production-ready. 🚀 ---
deco changed title from Add Gladiator Telegram bot with menu system and DM privacy to WIP: Add Gladiator Telegram bot with menu system and DM privacy 2026-01-21 04:48:50 +02:00
- Extract types.ts, storage/sqlite.ts, utils/helpers.ts, config/menu-content.json
- Reduce index.ts from 1,698 to 708 lines
- Add Vitest test framework with 57 unit tests
- Remove unused exports (safeEditMessage) and make internal helpers private
- Add comprehensive documentation (ARCHITECTURE.md, ANALYSIS.md, INDEX.md)
- Configure ADMIN_IDS via environment variable

Test coverage:
- SqliteAdapter: 93% statements, 100% functions
- FileIdCache: Full persistence testing
- Pure helpers: isGroupChat, isAdmin, getUserDisplayName, trackMenuView

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
User testing showed DM-first menu behavior created friction. Changed menu
responses to display directly in the group chat instead of sending to DMs.

- Simplified sendMenuResponse to edit message in place (both groups and DMs)
- Simplified sendMenuVideo and sendMenuPhotoAlbum to delegate to existing helpers
- Removed deep link infrastructure (setBotUsername, getDmDeepLink)
- Simplified sendMainMenu and sendSubmenu to always reply in current chat

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add BroadcastService with concurrent batching (5-10x faster broadcasts)
  - Non-blocking execution doesn't freeze bot during broadcasts
  - Automatic cleanup of inactive subscribers/groups
  - Progress callback support for status updates
  - Configurable batch size and delays for rate limiting

- Add database performance improvements to SqliteAdapter
  - Add indexes on sessions(key), subscribers(subscribed_at), groups(subscribed_at)
  - Add getAggregatedStats() for efficient stats without loading all sessions
  - Add cleanupOldSessions() for session TTL management (90 day default)
  - Add close() method for graceful shutdown

- Improve type safety in error handling
  - Change catch (err: any) to catch (err: unknown)
  - Add getErrorMessage() helper for type-safe error extraction

- Update index.ts to use new services
  - Integrate BroadcastService for non-blocking broadcasts
  - Add graceful shutdown with database close
  - Use efficient stats aggregation

- Add comprehensive test suite for BroadcastService (10 tests)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document outlines comprehensive refactoring plan to address:
- God Object anti-pattern in index.ts (688 lines -> ~50 lines)
- ~15% code duplication via Menu Factory pattern
- Mutable module state (_mainMenu variable)
- Missing service layer and dependency injection

Key design patterns:
- Menu Factory: Declarative menu definitions eliminate 35+ duplicate handlers
- Admin Decorator: Removes repeated auth check boilerplate
- Layered architecture: handlers/, menus/, middleware/, services/
- Dependency injection for testability

Includes 5-phase migration strategy with risk assessment.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major restructuring to address God Object anti-pattern:
- index.ts reduced from 688 lines to 37 lines (entry point only)
- Created bot.ts as factory with dependency injection support

New module structure:
- src/config/: Centralized configuration with validation
- src/handlers/: Command handlers (admin, user, menu, registration)
- src/menus/: Menu factory pattern with declarative definitions
- src/middleware/: Session and logging middleware
- src/utils/admin.ts: Admin decorator to eliminate auth check duplication

Key improvements:
- Menu Factory pattern eliminates ~140 lines of duplicate handler code
- adminOnly() decorator removes repeated authorization checks
- Declarative menu definitions in definitions.ts
- Clean separation of concerns across modules
- Dependency injection in createBot() enables testing

All 66 tests passing, build compiles successfully.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- FileIdCache now has LRU eviction (default 1000 max entries)
- Auto-migrates old cache format to new format with timestamps
- Added 4 new tests for LRU behavior (70 total tests)
- Rewrote CLAUDE.md to reflect modular architecture
- Added JSDoc comments to SessionData, MyContext, SqliteAdapter,
  FileIdCache, and key helper functions
- Updated dependencies: grammy 1.39.3, better-sqlite3 12.6.2

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
deco changed title from WIP: Add Gladiator Telegram bot with menu system and DM privacy to Add Gladiator Telegram bot with menu system and DM privacy 2026-01-21 23:16:44 +02:00
deco force-pushed feature/telegram-bot-implementation from 55182401f2 to d83e43deff
Some checks failed
Claude Code Review / claude-review (pull_request) Has been cancelled
2026-01-21 23:16:56 +02:00
Compare
Replace GitHub workflows with Gitea CI
Some checks failed
CI / test (push) Waiting to run
CI / test (pull_request) Has been cancelled
fc8a611027
- Add .gitea/workflows/ci.yml for test/build on push and PR
- Remove GitHub-specific Claude Code Action workflows
  (anthropics/claude-code-action is GitHub-only)

CI runs: npm ci, npm test, npm run build, tsc --noEmit

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use self-hosted runner for CI
Some checks failed
CI / test (pull_request) Failing after 10s
CI / test (push) Failing after 44s
8e1b25ee27
Remove setup-node step (already installed on runner)
All checks were successful
CI / test (push) Successful in 37s
CI / test (pull_request) Successful in 37s
dc235d826a
deco merged commit dd6bec14f9 into main 2026-01-21 23:27:10 +02:00
deco deleted branch feature/telegram-bot-implementation 2026-01-21 23:27:11 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
signal-works/gladiator_telegram_bot!1
No description provided.