An intelligent, real-time job monitoring platform that scrapes career pages and delivers instant Telegram alerts β so you never miss a job opening again.
KAIRO is a full-stack job monitoring system built for job seekers who want to stay ahead. You add the career pages of companies you want to watch, and KAIRO automatically scrapes those pages in the background. The moment a new job link appears β matching roles like Software Engineer, Data Analyst, MTO, Management Trainee, or Corporate Officer β you instantly receive a notification directly in your personal Telegram account.
No more manually refreshing career pages. No more missing deadlines. KAIRO watches for you.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USER BROWSER β
β Next.js Dashboard (localhost:3000) β
β Sign Up β Add URLs β Connect Telegram β Done! β
ββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β Prisma ORM
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Supabase (PostgreSQL Cloud DB) β
β Tables: User, TrackedJobPage, JobListing β
ββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β psycopg2 (direct connection)
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Python Scraper (scraper/main.py) β
β Reads URLs β Scrapes HTML β Deduplicates β Inserts β
ββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β Telegram Bot API
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Your Telegram Phone β
β "π¨ NEW JOB FOUND β Apply Here β" β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | Next.js 16, React 19 | Dashboard UI, App Router |
| Styling | Tailwind CSS 4 | Utility-first styles |
| UI Components | shadcn/ui, Radix UI | Pre-built accessible components |
| Animations | Framer Motion | Smooth page transitions & effects |
| Icons | Lucide React | Consistent icon set |
| Database | Supabase (PostgreSQL) | Cloud-hosted relational database |
| ORM | Prisma 5 | Type-safe DB access for Next.js |
| Auth | Custom JWT (jose) | Signed session cookies |
| Password Hashing | bcryptjs | Secure credential storage |
| Scraping | Python + BeautifulSoup 4 | HTML parsing engine |
| HTTP Client | Python requests | Fetches career page HTML |
| Next.js Scraping | cheerio | Server-side HTML parsing in API |
| Notifications | Telegram Bot API | Instant push notifications |
| Env Management | python-dotenv | Secure credential loading |
KAIRO/
βββ app/ # Next.js App Router
β βββ page.tsx # Landing page
β βββ layout.tsx # Root layout
β βββ globals.css # Global styles
β βββ login/page.tsx # Login page
β βββ signup/page.tsx # Sign up page
β βββ api/
β β βββ auth/
β β β βββ signin/route.ts # POST: authenticate user
β β β βββ signup/route.ts # POST: register user
β β βββ scrape/route.ts # POST: trigger scraping for logged-in user
β β βββ user/
β β βββ telegram/route.ts # GET/POST: user's Telegram Chat ID
β βββ dashboard/
β βββ page.tsx # Main dashboard overview
β βββ layout.tsx # Dashboard shell
β βββ jobs/page.tsx # Tracked job listings
β βββ notifications/page.tsx# Notification history
β βββ preferences/page.tsx # User preferences
β βββ telegram/page.tsx # Telegram bot connection
β βββ urls/page.tsx # URL tracker management
βββ components/
β βββ dashboard/
β β βββ header.tsx # Dashboard top bar
β β βββ sidebar.tsx # Navigation sidebar
β β βββ url-tracker.tsx # URL management UI
β β βββ dashboard-client.tsx # Client-side dashboard
β β βββ job-card.tsx # Individual job display
β β βββ activity-feed.tsx # Recent activity log
β β βββ stats-card.tsx # Summary stat cards
β βββ ui/ # shadcn/ui component library (57 components)
βββ lib/
β βββ db.ts # Prisma client singleton
β βββ session.ts # JWT session helpers
β βββ telegram.ts # sendJobAlert() utility
β βββ utils.ts # General utilities
βββ prisma/
β βββ schema.prisma # Database schema (3 models)
βββ scraper/
β βββ main.py # Python scraping engine
β βββ requirements.txt # Python dependencies
βββ middleware.ts # Route protection (auth guard)
βββ .env # Environment variables (git-ignored)
βββ README.md # This file
βββ instructions.md # AI coding SOPs
model User {
id String @id @default(cuid())
email String @unique
passwordHash String
telegramChatId String? // User's personal Telegram ID
trackedPages TrackedJobPage[]
createdAt DateTime @default(now())
}
model TrackedJobPage {
id String @id @default(cuid())
url String // e.g. https://careers.brac.net
companyName String
lastScraped DateTime?
userId String
user User @relation(...)
jobs JobListing[]
createdAt DateTime @default(now())
}
model JobListing {
id String @id @default(cuid())
title String // e.g. "Senior Data Analyst"
url String @unique
trackedPageId String
trackedPage TrackedJobPage @relation(...)
createdAt DateTime @default(now())
}- Node.js 18+
- Python 3.10+
- A Supabase account (free tier works)
- A Telegram account
git clone https://github.com/ridhwankhan/JobPulse.git
cd JobPulse
npm installCreate a .env file in the root directory:
# Supabase / PostgreSQL
DATABASE_URL="postgresql://postgres:yourpassword@db.yourproject.supabase.co:5432/postgres"
DIRECT_URL="postgresql://postgres:yourpassword@db.yourproject.supabase.co:5432/postgres"
# Supabase Public Keys
NEXT_PUBLIC_SUPABASE_URL=https://yourproject.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...
# JWT Auth
JWT_SECRET=your_random_secret_here
NEXTAUTH_SECRET=your_random_secret_here
NEXTAUTH_URL=http://localhost:3000
# Telegram Bot
TELEGRAM_BOT_TOKEN="your_bot_token"
# Secure scheduled scraping (required for /api/cron/scrape)
CRON_SECRET="a_long_random_secret_value"
# Admin account email (required)
ADMIN_EMAIL="admin@example.com"
# SMTP for admin messaging (optional but recommended)
SMTP_HOST="smtp.gmail.com"
SMTP_PORT="587"
SMTP_SECURE="false"
SMTP_USER="your-email@gmail.com"
SMTP_PASS="your-app-password"
SMTP_FROM="KAIRO <your-email@gmail.com>"
β οΈ Special Character Warning: If your database password contains#, encode it as%23in the URL (e.g.,password123#βpassword123%23).
npx prisma db pushcd scraper
pip install -r requirements.txt
cd ..npm run devcurl -H "Authorization: Bearer $CRON_SECRET" http://localhost:3000/api/cron/scrapeOn Windows PowerShell:
Invoke-WebRequest -Uri "http://localhost:3000/api/cron/scrape" -Headers @{ Authorization = "Bearer $env:CRON_SECRET" }python scraper/main.pyKAIRO now includes a built-in cron endpoint: GET /api/cron/scrape.
- Add
CRON_SECRETin your deployment environment variables. - Keep
vercel.jsonin the repo with:path:/api/cron/scrapeschedule:0 9 * * *
- Vercel Hobby supports once-daily cron. This schedule runs once per day.
- The route scrapes all users who have tracked pages and sends Telegram alerts to each user's own chat ID.
- Admin account is prioritized first in scheduled scrape order.
- Normal users: manual scrape allowed once every 20 minutes.
- Admin user: no manual scrape cooldown.
If you deploy on another platform, set any scheduler (cron/job runner) to call:
- URL:
https://<your-domain>/api/cron/scrape - Header:
Authorization: Bearer <CRON_SECRET>
- Signup now collects two user-defined recovery prompts + answers.
- Forgot password uses those saved recovery prompts:
POST /api/auth/request-password-reset-otpPOST /api/auth/verify-password-reset-otp
- Account deletion now requires:
- current password
- typing
DELETEconfirmation text
- Admin dashboard:
- URL:
/dashboard/admin - Access is restricted to
ADMIN_EMAIL - Controls:
- Toggle signup open/maintenance
- View user details
- Ban/restrict users
- Force reset user password
- Send email or direct Telegram message to users (if linked)
- URL:
Each user connects their own personal Telegram for alerts:
- Open Telegram β Search
@userinfobotβ Start chat β Copy your numeric ID - Open Telegram β Search your bot (e.g.
@Kairo_Job_bot) β Click Start - Go to your KAIRO Dashboard β Telegram page
- Click Connect Telegram β Paste your Chat ID β Click Save & Connect
β From now on, every new job found for your tracked URLs will ping YOUR Telegram instantly.
The Python scraper (scraper/main.py) runs these steps:
- Fetch: Reads all
TrackedJobPageURLs and their owners'telegramChatIdfrom Supabase. - Scrape: Downloads each page's HTML using
requestswith a real browserUser-Agent. - Parse: Uses
BeautifulSoupto extract all<a>tags. - Filter: Keeps only links that:
- Contain job-role keywords (
engineer,manager,mto,data analyst, etc.) - Are NOT generic navigation phrases (
learn more,seminar,login, etc.) - Are NOT anchor (
#) or JavaScript links
- Contain job-role keywords (
- Deduplicate: Checks if the job URL already exists in
JobListing. - Alert: If it's new β inserts into DB β sends Telegram message to the user.
- Cleanup: Deletes job listings older than 10 days to keep the database lean.
engineer, developer, manager, mto, management trainee, data analyst, data scientist, corporate, associate, specialist, director, officer, executive, lead, coordinator
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/api/auth/signup |
Direct signup with recovery prompts + answers | β |
POST |
/api/auth/request-password-reset-otp |
Load saved recovery prompts for email | β |
POST |
/api/auth/verify-password-reset-otp |
Verify prompt answers and reset password | β |
POST |
/api/auth/signin |
Login, sets session cookie | β |
DELETE |
/api/user/account |
Delete account (requires password + DELETE) |
β |
POST |
/api/scrape |
Scrape all user's URLs, send alerts | β |
GET |
/api/user/telegram |
Get current user's Telegram Chat ID | β |
POST |
/api/user/telegram |
Save user's Telegram Chat ID | β |
GET |
/api/admin/users |
List users for admin dashboard | β Admin |
POST |
/api/admin/users/status |
Ban/restrict user | β Admin |
POST |
/api/admin/users/force-reset-password |
Admin force reset user password | β Admin |
POST |
/api/admin/message |
Admin send email/Telegram to users | β Admin |
- Auto-Scrape Scheduler: Windows Task Scheduler / cron job guide to auto-run Python scraper daily
- Scrape from Dashboard: "Scrape Now" button on the URL Tracker page calls
/api/scrape - Real-time Job Feed: Dashboard Jobs page shows live data from Supabase instead of mock data
- Pagination: Add pagination to job listings for users with many tracked URLs
- Toast Notifications: In-app browser toasts when a new scrape completes
- User-specific keyword filters: Each user can set custom keywords beyond the defaults
- Company logos: Auto-fetch favicon/logo for each tracked company
- Notification history: Store and display the last 30 Telegram alerts per user
- Email digest: Daily email summary of new jobs found (optional alternative to Telegram)
- AI Job Matching: Use a lightweight LLM to score job relevance against the user's profile/resume
- Resume upload: Users can upload a PDF resume; the AI uses it to filter which jobs are actually relevant
- Duplicate title detection: Fuzzy match job titles to prevent near-duplicate alerts
- LinkedIn / Bdjobs integration: Native API connectors for major job boards
- Browser extension: Chrome extension to add any page as a tracked URL in one click
- Job trend charts: Track how many new jobs were found per company per week
- Application tracker: Mark jobs as Applied / Interviewing / Rejected
- Best time to apply: Analytics on when companies post new jobs (by day/hour)
- Vercel deployment: One-click deploy with environment variable guide
- Subscription tiers: Free (5 tracked URLs), Pro (unlimited + AI matching)
- Team accounts: Share a tracked URL list with a study group or team
- Admin dashboard: Monitor all users, scraping health, and system metrics
- Passwords are hashed with bcrypt (10 salt rounds) β never stored in plain text.
- Sessions use signed JWT tokens (HS256) stored in
httpOnlycookies. - All dashboard routes are protected by
middleware.tsβ unauthenticated requests are redirected. - Recovery answers are hashed before storage and never exposed as plain text.
- Accounts can be banned/restricted from admin dashboard.
- Basic per-IP API rate limiting is enabled in middleware to reduce abuse/spam bursts.
.envand other local secret files are git-ignored β never commit credentials.- Supabase connection string is kept server-side only (not exposed to the browser).
Before pushing to GitHub:
- Confirm
.envis not tracked:git status --short .env
- Verify no hardcoded secrets in code:
rg "postgresql://|TELEGRAM_BOT_TOKEN|SMTP_PASS|JWT_SECRET|sb_publishable_" .
- Use env variables for all runtime secrets:
- DB, JWT, Telegram bot token, SMTP, admin email, cron secret.
MIT License β feel free to fork, modify, and use this project.
Built with β€οΈ to help job seekers in Bangladesh and beyond never miss an opportunity.