Aperçu
Les chercheurs d'emploi perdent des heures chaque jour à consulter les mêmes sites. Ce workflow n8n s'exécute quotidiennement, recherche sur Google des offres d'emploi selon vos critères via Scavio, dédoublonne par rapport aux résultats précédents et envoie uniquement les nouvelles correspondances vers Slack ou par e-mail. Zéro code, 250 crédits gratuits/mois couvrent les recherches.
Déclencheur
Quotidiennement à 7h00 via le déclencheur Cron de n8n.
Planification
Quotidien
Étapes du workflow
Déclencher selon un planning
Le nœud Cron de n8n s'exécute quotidiennement à 7h00. Fuseau horaire configurable.
Rechercher des offres d'emploi via le nœud HTTP Scavio
Le nœud HTTP Request appelle l'API de recherche Scavio avec des requêtes liées à l'emploi. Retourne des résultats structurés.
Filtrer les résultats liés à l'emploi
Le nœud Function filtre les résultats pour ne conserver que ceux contenant des mots-clés liés à l'emploi dans le titre.
Dédoublonner par rapport aux exécutions précédentes
Compare les URL avec une liste stockée d'offres déjà vues. Ne conserve que les nouvelles annonces.
Envoyer les nouvelles offres vers Slack ou par e-mail
Formate les nouvelles annonces et les envoie via webhook Slack ou nœud e-mail.
Implémentation Python
import requests, os, json
from pathlib import Path
API_KEY = os.environ["SCAVIO_API_KEY"]
H = {"x-api-key": API_KEY, "Content-Type": "application/json"}
SEEN_FILE = Path("seen_jobs.json")
JOB_QUERIES = [
"python developer remote jobs 2026",
"senior backend engineer remote",
"machine learning engineer hiring 2026",
]
def search_jobs(query: str) -> list:
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers=H,
json={"query": query, "country_code": "us"},
timeout=10,
)
results = resp.json().get("organic_results", [])
job_keywords = ["job", "hiring", "career", "position", "apply", "opening", "vacancy"]
return [{"title": r.get("title", ""), "url": r.get("link", ""), "snippet": r.get("snippet", "")}
for r in results if any(kw in r.get("title", "").lower() for kw in job_keywords)]
def daily_job_search():
seen = set(json.loads(SEEN_FILE.read_text())) if SEEN_FILE.exists() else set()
new_jobs = []
for q in JOB_QUERIES:
jobs = search_jobs(q)
for j in jobs:
if j["url"] not in seen:
new_jobs.append(j)
seen.add(j["url"])
SEEN_FILE.write_text(json.dumps(list(seen)))
return new_jobs
new_jobs = daily_job_search()
print(f"Found {len(new_jobs)} new job listings")
for j in new_jobs[:5]:
print(f" {j['title']}: {j['url']}")Implémentation JavaScript
const H = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
const fs = await import('fs');
const JOB_QUERIES = ['python developer remote jobs 2026', 'senior backend engineer remote', 'machine learning engineer hiring 2026'];
async function searchJobs(query) {
const r = await fetch('https://api.scavio.dev/api/v1/search', {method:'POST', headers:H, body:JSON.stringify({query, country_code:'us'})});
const results = (await r.json()).organic_results || [];
const kws = ['job','hiring','career','position','apply','opening','vacancy'];
return results.filter(r=>kws.some(k=>(r.title||'').toLowerCase().includes(k))).map(r=>({title:r.title, url:r.link, snippet:r.snippet}));
}
async function dailyJobSearch() {
let seen = new Set();
try { seen = new Set(JSON.parse(fs.readFileSync('seen_jobs.json','utf8'))); } catch {}
const newJobs = [];
for (const q of JOB_QUERIES) {
for (const j of await searchJobs(q)) {
if (!seen.has(j.url)) { newJobs.push(j); seen.add(j.url); }
}
}
fs.writeFileSync('seen_jobs.json', JSON.stringify([...seen]));
return newJobs;
}
const newJobs = await dailyJobSearch();
console.log('Found '+newJobs.length+' new job listings');
for (const j of newJobs.slice(0,5)) console.log(' '+j.title+': '+j.url);Plateformes utilisées
Recherche web avec graphe de connaissances, PAA et aperçus IA