Skip to content

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

Matcher — Future Camp 2026

Wpisujesz, czego szukasz. Model czyta bazę 131 osób i zwraca tych, z którymi warto pogadać, z uzasadnieniem i pytaniem na start.

Pliki

index.html        strona — trzy zakładki: Matcher, Agenda, Swipe agendy
agenda.js         agenda campu (godziny, ścieżki, prowadzący) — wczytywana w przeglądarce
api/match.js      funkcja serwerowa: jedyne miejsce, które zna klucz API
api/data.js       GENEROWANY katalog dla modelu — nie edytuj ręcznie
profiles.js       56 uczestników (intro z grupy WhatsApp)
speakers.js       75 prelegentów, mentorów i jury (agenda + biogramy PARP)
build-data.js     przerabia profiles.js + speakers.js na api/data.js
vercel.json

Wdrożenie — 4 kroki

1. Klucz API

aistudio.google.com → Get API key → Create API key in new project. Bez karty, darmowy tier.

Funkcja obsługuje też Claude jako zapas — patrz „Gdy padnie limit” niżej.

2. Wrzuć projekt na Vercela

Najprościej przez GitHub: załóż repo, wrzuć te pliki, potem na vercel.com → Add New → Project → wybierz repo → Deploy.

Framework Preset: Other. Build Command i Output Directory zostaw puste.

Alternatywa bez GitHuba:

npm i -g vercel
vercel        # w katalogu projektu, odpowiadasz na kilka pytań

3. Wklej klucz jako zmienną środowiskową

To jest ten krok, którego nie wolno pominąć ani obejść. W panelu Vercela: Project → Settings → Environment Variables → dodaj:

Nazwa Wartość
GEMINI_API_KEY Twój klucz z AI Studio
GEMINI_MODEL (opcjonalnie) np. gemini-2.5-flash

Klucza nie wolno wkleić do index.html ani do żadnego pliku w repo. Wszystko, co trafia do przeglądarki, jest jawne — każdy odwiedzający może podejrzeć źródło strony, wyciągnąć klucz i obciążyć nim Twoje konto. Klucz ma istnieć wyłącznie w zmiennych środowiskowych Vercela, gdzie czyta go funkcja api/match.js.

Po dodaniu zmiennej zrób Redeploy — bez tego stara wersja jej nie zobaczy.

GEMINI_MODEL możesz zostawić puste. Jeśli domyślna nazwa modelu nie zadziała, funkcja sama zapyta API o listę dostępnych i wybierze wariant Flash. Listę zobaczysz też sam:

curl https://generativelanguage.googleapis.com/v1beta/models -H "x-goog-api-key: TWOJ_KLUCZ"

Gdy padnie limit darmowego tieru

Gemini ma dzienny limit. Jeśli wyczerpie się w środku eventu, strona zacznie zwracać błąd. Ratunek zajmuje 30 sekund i nie wymaga zmiany kodu:

  1. Weź klucz z console.anthropic.com → Settings → API Keys
  2. Vercel → Settings → Environment Variables → usuń GEMINI_API_KEY, dodaj ANTHROPIC_API_KEY
  3. Redeploy

Funkcja sama wykryje, który klucz jest ustawiony. Claude jest płatny, ale katalog idzie przez prompt caching, więc przy modelu Haiku i skali tego wydarzenia to pojedyncze złotówki. Jak ustawisz oba klucze naraz, wygrywa Gemini.

4. Sprawdź

Wejdź na adres z Vercela, wpisz „szukam inwestora na pierwszą rundę”, poczekaj kilka sekund. Powinny wyjść nazwiska z uzasadnieniami.

Jeśli wyskoczy błąd — Vercel → Deployments → wybierz deploy → Runtime Logs. Tam jest powód.

Dopisanie ludzi

  1. Dodaj rekord w profiles.js (uczestnicy) albo speakers.js (prelegenci)
  2. node build-data.js
  3. Commit i push — Vercel przebuduje sam

Krok 2 jest obowiązkowy. Bez niego model nie zobaczy nowej osoby, mimo że jest w pliku.

Koszty i bezpieczniki

Katalog ma około 27 tys. tokenów i leci przy każdym zapytaniu. Na darmowym tierze Gemini kosztuje to zero — liczy się tylko dzienny limit zapytań.

W api/match.js siedzą dwa bezpieczniki:

  • MAX_Q = 500 — dłuższych zapytań funkcja nie przyjmie
  • RPM_PER_IP = 12 — maksymalnie 12 zapytań na minutę z jednego adresu

To zgrubna ochrona, licząca w pamięci procesu. Wystarczy przeciw przypadkowemu zapętleniu i komuś, kto się nudzi. Nie wystarczy przeciw komuś, kto naprawdę chce Ci wypalić limit — jeśli link wyjdzie poza grupę, obserwuj zużycie w konsoli Anthropic i w razie czego wygeneruj nowy klucz.

Przed wrzuceniem linku na grupę

  1. Podmień TWOJ@MAIL.PL w stopce index.html na swój adres
  2. noindex jest już w <head> — strona nie wejdzie do Google
  3. Napisz do organizatora zanim link pójdzie na grupę
  4. Baza zawiera tylko to, co ludzie sami wrzucili na grupę, plus publiczną agendę PARP. Numery telefonów widoczne na zrzutach nie weszły. Natalia z HerRise jest oznaczona hidden:true, bo jej opis pochodził z LinkedIna, a nie z jej intro — zdejmij tę flagę dopiero, jeśli sama napisze coś na grupie.

Agenda, zapisywanie i kalendarz

Zakładka Agenda pokazuje cały program obu dni z agenda.js. Przycisk + przy punkcie zapisuje go do „Mojej agendy” — lista trzyma się w localStorage przeglądarki, nic nie idzie na serwer. Przy każdym punkcie jest link Dodaj do Google Calendar (gotowy formularz wydarzenia), a nad listą przycisk Pobierz .ics eksportujący wszystkie zapisane punkty jednym plikiem — importuje się do Google Calendar, Apple Calendar i Outlooka.

Wysyłka wprost do Google Calendar

Przycisk Wyślij do Google Calendar loguje użytkownika przez OAuth i wrzuca wszystkie zapisane punkty do jego kalendarza. Bez backendu — cały przepływ dzieje się w przeglądarce (Google Identity Services, token client). Client secret nie jest tu w ogóle używany.

Zakres uprawnień to calendar.app.created: strona tworzy własny, osobny kalendarz „PARP Future Camp 2026” i pisze tylko po nim. Do głównego kalendarza użytkownika nie ma dostępu ani do odczytu, ani do zapisu. To najwęższy zakres, jaki wystarcza do tego zadania — i dlatego nie wymaga przechodzenia przez weryfikację aplikacji, którą Google nakłada na zakresy dające dostęp do całego kalendarza.

Żeby to włączyło się na Twoim wdrożeniu, potrzebny jest własny OAuth Client ID:

  1. Nowy projekt: console.cloud.google.com/projectcreate
  2. Włącz Google Calendar API: console.cloud.google.com/apis/library/calendar-json.googleapis.com
  3. Ekran zgody: console.cloud.google.com/auth/overview → Get started → nazwa aplikacji, mail wsparcia, Audience External, dane kontaktowe
  4. Klient: console.cloud.google.com/auth/clients → Create client → typ Web application
  5. W Authorized JavaScript origins dodaj adres strony (np. https://twoj-projekt.vercel.app, a do testów http://localhost:5199)
  6. Wklej Client ID do stałej GOOGLE_CLIENT_ID w index.html

Starsze poradniki każą szukać APIs & Services → Credentials. Tej ścieżki już nie ma — zarządzanie klientami OAuth przeniosło się do sekcji Google Auth Platform → Clients. Zanim skonfigurujesz ekran zgody (krok 3), lista klientów bywa pusta i nie da się nic dodać.

Client ID jest jawny z definicji — leci do przeglądarki przy każdym logowaniu OAuth, więc trzymanie go w index.html jest w porządku. To nie jest sekret. (Klucz do modelu z sekcji wyżej sekretem jest i musi zostać w zmiennych środowiskowych.)

Jeśli GOOGLE_CLIENT_ID zostanie puste, przycisk pokaże panel z instrukcją i polem na wklejenie ID — wtedy siedzi ono tylko w localStorage tej jednej przeglądarki. Wygodne do sprawdzenia, czy działa, zanim wpiszesz je na stałe.

Ponowna wysyłka nie duplikuje wydarzeń: strona pamięta w localStorage, co już wysłała, i aktualizuje istniejące wpisy zamiast tworzyć nowe.

Zakładka Swipe agendy pokazuje wyłącznie punkty, które nachodzą na siebie w czasie: dwie alternatywy naraz, wybierasz jedną przeciągnięciem karty albo kliknięciem. Wybrany punkt ląduje w Mojej agendzie, a wszystko, co z nim koliduje, znika z kolejki pytań.

Godziny końca krótkich wystąpień są wyliczone z początku następnego punktu na tej samej ścieżce — to przybliżenie, nie oficjalny program.

Sekcja „O tej osobie”

Na karcie wyniku ta sekcja pokazuje tekst źródłowy bez żadnych przeróbek: dla uczestnika — dokładnie jego intro z grupy WhatsApp (pole raw w profiles.js), dla prelegenta — dokładnie biogram z jego strony w PARP (pole bio w speakers.js). Przerobiony, skrócony opis (does) idzie tylko do modelu i do nagłówka karty.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages