Sjoerd de Vries 52c9947267 fix: harden price scraping (findings 1, 2, 6)
Finding 1: parsePriceValue mishandled thousands separators — "1.299,00"
and "1,299.00" both parsed to 1.3. Both the meta-tag path and the
text-regex path now funnel through a single normalizeAmount() helper
that picks the last separator as the decimal one, and the text regex
also matches thousands-grouped amounts.

Finding 2: the text fallback read <script>/<style> contents via
$('body').text(); those elements are now stripped from a clone first.

Finding 6: the default fetch now uses a 15s AbortSignal.timeout and a
browser-like User-Agent, so one unresponsive host cannot stall the
whole sequential run. The fetchImpl injection point is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013gwc3aCiyQxmCWQke8RvEz
2026-09-05 15:49:56 +02:00
2026-09-05 14:59:04 +02:00
2026-09-05 14:59:04 +02:00
2026-09-05 14:59:04 +02:00
2026-09-05 14:59:04 +02:00
2026-09-05 15:40:08 +02:00

Korting — prijstracker

Houdt een lijst productpagina's dagelijks in de gaten en mailt wanneer de prijs verandert.

Lokaal draaien

npm install
cp .env.example .env   # env vars invullen
npm test
npm start

De UI staat achter basic auth (BASIC_AUTH_USER / BASIC_AUTH_PASS) op http://localhost:3000.

Environment variables

Variabele Omschrijving
PORT HTTP-poort (default 3000)
DB_PATH Pad naar het SQLite-bestand (default ./data/korting.db)
BASIC_AUTH_USER / BASIC_AUTH_PASS Login voor de web-UI
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS SMTP-server (Postal op mail.sjoerd.app)
SMTP_FROM Afzenderadres van de notificatiemails
NOTIFY_EMAIL Ontvangeradres van de notificatiemails

Hoe het werkt

Elke dag om 08:00 (Europe/Amsterdam) doorloopt de app alle producten, haalt de huidige prijs op (JSON-LD → meta tags → regex-fallback), en stuurt een email als de prijs is veranderd sinds de vorige geslaagde check. Een mislukte poging (pagina onbereikbaar, geen prijs gevonden, of de mail kon niet verstuurd worden) verandert de opgeslagen prijs niet, zodat de volgende dag opnieuw wordt geprobeerd. Via de "Nu controleren"-knop in de UI kan dit ook handmatig getriggerd worden.

S
Description
Dagelijkse prijstracker die mailt bij prijswijzigingen
Readme 136 KiB
Languages
JavaScript 98%
Dockerfile 2%