# Alpinbet parser

Готовый каркас проекта для парсинга HTML-страниц Alpinbet через Playwright.

Что уже есть:
- ручная авторизация с сохранением browser session;
- повторное использование cookies/localStorage через `storageState`;
- polling раз в 20 секунд;
- вытаскивание данных из DOM по CSS-селекторам;
- сравнение текущего состояния с прошлым;
- отправка webhook при изменениях;
- сохранение HTML-снимка;
- скриншот при ошибке;
- простой логгер.

## 1. Установка

```bash
npm install
npx playwright install chromium
```

## 2. Настройка

Скопируй пример env:

```bash
cp .env.example .env
```

Минимум проверь:
- `ALPINBET_TARGET_URL`
- `SESSION_FILE`
- `ITEM_SELECTOR`
- селекторы полей строки
- `WEBHOOK_URL` при необходимости
- `HTTP_USER_AGENT` при необходимости
- `FORECAST_ACTIVE_TABS` (обычно `1,2`, где `1` — активные, `2` — неактивные)
- `FORECAST_PER_PAGE` и `FORECAST_MAX_PAGES`

## 3. Первичная авторизация

```bash
npm run auth
```

Что будет:
1. откроется Chromium;
2. ты вручную логинишься в Alpinbet;
3. после входа возвращаешься в консоль и жмёшь Enter;
4. сессия сохранится в `data/alpinbet-session.json`.

## 4. Проверка сессии

```bash
npm run check-session
```

Скрипт попытается открыть целевую страницу и выведет:
- текущий URL;
- заголовок страницы;
- часть HTML.

Если тебя редиректит на логин, значит сессия протухла.

## 5. Запуск парсера

```bash
npm start
```

## Как работает парсер

Каждый цикл:
1. получает HTML через HTTP-запрос с cookies из Playwright-сессии;
2. если сессия истекла, переавторизуется через Playwright и повторяет HTTP-запрос;
3. парсит HTML через Cheerio;
4. собирает массив объектов;
5. нормализует и сортирует его;
6. сравнивает с прошлым состоянием;
7. если есть изменения — сохраняет state и шлёт webhook.

### Получение HTML

- Парсер работает через HTTP-запросы с cookies из Playwright-сессии

Дополнительно:
- `FORECAST_ACTIVE_TABS=1,2` — какие вкладки забирать
- `FORECAST_PER_PAGE=40` — размер страницы запроса
- `FORECAST_START_PAGE=1` — стартовая страница
- `FORECAST_MAX_PAGES=10` — максимум страниц на вкладку за цикл

Парсер автоматически подставляет в URL параметры:
- `ForecastSearch[activeTab]`
- `ForecastSearch[perPage]`
- `page`

Пример `ALPINBET_TARGET_URL`:

```text
https://alpinbet.com/dispatch/diamondwither/dfadfdfaadfadf?ForecastSearch%5BisFavorite%5D=0&ForecastSearch%5Bsort%5D=date&ForecastSearch%5Buser_id%5D=7891&ForecastSearch%5Bg_id%5D=&ForecastSearch%5Bdispatch_id%5D=63652&_pjax=%23pjax-forecast-list
```

## Важный момент

Селекторы в `.env.example` — это заглушки. Их почти наверняка надо поменять под реальный DOM Alpinbet.

Самый быстрый путь:
1. зайди на страницу;
2. открой DevTools;
3. найди контейнер одной строки/сигнала;
4. подставь реальные селекторы в `.env`.

## Формат webhook

По умолчанию отправляется JSON:

```json
{
  "event": "alpinbet_changes_detected",
  "timestamp": "2026-03-18T00:00:00.000Z",
  "count": 2,
  "changes": [
    {
      "type": "added",
      "item": {}
    }
  ]
}
```

Если нужен Telegram/email/max, обычно проще принимать этот webhook на своём backend и уже там делать доставку.

## Структура

```text
alpinbet-parser/
  data/
  logs/
  scripts/
    save-session.js
    check-session.js
  src/
    config.js
    index.js
    logger.js
    notifier.js
    parser.js
    session.js
    state.js
    utils.js
```

## Что доработать под прод

- health endpoint;
- Dockerfile;
- очередь уведомлений;
- админку для переавторизации;
- хранение state в Redis/PostgreSQL;
- multiple bot profiles / multiple pages.
