Public
Co dziś w Zamościu i na Roztoczu — koncerty, kino, wydarzenia
eventsreactscrapersqlite
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

Co w Zamościu

Mobilna aplikacja (PWA do zainstalowania na telefonie): co dziś, jutro i w weekend dzieje się w Zamościu i na Roztoczu. Koncerty, kino, teatr, festyny, sport, wydarzenia dla dzieci.

👉 https://co-w-zamosciu.val.run

Jak to działa

  • cron/scrape.ts zbiera wydarzenia 3 razy dziennie (6:00, 12:00, 18:00 czasu letniego) z:
    • Biletyna (Zamość, Biłgoraj, Tomaszów Lub., Hrubieszów, Krasnystaw, Chełm): dane schema.org, seanse kin łączone w jedną kartę filmu,
    • tuzamosc.pl,
    • Zamojski Dom Kultury: godziny ze stron szczegółów,
    • Zamojska Akademia Kultury: kalendarz przez API (bez cotygodniowych zajęć) i sala kinowa ZAK,
    • Melodia Smaku (Jazz Club Kosz): kalendarz ze strony,
    • Kino Stylowy: repertuar na tydzień, w aplikacji jako jedna karta dziennie,
    • KS Hetman Zamość: mecze u siebie,
    • Kronika Tygodnia: festyny i pikniki w powiatach,
    • Super Tydzień Chełmski: Chełm i Krasnystaw,
    • Krasnostawski Dom Kultury,
    • Biłgorajskie Centrum Kultury: zapowiedzi czytane przez AI i kino (tylko okresy wyświetlania, bez godzin),
    • OSiR Biłgoraj: kalendarz imprez i meczów (bez rozgrywek młodzieżowych),
    • Facebook przez Apify (apify/facebook-events-scraper): szczegóły niżej.

Facebook (Apify)

  • cron/facebook.ts co 2 dni (3:30 UTC) uruchamia aktora z wyszukiwaniami: Zamość, Chełm, Tomaszów Lubelski, Biłgoraj, Krasnystaw, Roztocze.
  • Pobierane są tylko nadchodzące wydarzenia (filtr dat wyszukiwarki FB, 30 dni do przodu), bo Apify liczy opłatę za każde wydarzenie w wyniku.
  • Limit kosztu: 1 USD na run (maxTotalChargeUsd). Przewidywany koszt to ok. 0,25–0,40 USD za run.
  • cron/scrape.ts czyta wynik ostatniego udanego runu, także uruchomionego ręcznie w konsoli Apify.
  • Z wyników odpada wszystko dalej niż 80 km od Zamościa, a także wycieczki, pielgrzymki i wydarzenia online.
  • Zdjęcia z FB nie są zapisywane, bo ich linki szybko wygasają.
  • Wydarzenia z FB mają najniższy priorytet, więc scalają się z tymi samymi wydarzeniami z innych źródeł.

👉 Add APIFY_TOKEN here: https://www.val.town/x/dominik1/co-w-zamosciu/environment-variables?key=APIFY_TOKEN

  • Tytuły filmów z repertuarów pisanych wersalikami dostają poprawną wielkość liter od AI (z cache).
  • Nie da się pobierać automatycznie: Arabeska (ogłasza tylko na Facebooku i Instagramie). Takie wydarzenia dodajesz przyciskiem +.
  • To samo wydarzenie z kilku stron jest scalane w jedno. Decyduje ten sam dzień, zgodna godzina i podobny tytuł.
  • Wydarzenia, których reguły nie przypisały do kategorii, klasyfikuje AI (std/openai, gpt-5.4-nano). Wystarcza darmowy limit Val Town.
  • cron/digest.ts codziennie o 8:00 wysyła push na telefony (Twoje „Idę” są na początku) i mail do właściciela. W piątek dochodzi zapowiedź weekendu i ostrzeżenia o źródłach, które przestały działać.
  • Dodawanie ręczne (przycisk +, wymaga PIN-u): wklej tekst z plakatu, posta z FB albo link, a AI wypełni formularz.
  • Stan źródeł: /api/status.

Zmienne środowiskowe

  • ADD_PIN: PIN do dodawania i ukrywania wydarzeń.
  • VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY: klucze Web Push. Po zmianie trzeba ponownie włączyć powiadomienia na telefonach.
  • OPENAI_API_KEY (opcjonalnie): własny klucz, jeśli darmowy limit Val Town okaże się za mały.

👉 Add ADD_PIN here: https://www.val.town/x/dominik1/co-w-zamosciu/environment-variables?key=ADD_PIN

Struktura

  • index.ts: serwer Hono (strona, manifest, ikony, service worker, API, pliki .ics)
  • backend/adapters/*: parsery poszczególnych stron
  • backend/sources.ts: rejestr źródeł i przebieg zbierania
  • backend/db.ts: SQLite (wydarzenia, źródła, subskrypcje push, cache AI)
  • backend/normalize.ts: daty w strefie Europe/Warsaw, kategorie, miejscowości, deduplikacja
  • backend/llm.ts: AI do odczytu tekstu i klasyfikacji
  • frontend/: interfejs React, service worker, powiadomienia
  • scripts/test-adapters.ts: próbny przebieg parserów bez zapisu (do diagnozy, gdy strona zmieni układ)

Nowe źródło dodajesz jako adapter w backend/adapters/ i wpis w SOURCES w backend/sources.ts.