Case studyDaily Job Watcher
An automated job-search pipeline I built for myself and run every two hours. It checks 70 company job boards and careers sites, scores each posting against my background, and sends new matches to my phone, my inbox and a Google Sheet where I track applications.
Python, asyncio, httpx, GitHub Actions, Google Sheets API, pytest. The repository is private; I’m happy to walk through it.
What I built
A scheduled Python job on GitHub Actions. Each run fetches every source in parallel, normalizes the postings, filters and scores them, compares them with what it has already seen, and sends only what is new.
70 sources
→↓
Adapters: one per job-board system
→↓
Filter and score
→↓
Seen-jobs state
→↓
Push, email digest, Google Sheet
- Adapters for Greenhouse, Ashby, Lever, Workday, Workable and amazon.jobs, plus the Microsoft, Google and Apple careers sites, turn every posting into one common record.
- Filter rules live in YAML: excluded titles, Seattle and US-remote location rules, points for role, level, company priority and pay. Tuning needs no code changes.
- An experience parser reads the required years from each description and ignores “preferred” and “nice to have” sections.
- State is committed back to the repository after every run, so each job alerts once. A job that disappears is closed; a source that fails leaves its jobs untouched.
- New matches go out as a push notification and an HTML email digest and are appended to a Google Sheet. Runs with nothing new send one silent “No new jobs” push.
- A health alert goes out once when a source fails two runs in a row, rather than on every failed run.