AcadBot is a Telegram bot that acts as a personal academic assistant for university students. Point it at any university website and it will scrape, index, and answer questions about results, notices, study material, events, timetables, and more — all in a natural chat interface.
No setup needed. Just open Telegram and search for @AcadBot (or the deployed bot username).
- Send
/start - Send your university website URL when asked
- If your portal requires login, the bot will ask for your credentials (encrypted at rest)
- The bot crawls your university site (~1–2 min) and is ready
That's it — no account, no app, no installation.
| Feature | Description |
|---|---|
| 💬 AI Chat | Groq (Llama 3.3 70B) as primary model, Google Gemini 2.0 Flash as automatic fallback |
| 🏫 University Scraper | Crawls any university website (login-protected or public) and indexes all content |
| 📄 PDF Q&A | Upload any PDF and chat with it — fully local, no external API cost |
| 🔍 Resource Search | Semantic + keyword search over scraped university pages |
| 🔒 Secure Credentials | University login credentials encrypted with Fernet before storage |
| 🗄️ Shared Index | Multiple students from the same university share one scrape — efficient |
| Command | Description |
|---|---|
/start |
Onboard (new user) or greet returning user |
/setup |
Change or re-index your university |
/resource |
Search for notices, results, study material, events |
/pdf_qna |
Upload a PDF and chat with it |
/clear |
Clear chat history and active PDF session |
/help |
Show all commands |
Student (Telegram)
│
▼
AcadBot (Railway)
┌──────────────────────────────────────────────────────┐
│ │
│ AI Chat ──────────► Groq (Llama 3.3 70B) │
│ └──► Gemini 2.0 Flash (fallback) │
│ │
│ Uni Info ─────────► Scraper (requests+BS4) │
│ └──► Qdrant Cloud (vectors) │
│ │
│ PDF Q&A ──────────► pdfplumber → FAISS (in-memory) │
│ │
│ Database ──────────► PostgreSQL (Railway addon) │
└──────────────────────────────────────────────────────┘
/start
└─► New user? → "What's your university URL?"
└─► Auto-detect login required
├─► No → scrape in background thread
└─► Yes → ask username → ask password (encrypted)
└─► scrape with credentials
└─► index in Qdrant → bot ready
| Component | Technology | Hosted At | Cost |
|---|---|---|---|
| Bot runner | Python + pyTelegramBotAPI | Railway | Free |
| Chat model | Groq API (Llama 3.3 70B) | Groq Cloud | Free |
| Chat fallback | Google Gemini 2.0 Flash | Google AI | Free |
| Embeddings | sentence-transformers (all-MiniLM-L6-v2) | Railway (local) | Free |
| Vector store | Qdrant | Qdrant Cloud | Free (1 GB) |
| Database | PostgreSQL | Railway addon | Free |
| PDF extraction | pdfplumber | Railway (local) | Free |
| Web scraping | requests + BeautifulSoup | Railway (local) | Free |
| Encryption | cryptography (Fernet) | Railway (local) | Free |
Total running cost: $0/month
AcadBot/
├── main.py # Bot entry point — all commands, state machine, onboarding
├── Procfile # Railway: tells it to run main.py as a worker
├── railway.json # Railway deploy config
├── requirements.txt
├── .env.example # Template — copy to .env and fill in keys
│
├── function/
│ ├── chat.py # Groq + Gemini fallback, per-user history
│ ├── rag.py # Qdrant (university) + FAISS (PDF sessions)
│ ├── scraper.py # Universal university crawler + login handler
│ ├── database.py # PostgreSQL schema and queries
│ ├── res.py # Resource finder (RAG → DB → static fallback)
│ └── pdflinks.txt # Static fallback resource links
│
└── website/ # Companion website (Netlify)
| Service | What it's for | Link |
|---|---|---|
| Telegram | Create a bot token | @BotFather |
| Railway | Host the bot + PostgreSQL | railway.app |
| Groq | Free LLM API | console.groq.com |
| Google AI Studio | Gemini fallback API | aistudio.google.com |
| Qdrant Cloud | Vector database | cloud.qdrant.io |
git clone https://github.com/AniketMishra23/AcadBot.git
cd AcadBota) Connect repo
- Go to railway.app → New Project → Deploy from GitHub repo
- Select
AniketMishra23/AcadBot
b) Add PostgreSQL
- In your Railway project → Add Service → Database → PostgreSQL
- Railway automatically sets
DATABASE_URLas an environment variable
c) Set environment variables
In Railway → your service → Variables, add:
BOT_TOKEN = your telegram bot token
GROQ_API_KEY = from console.groq.com
GEMINI_API_KEY = from aistudio.google.com
QDRANT_URL = from Qdrant Cloud cluster console
QDRANT_API_KEY = from Qdrant Cloud cluster console
ENCRYPTION_KEY = generated below
Generate your ENCRYPTION_KEY (run once locally):
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"d) Deploy
Railway auto-deploys on every push to main. The Procfile tells it to run python main.py as a background worker (not a web server — no port needed).
pip install -r requirements.txt
cp .env.example .env # fill in your keys
python main.pyFor local PostgreSQL you can use Neon (free serverless Postgres) and paste the connection string as DATABASE_URL.
Scrape university pages
│
▼
Extract text + PDF links per page
│
▼
Split into 500-char chunks (80-char overlap)
│
▼
Embed with all-MiniLM-L6-v2 (384-dim vectors)
│
▼
Upsert into Qdrant Cloud ← filtered by uni_id
│
┌─────┘ on student query
▼
Embed the question
│
▼
Top-5 nearest chunks from Qdrant (same uni_id)
│
▼
Injected as context into LLM prompt
│
▼
LLM answers, citing source page titles
PDF uploads use the same chunking and embedding, but stored in a per-user in-memory FAISS index (not Qdrant) — ephemeral, cleared when the user types stop.
The scraper automatically classifies every crawled page:
| Type | Keywords detected |
|---|---|
result |
result, marksheet, grade, score, merit list, cgpa |
notice |
notice, circular, announcement, notification, bulletin |
event |
event, seminar, workshop, conference, webinar, fest |
material |
syllabus, notes, lecture, study material, question paper |
timetable |
timetable, schedule, routine, exam date, academic calendar |
admission |
admission, enroll, registration, application, fee |
general |
everything else |
- University passwords are never stored in plain text
- Encrypted with Fernet symmetric encryption before writing to PostgreSQL
- The
ENCRYPTION_KEYin your environment is required to decrypt — never lose it .envis excluded from git via.gitignore
- Freemium model (usage limits + Telegram Stars payments)
- Scheduled re-scraping (auto-refresh university content daily)
- Playwright support for JavaScript-heavy university portals
- Multi-language support
Pull requests are welcome. Open an issue first for major changes.
MIT