Automated job scanner that monitors multiple job boards, matches postings against your resume using semantic similarity (sentence-transformers), and sends alerts via Discord and/or Telegram.
config.py → All settings, API keys, resume text, thresholds
sources.py → Job source plugins (Adzuna, Remotive, Arbeitnow, USAJobs, The Muse, RSS)
matcher.py → Sentence-transformer cosine similarity engine
alerts.py → Discord webhook + Telegram bot notifications
main.py → Scheduler, deduplication, CLI entry point
# 1. Create venv
python3 -m venv venv
source venv/bin/activate
# 2. Install dependencies
pip install -r requirements.txt
# 3. Edit config.py:
# - Paste your resume into RESUME_TEXT
# - Set SEARCH_QUERIES for your target roles
# - Add API keys (Adzuna is free, Remotive/Arbeitnow need no keys)
# - Add Discord webhook URL and/or Telegram bot token
# 4. Run diagnostic first to tune your threshold
python main.py --stats
# 5. Single scan test
python main.py --once
# 6. Run on schedule (every 30 min by default)
python main.py85% is aggressive. Run --stats first to see your score distribution. If you get zero matches, try lowering to 0.60-0.70 and work up. Semantic similarity at 0.85 means "nearly identical topic and skill set" — most real job matches land in 0.55-0.80.
Recommended approach:
- Start with
SIMILARITY_THRESHOLD = 0.55 - Run
--stats, examine the histogram - Raise the threshold until you're getting 5-15 matches per scan
- Open your Discord server
- Channel Settings → Integrations → Webhooks → New Webhook
- Copy the webhook URL into
config.py
- Message @BotFather on Telegram →
/newbot→ follow prompts - Copy the bot token into
config.py - Message @userinfobot to get your chat ID
- Copy your chat ID into
config.py
tmux new -s jobscan
python main.py
# Ctrl+B, D to detach# /etc/systemd/system/jobscanner.service
[Unit]
Description=Job Scanner Bot
After=network.target
[Service]
Type=simple
User=your_username
WorkingDirectory=/path/to/job_scanner
ExecStart=/path/to/job_scanner/venv/bin/python main.py
Restart=on-failure
RestartSec=60
[Install]
WantedBy=multi-user.targetsudo systemctl enable jobscanner
sudo systemctl start jobscannerCreate a function in sources.py:
def fetch_my_source(queries: list[str]) -> list[JobPosting]:
jobs = []
# ... fetch logic ...
jobs.append(JobPosting(
title="...", company="...", description="...",
url="...", source="my_source", uid="my_source:unique_id"
))
return jobsThen register it in SOURCE_MAP and ENABLED_SOURCES.
| Command | Description |
|---|---|
python main.py |
Run continuous scanner (default 30 min interval) |
python main.py --once |
Single scan, then exit |
python main.py --stats |
Score distribution diagnostic |
python main.py --reset |
Clear seen-jobs database |