- JavaScript 99.3%
- Shell 0.4%
- Dockerfile 0.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Probe hat kein residential (getProxy()->null, alle Worker datacenter); mydealz Managed Challenge blockt nacktes headless Playwright (403 cf_chl). Bypass wird (zu Recht) nicht gebaut = Umgehung der Zugangskontrolle. Kuratierter Stil-Korpus bleibt Primaerquelle. COMMENT_HARVEST_ENABLED false. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
| .forgejo/workflows | ||
| deploy | ||
| recipes | ||
| src | ||
| test | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| CONCEPT.md | ||
| Dockerfile | ||
| llm-key.txt | ||
| package.json | ||
| README.md | ||
deal-ingest
Automatische Befüllung des Deals-Portals: liest Schnäppchen aus mehreren Portalen, filtert auf Zielkategorien, bereitet sie per LLM (Ollama / OpenAI-kompatibel) auf (Titel, eigene Beschreibung, Tags), prüft den Mindestrabatt und legt sie über die Deals-Plugin-REST an — als rotierende Bot-User, optional mit LLM-Kommentaren.
Eigenständiger Dienst (Node 22, ESM), Rollout über ArgoCD mit eigener Datenbank im Cluster (CNPG). Redis ist optional und austauschbar.
Pipeline
discover (RSS/Probe) → prefilter (Heuristik) → classify (LLM bei Unsicherheit)
→ enrich (Detailseite: Merchant-Link, Preis, Bild, Gutschein, Ablauf)
→ market (price-api: günstigster Vergleichspreis) → Mindestrabatt-Gate
→ dedup (deals/v1 + lokal) → create (deals/v1, pending) → Kommentare (optional)
Zielkategorien
Smart Home, Elektronik, Computer, Homelab, Smart Gardening
(src/util/categories.js; per TARGET_CATEGORIES eingrenzbar).
Quellen
Connector je Portal in src/sources/, Recipe (Feeds) in recipes/.
Aktiv: mydealz. Geplant: DealDoktor, Schnäppchenfuchs, MonsterDealz,
Mein-Deal, Snipz. Entdeckung bevorzugt über RSS; Anti-Bot-Seiten laufen über
Probe (PROBE_BASE/PROBE_TOKEN), sonst inline via fetch.
Vollautomatische Entdeckung über Probe
Mit PROBE_ENABLED=true erzeugt der Dienst die Scrape-Aufträge selbst — es muss
nichts von Hand angelegt werden:
- Planer (
src/probe/planner.js) baut aus jedem Recipe eine Probe- Task-Group: je Einstiegspunkt (Startseite, Sucheamazon, Kategorie- Gruppen) eine Task mitnavigate+extract_list.extract_list.detailfolgt jeder Deal-Karte auf die Detailseite und zieht Merchant-Link, Preis, UVP, Bild, Gutschein und Ablauf gleich mit. - Client (
src/probe/client.js) reicht die Task-Group bei Probe ein (POST /v1/tasks) und setztoutput.callback_url+auth_token. - Callback (
/probe/callback) nimmt die Ergebnisse entgegen, verifiziert Bearer-Token (und optional die HMAC-Signatur), mappt jede Ergebniszeile übersource.fromProbe()auf einen Kandidaten und schickt sie durch dieselbe Pipeline wie die RSS-Entdeckung (Klassifikation → Mindestrabatt → Anlegen).
Der Scheduler stößt die Auftragserzeugung im Intervall PROBE_INTERVAL_S an.
Manuell prüfen/auslösen:
node src/cli.js probe-plan # Task-Groups nur anzeigen (Selektoren prüfen)
node src/cli.js probe-submit # Task-Groups bei Probe einreichen
⚠️ Die CSS-Selektoren in
src/sources/mydealz.js(probe.list/probe.detail) sind Best-Effort und vor dem Scharfschalten gegen die aktuelle mydealz-DOM zu verifizieren — der Mechanismus (Auftragserzeugung, Callback, Pipeline) ist davon unabhängig und getestet.
Sicherheitsnetz
POST_MODE=pending→ neue Deals gehen zuerst in die Moderation (zusätzlich abgesichert, wenn die Bot-User nursubmit_dealshaben).DRY_RUN=true→ nichts schreiben, nur protokollieren.MIN_DISCOUNT_PERCENT→ Deal nur posten, wenn er belegbar genug günstiger ist (Referenz: price-api-Marktpreis, sonst UVP/nächstbester Preis).
Lokal ausführen
cp .env.example .env # Werte eintragen (Ollama, DEALS_API_BASE, BOT_USERS …)
node --env-file=.env src/cli.js health
node --env-file=.env src/cli.js run --once --source mydealz
node --test # Unit-Tests
Ohne DB: STORE_DRIVER=memory (Zustand nur im Prozess).
Konfiguration (Auszug)
| ENV | Zweck |
|---|---|
POST_MODE |
pending | publish |
DRY_RUN |
nichts an WP schicken |
MIN_DISCOUNT_PERCENT |
Mindestrabatt (Default 5) |
STORE_DRIVER |
pg | memory |
DATABASE_URL |
eigene Cluster-DB |
QUEUE_DRIVER |
memory | redis (+ REDIS_URL) |
LLM_BASE_URL / LLM_MODEL_* |
Ollama/OpenAI |
DEALS_API_BASE / WP_API_BASE |
WordPress-REST |
BOT_USERS |
JSON-Liste (Application Passwords, Gewicht) |
CATEGORY_MAP |
Slug→Term-ID je Zielseite |
COMMENTS_ENABLED |
LLM-Kommentare |
PRICE_API_BASE |
interne price-api |
PROBE_BASE/PROBE_TOKEN |
Scraper für Anti-Bot-Seiten |
PROBE_ENABLED |
automatische Scrape-Aufträge erzeugen |
PROBE_CALLBACK_URL |
Rückruf-URL dieses Dienstes (…/probe/callback) |
PROBE_CALLBACK_TOKEN |
Bearer-Token, das den Callback absichert |
PROBE_SEARCH_TERMS |
Such-Einstiegspunkte (Default amazon) |
Bot-User brauchen ein Application Password und die Fähigkeit submit_deals
(für pending) bzw. publish_deals (für Direkt-Veröffentlichung).
Deploy (ArgoCD)
deploy/k8s/ enthält Namespace, eigene CNPG-DB, ConfigMap, Secret-Vorlage,
Deployment, Service. Die Argo-Application liegt in deploy/argocd/.
Container-Image wird per Forgejo-CI (.forgejo/workflows/build.yml) gebaut und
nach git.valitype.com/claude/deal-ingest gepusht.
Secrets out-of-band setzen (deal-ingest-secrets, deal-ingest-db-app).
Hinweise
Fremdtexte werden umgeschrieben, nicht kopiert; verlinkt wird der Händler, nicht das Quell-Portal. Automatisierte Bot-Kommentare sind vorgetäuschte Aktivität und standardmäßig aus — Betrieb ist Entscheidung des Seitenbetreibers. Portal-ToS/Urheberrecht bleiben zu beachten.