How jeffy-sajan/ai-job-hunter works
Purpose and execution
AI Job Hunter is a scheduled Python batch pipeline that discovers entry-level Python/tech roles, ranks them against a configurable candidate profile, deduplicates results, and alerts a Telegram chat. The local entry point is main.py; scheduled execution is defined in .github/workflows/job-hunter.yml.
Pipeline orchestration
main.py coordinates source collection, fallback behavior, matching, persistence, and notifications. It aggregates normalized job records from scrapers; when primary collection fails or yields no results, it can use mock data from scraper/mock.py. This is a one-run-at-a-time batch workflow rather than a web service.
Job-source acquisition boundary
Source adapters isolate each provider’s API, HTML, or feed format behind fetch functions:
• scraper/remoteok.py for RemoteOK API data
• scraper/naukri.py for Naukri search scraping
• scraper/indeed.py for Indeed acquisition
• Additional/backup adapters: scraper/google_jobs.py, scraper/rss_jobs.py, scraper/infopark.py, and scraper/technopark.py
These modules form the external-network boundary and are susceptible to provider blocking, markup changes, and unavailable feeds.
Candidate profile and eligibility filtering
Profile inputs and defaults are centralized in config.py. Resume-oriented skill extraction/normalization is handled by matcher/resume_profile.py, including environment-provided skill overrides for CI use. matcher/job_filters.py applies role and entry-level eligibility rules, defining the domain boundary for MCA/CS-oriented roles and fresher/intern or 0–1-year opportunities.
Relevance scoring
matcher/scorer.py converts job/profile overlap into a match score used to decide which eligible jobs are worth alerting. The scoring stage consumes the normalized source record plus configured or extracted skills, separating source-specific parsing from candidate-specific decision logic.
Persistence and duplicate control
database/db.py owns SQLite access and the seen-job state stored under data/jobs.db. The pipeline queries/inserts jobs before notification so repeated scheduled runs do not resend prior listings. SQLite is the only durable state layer; GitHub Actions runners may require persistence handling outside the ephemeral runner if cross-run deduplication is expected.
Notification delivery and runtime infrastructure
notifier/telegram.py sends selected new matches through the Telegram Bot API using bot token and chat ID environment configuration. config.py supplies runtime configuration, while .github/workflows/job-hunter.yml supplies the recurring six-hour GitHub Actions runtime and secret injection. Local runs use the same Python process and can load .env-based credentials.
Main entry points: main.py Batch orchestrator · db.py SQLite seen-job store · resume_profile.py Resume profile · scorer.py Match scorer
Components 15
Execution
- GitHub Actions schedule · Runs the pipeline every six hours and injects secrets.
.github/workflows/job-hunter.yml - Batch orchestrator · Coordinates collection, fallback, matching, deduplication, and alerts.
main.py - Runtime config · Centralizes profile defaults and runtime settings.
config.py
Job Sources
Provider adapters isolate external formats.
- RemoteOK adapter
scraper/remoteok.py - Naukri adapter
scraper/naukri.py - Indeed adapter
scraper/indeed.py - Backup source adapters · Google Jobs, RSS, Infopark, and Technopark acquisition.
scraper/google_jobs.py - Mock fallback jobs · Used when primary collection fails or is empty.
scraper/mock.py
Candidate Matching
- Resume profile · Normalizes candidate skills and CI environment overrides.
matcher/resume_profile.py - Eligibility filters · Keeps MCA/CS-oriented entry-level roles.
matcher/job_filters.py - Match scorer · Scores eligible jobs by profile-skill overlap.
matcher/scorer.py
State & Delivery
- SQLite seen-job store · Checks and records jobs before notification.
database/db.py - Job state database · Durable deduplication state; runner persistence is required across ephemeral runs.
data/jobs.db - Telegram notifier · Sends selected new matches through the Bot API.
notifier/telegram.py - Telegram Bot API
Connections 17
- GitHub Actions schedule → Batch orchestrator: scheduled run
- Runtime config → Batch orchestrator: settings
- Batch orchestrator → RemoteOK adapter: collects jobs
- Batch orchestrator → Naukri adapter: collects jobs
- Batch orchestrator → Indeed adapter: collects jobs
- Batch orchestrator → Backup source adapters: collects jobs
- Batch orchestrator → Mock fallback jobs: fallback
- Runtime config → Resume profile: profile defaults
- Batch orchestrator → Resume profile: builds profile
- Batch orchestrator → Eligibility filters: normalized jobs
- Resume profile → Match scorer: skills
- Eligibility filters → Match scorer: eligible jobs
- Batch orchestrator → SQLite seen-job store: checks and records
- SQLite seen-job store → Job state database: SQLite access
- Match scorer → Telegram notifier: new qualifying matches
- SQLite seen-job store → Telegram notifier: only unseen jobs
- Telegram notifier → Telegram Bot API: Bot API message