Job Radar
A daily job-intelligence pipeline that merges hundreds of remote postings, filters them with config-driven rules and scores the survivors against my profile with an explainable formula.
- Role
- Solo: design, build, deployment
- Period
- 2026
- Status
- Deployed on a GCP Always Free VM, scheduled daily at 07:00 Tunis time
- Stack
- n8n, Docker, GCP e2-micro, Google Sheets, Groq, Gemini, Discord, REST APIs, RSS
- Links
- Repository
The problem
Remote junior roles in automation and GTM engineering are scattered across a dozen boards, most postings are a poor fit (wrong seniority, wrong region, a language I do not speak), and reading them by hand every morning does not scale. I wanted a ranked shortlist with reasons, built at no cost, that I could tune without touching code.
What I built
One n8n workflow, deployed on a free cloud VM, runs every morning.
- Sources
- Filter before the model
- Extract and score
- DeliverWrites matches, ops, Discord
- My reviewI give every match a verdict (good, false positive, applied). The verdicts drive the next tuning change.
Config tabThresholds, keyword lists and weights, with a revision number for every change.
- Ingest. 12 sources are wired and 11 enabledSource: workflow export and config tab. October 2026.: public APIs, RSS feeds and community job boards. Each source has its own mapper and its own filters, because each has its own noise.
- Filter before the LLM. Deduplication by URL, a posting-age window, remote-only, a senior-title veto and banned phrases. Only a capped batch moves on: at most 15 postings per runSource: config tab slice_cap (v4). October 2026..
- Extract and score. An LLM returns strict JSON (seniority, work policy, languages, visa mention, contract-friendliness). A weighted formula combines it with rule-based fit and recency: 0.40 match, 0.25 filter fit, 0.20 feasibility and 0.15 recency, with a pass mark of 65Source: SPEC v3.2 section 8. September 2026..
- Deliver. Matches go to a sheet with the reason and red flags for each, telemetry goes to an ops tab, and a Discord digest lists the best ones.
All thresholds, keyword lists and weights live in a config tab. Tuning is a sheet edit with a revision number, never a code change.
Decisions that mattered
ADR-JR-08Dynamic config in a sheet tab
- Context
- Thresholds and keyword lists changed weekly during tuning.
- Decision
- A key/value config tab, parsed by a Load Config node with typed coercion, defaults and a warnings list.
- Trade-offs
- Every behavior change is a sheet edit; a bad value falls back to its default with a warning instead of breaking the run.
ADR-JR-17Calibration as data
- Context
- Output quality tuning tempted code edits.
- Decision
- All quality tuning happens in the config tab with a rev bump: one variable per change, one ops row as evidence.
- Trade-offs
- Slower tuning, but every change is traceable to a run.
ADR-JR-16GCP Always Free VM for deployment
- Context
- The pipeline must run daily at $0 without the laptop on.
- Decision
- Docker on a GCP e2-micro Always Free VM, port bound to localhost and reached through an SSH tunnel, with a $1 budget alert as an alarm.
- Trade-offs
- Small VM (swap required); no public UI exposure by design.
What broke, and what I changed
A provider outage. On 15 September Groq returned 401 and one Gemini model returned 404, and the remaining route scored 24 of 24 postingsSource: ops tab 2026-09-15 09:33. 15 September 2026.. The run finished on the last route in the chain, which is why the chain exists.
An n8n update blocked environment variables. On 21 September a run failed with ‘access to env vars denied’ for every provider, and it was fixed and re-run 14 minutes later with 25 of 25 scoredSource: ops tab 2026-09-21. 21 September 2026.. The ops row showed the exact error for every provider, so the fix took one setting, not a debugging session.
Results
- active job sources (12 wired)
- 11Source: workflow export and config tab. October 2026.
- postings merged per full run
- 466 to 617Source: ops tab, full runs. September 2026.
- at most this many reach the LLM per run
- 15Source: config tab slice_cap (v4). October 2026.
- infrastructure cost
- $0Source: SPEC v3.2. September 2026.
What I would do next
- Finish calibration: one week of reviewed matches, then set the score threshold at the elbow of the distribution.
- Reuse the router and config pattern in other workflows (the Personal GTM Engine already does).