A battle-tested, fully open source & libre Telegram bot that served 30,000+ users/month at its peak
Fast lookups β’ Full-text search β’ Smart announcement subscriptions β’ Real-time notifications
Everything the official website should've been, but isn't.
No ads. No tracking. 100% libre and will always remain so.
Important
This bot just got a major rewrite. This branch (grammy-rewrite) contains the new architecture built on GrammY. The legacy implementation lives in the prod branch.
Read the story: Why I rewrote this entire thing
Note
This project is currently in autopilot/maintenance mode. Core functionality depends on public KTU endpoints that can change without notice. If you want to help maintain, extend, or fork it β you're more than welcome. β€οΈ
KTU Bot is a Telegram bot that helps students do everything they could (and should) do on the official KTU website β check announcements, timetables, academic calendars, results, and more. The official site is notoriously clunky and frequently crashes when you actually need it, so this bot taps into their public APIs to deliver a reliable experience the website can't.
What started as a quick 50-line script to check my own results eventually became a lifeline for tens of thousands of students. It turned into the default go-to during results season, sparked a wave of similar tools, and carved out its own identity.
- π Full-text search across announcements, academic calendars, and exam timetables β find what you need right from the chat
- π Browse historical data β announcements, exam timetables, academic calendars, all in one place
- β‘ Smart subscriptions β get only the announcements that matter to you using filters (course, type), delivered the moment they arrive
- π Results lookup (currently broken, not the bot's fault β read why)
Tip
Check out the Commonly Asked Questions for answers to common questions like "Why isn't results working?" and "Will the bot keep working?"
The bot follows a microservices architecture where each component handles a specific responsibility. If one service fails, others keep running.
| Component | Type | What It Does |
|---|---|---|
| Bot | GrammY Telegram bot | Handles all user interactions β commands, searches, conversations |
| Announcements Notify Worker | Background worker | Monitors for new announcements using BullMQ scheduled jobs and sends filtered alerts to users |
| Broadcasts Worker | Background worker | Handles queued broadcast message delivery |
| Data Sync Worker | Background worker | Periodically syncs KTU data to local DB via BullMQ scheduled jobs to power full-text search |
| Bull Board Service | Monitoring service | Web dashboard for real-time queue monitoring and job management |
| PostgreSQL | Database | Stores all data with Drizzle ORM for type-safe queries |
| Redis | Queue | Powers BullMQ jobs |
Tip
Want to understand how it all works? Check out How It Works for the complete architecture breakdown with diagrams.
- Docker + Docker Compose
- Node.js (if running locally) β this project uses
pnpm - A Telegram bot token from @BotFather
Trust me. Docker is the easiest way to run anything within seconds π
git clone https://github.com/devadathanmb/ktu-bot.git
cd ktu-botDevelopment environment files live in the dev/ directory. Each service/module has its own .env file.
Minimum required:
dev/bot.envβ SetBOT_TOKENandBOT_FILE_UPLOAD_CHANNEL_ID- Most files come prefilled with sensible defaults
Optional (for extra features):
dev/api.envβ For UptimeRobot monitoring, file uploads, etc.dev/llm.envβ For AI-powered announcement filtering
Note
Most environment variables needed for the development setup come pre-configured in each .env file.
However, some configurations depend on external services and are left as placeholder values. Fill those in with actual credentials if you plan to use those features.
Important
For sensitive local secrets:
cp .env.dev.example .env.dev
# Add your personal API keys, tokens, or credentials hereThis file is mounted last in Docker Compose, so values here override anything in dev/*.env files.
Warning
If you don't configure certain .env variables, those features simply won't work or the zod validations may get triggered. Review each file to see what's needed.
docker compose -f docker-compose.dev.yaml down -v --remove-orphans && \
docker compose -f docker-compose.dev.yaml up --buildThis starts all services with hot-reload enabled. Code changes trigger automatic restarts.
If you don't need the workers:
docker compose -f docker-compose.dev.yaml up ktu-bot-app --buildTip
Database migrations are generated and run automatically via the ktu-bot-db-migrations service.
Once everything is up, talk to your bot in Telegram!
Need just the notification worker? No problem:
# Announcements notify worker
docker compose -f docker-compose.dev.yaml up announcements-notify-worker --build
# Data sync worker
docker compose -f docker-compose.dev.yaml up data-sync-worker --build
# Broadcasts worker
docker compose -f docker-compose.dev.yaml up broadcasts-worker --buildTip
Each service exposes a health check endpoint (e.g., http://localhost:3000/health)
There's also a dedicated bull-board-service running on port 3010 that provides a Bull Board UI for monitoring background workers and queues. Access it at http://localhost:3010
Production uses a single .env file approach for simplicity.
cp .env.prod.example .env
# Edit .env and fill in all required values
# Most values come pre-configured β just update anything specific to your deployment.docker compose down -v --remove-orphans && \
docker compose up -d --buildcurl -f http://localhost:3000/health- All services communicate over an internal Docker network
- Database migrations run automatically on startup
- Make sure all required API keys/tokens are provided
- If some keys are missing, update the code to handle their absence gracefully
- Language: TypeScript β Because type-safe code is always better?
- Bot Framework: GrammY β Modern, type-safe Telegram bot framework
- Database: PostgreSQL β Powerful relational DB with god knows how many features
- ORM: Drizzle β Type-safe SQL queries and migrations
- Job Queue: BullMQ β Reliable background job processing
- HTTP Client: got β Modern fetch wrapper
Contributions are welcome! Whether it's bug fixes, new features, documentation improvements, or ideas β all are appreciated.
Tip
Need help getting started? Check out How It Works to understand the architecture.
Tip
New to Telegram Bot ecosystem? Check out this awesome getting started guide from GrammY.
Found a bug? Have an idea? Want to discuss something?
Open an issue: https://github.com/devadathanmb/ktu-bot/issues
When reporting bugs, please try to include:
- What you were trying to do?
- What happened instead?
- Steps to reproduce (if reproducible)
- How It Works β Complete architecture breakdown with diagrams
- The Rewrite Story β Why I rewrote this and some commonly asked questions
GPL-3.0 β See LICENSE for details.
This means you can use, modify, and distribute this code freely, but you must:
- Keep it open source
- Share your changes under the same license
- Give credit where it's due