Automated job discovery for software engineering internships
FreshRoles monitors LinkedIn for new job postings, scores them against your profile using AI, and sends real-time notifications to your phone via ntfy.
- LinkedIn Monitoring: Scrapes LinkedIn job search using Playwright + cookies
- AI Matching: Uses Ollama embeddings to score jobs against your profile
- Real-time Notifications: Push notifications via ntfy.sh
- Customizable Profiles: Define your ideal role, skills, and location preferences
- US-Only Filtering: Built-in filters for US-based positions
# Clone the repo
git clone https://github.com/WutIsHummus/FreshRoles.git
cd FreshRoles
# Create virtual environment
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # Linux/Mac
# Install dependencies
pip install -e .
pip install playwright beautifulsoup4
playwright install chromium- Log into LinkedIn in your browser
- Export cookies using a browser extension (e.g., "Cookie-Editor")
- Save as
cookies.jsonin the project root
- Install the ntfy app on your phone
- Subscribe to a topic (e.g.,
my-job-alerts) - Use that topic name with the
--ntfy-topicflag
For best results, install Ollama for local AI embeddings:
# Install Ollama from ollama.com, then:
ollama serve # Start the server
ollama pull nomic-embed-text # Download the embedding modelpython -m freshroles monitor \
--query "software engineer intern" \
--ntfy-topic my-job-alertsCreate your profile in configs/profiles/your_name.yaml:
name: your_name
desired_roles:
- Software Engineer Intern
- Backend Intern
- Full Stack Intern
must_have_keywords:
- intern
must_not_keywords:
- senior
- staff
- 5+ years
preferred_locations:
- United States
- Remote
remote_preference: remote
min_score_threshold: 0.15| Variable | Default | Description |
|---|---|---|
TPR_SECONDS |
86400 | Lookback window (24h) |
FRESHROLES_NTFY_TOPIC |
- | ntfy topic for notifications |
# Monitor continuously (main command)
python -m freshroles monitor --query "software engineer intern" --ntfy-topic my-topic
# One-time LinkedIn scan
python -m freshroles scan-linkedin --query "backend intern" --location "Texas"
# Match existing jobs against profile
python -m freshroles match --profile configs/profiles/your_name.yaml
# Create a new profile interactively
python -m freshroles create-profileFreshRoles/
├── freshroles/
│ ├── adapters/ # LinkedIn scraper
│ ├── matching/ # AI scoring + keyword matching
│ ├── notify/ # ntfy notifications
│ ├── storage/ # SQLite database
│ └── cli.py # Main CLI
├── configs/
│ ├── profiles/ # User profiles (YAML)
│ └── companies/ # Company configs (optional)
├── cookies.json # LinkedIn cookies (you create this)
└── freshroles.db # SQLite database (auto-created)
- Python 3.11+
- Playwright (for LinkedIn scraping)
- Ollama (optional, for AI matching)
- Scrape: Uses Playwright + cookies to fetch LinkedIn job search results
- Parse: Extracts job data from HTML/embedded JSON
- Deduplicate: Checks SQLite database for already-seen jobs
- Score: Uses Ollama embeddings + keyword matching to score jobs
- Notify: Sends matching jobs to ntfy.sh
- Repeat: Polls every 5 minutes (configurable)
MIT License - See LICENSE
Pull requests welcome! Please open an issue first to discuss changes.