Веб-дашборд для автоматизации hh.ru: массовые отклики, мгновенные LLM-ответы HR через WebSocket push (websocket.hh.ru), заполнение опросников нейросетью, аудит резюме с конкурентным анализом, рейтинги работодателей с politeness-индексом + онлайн-статусом HR, smart-фильтрация уже отклонённых вакансий, OAuth-совместимый канал отправки.
Cyberpunk-интерфейс с моноширинным шрифтом, сканлайнами и неоновыми HUD-карточками. Реалтайм через WebSocket (300мс tick).
На каждой карточке:
- Статус-бейдж с пульсацией (collecting / applying / waiting / limit)
- HUD stat-boxы — отклики / тесты / уже / ошибки / интервью с tabular-nums и glow
- HR-метрики резюме — просмотры / приглашения за 7 дней
- LLM-блок — статус, общий счётчик ответов, размер очереди
- 📤 Последняя попытка + ✅ удачный отклик с relative-ago таймером
- 🛑 HH-лимит ETA — обратный отсчёт до 00:00 МСК когда сбросится квота
- Действия: пауза, очистка discards, авто-подъём резюме, ручной туч
Журнал событий бота в реалтайме — что собрал, какие отклики прошли, какие пропуски и почему, ответы LLM, ошибки авторизации, HH-лимиты. Фильтры по аккаунту и уровню (info / warning / error).
История всех отправленных откликов: компания, вакансия, зарплата, время, аккаунт. Поиск, сортировка, пагинация.
Кнопка 🔁 (похожие) на каждой строке раскрывает inline-таблицу из 10
похожих вакансий через api.hh.ru/vacancies/{vid}/similar_vacancies (до
36 000+ похожих на одну исходную). Чипы: 🧪 с тестом, 📝 нужно письмо,
✅ принимают неполные резюме, 🎓 стажировка.
Все переговоры с интервью-статусом + per-employer politeness (% чтения откликов работодателем + дни ответа), per-HR онлайн-статус.
- Всего просмотров за всё время + новые непрочитанные
- 30-day sparkline — daily breakdown из
graphHistoryViewsSSR - Список просмотревших работодателей с датой
- Аудит резюме: % заполненности, конкуренция по запросам, скилы конкурентов с частотой, проблемы по уровню важности
- 🔥 Горячие лиды — работодатели, готовые пригласить (из
/shards/applicant/negotiations/possible_job_offers)
Точечный отклик: вставляешь URL вакансии, бот собирает форму (включая опросник, который заполнит LLM или шаблоны), показывает результат. Удобно для вакансий с тестами.
Таблица переговоров с авто-ответами + чипы рейтинга работодателя на каждой строке:
- ⭐ общий рейтинг (зелёный ≥4.3 / жёлтый ≥3.8 / красный <3.8) с tooltip-разбивкой по 6 категориям (workplace / team / management / career / rest / salary)
- 📖 politeness — % чтения откликов работодателем + дни ответа
- 🚫 last_state (DISCARD / INVITE / RESPONSE / INTERVIEW)
- 👁 viewed_by_opponent (HR увидел/нет) + 📬 непрочитанные у HR
- 🟢 HR online сейчас / 🟠 был вчера / 🔴 неделю назад
- 📪 inbox_off (работодатель отключил входящие)
Источники: employer_reviews/proxy_components/small_widget,
applicantEmployerPoliteness, applicantEmployerManagersActivity —
смерджены backend'ом в один endpoint per vacancy.
Все параметры бота на одной вкладке (разделы collapsible):
- Браузерные сессии — добавление через cURL/cookie-string или вручную; редактирование кук с горячим обновлением (без рестарта)
- Параметры бота — слайдеры: страниц на URL, пауза, размер пакета, мин. зарплата, дневной лимит, авто-пауза при ошибках, интервал LLM
- Фильтры — заголовки (include / exclude tags), формат работы (полный/удалёнка/гибкий/сменный/вахта), регион
- LLM-профили — несколько провайдеров с fallback/round-robin, системный промпт, чекбоксы (use resume / cover letter / fill questionnaire / auto-send), one-click setup
- 🎯 Диагностика — на главной: бейдж с red-flags + сменой
jobSearchStatusчерез/shards/user_statuses/job_search_status - JSON-редактор + бэкап — единый файл со всеми config + accounts
- browser_sessions + oauth_tokens; защита от затирания
- WebSocket push через
wss://websocket.hh.ru/ws/connect— бот получает событиеchat_message_createмгновенно (HR написал → бот отвечает через 1-2с), вместо 5-минутного polling - Reconnect-логика как у HH-фронта: до 120 попыток, backoff 2-30с, ping 180с
- Fallback на polling если WS недоступен
- DeepSeek / OpenAI / Anthropic / OpenRouter / любой OpenAI-compat API
- Multi-profile: fallback (попробовать по очереди) или round-robin
- Persona по полу соискателя (female / male / neutral) — корректные склонения в ответах
- Контекст: резюме (если включено) + история чата (последние 8 сообщений)
- Защита от prompt-injection (явное предупреждение системному промпту)
- Smart robot-recruiter button picker — если HH прислал кнопки «Да / Нет», бот их распознаёт и жмёт правильную (heuristic + LLM fallback для неоднозначных случаев)
- LLM_PROXY — отдельный прокси только для LLM-трафика, hh.ru остаётся напрямую (актуально для РФ-серверов)
- DISCARD-фильтр — если HH помечает вакансию
userLabelsForVacancies: DISCARD(работодатель уже отказал), бот не повторяется. На реальной выборке экономит ~16% откликов в день - chat_write_possibility=DISABLED фильтр — 15% чатов в выборке имели его, бот не тратит LLM-токены на гарантированный отказ
- Title keyword filters — include/exclude по словам в заголовке
- Salary / schedule / region — стандартные
- Auto-pause — при
consecutive_errors >= Nили HH-лимите (с авто-сбросом в 00:00 МСК)
- Рейтинг работодателей —
employer_reviews/proxy_components/small_widget, 6 категорий, топ-преимущества, число отзывов; кэш 24ч - Politeness индекс —
applicantEmployerPolitenessSSR-поле: % чтения откликов + дни ответа per employer - HR online-статус —
applicantEmployerManagersActivityper HR-hhid - Topic state — viewedByOpponent, conversationUnreadByEmployerCount, lastState, inboxAvailabilityState
- Аудит резюме — конкуренция по запросам (вакансий / соискателей), скилы топ-конкурентов, проблемы заполнения
- 18 000+ просмотров всего времени + 30-day sparkline
- Кто просмотрел (компания + дата) — последние 50
- Авто-подъём резюме раз в 4 часа через
/applicant/resumes/touch - HH-инвайты —
userStats.new-applicant-invitations(отдельным счётчиком)
- Опт-ин через
chat_use_oauth: true: бот сначала пробует официальныйPOST api.hh.ru/common/chats/{id}/messagesс Bearer-токеном (is_automated: true), fallback на reverse-engineeredchatik.hh.ru/api/send. ToS-compliant путь _oauth_applyдля откликов через official API (опц.)
- Backup/restore — единый JSON со всем (config + accounts +
browser_sessions + oauth_tokens), защита от затирания непустых
полей пустыми (нужен
?force=1для перезаписи) - Региональный поддомен —
<region>.hh.ruдля поиска/откликов (SSRF-защита regex'ом) - JSON-редактор — прямая правка raw config через UI
- 138+ unit-тестов, atomic-writes через filelock
git clone https://github.com/Vlad9572324/hh.ru-clicker.git
cd hh.ru-clicker
docker-compose up -d→ открыть http://localhost:8000
git clone https://github.com/Vlad9572324/hh.ru-clicker.git
cd hh.ru-clicker
pip install -r requirements.txt
python web_app.py→ открыть http://localhost:8000
KEY=$(uuidgen | tr -d -)
HH_BOT_HOST=0.0.0.0 HH_BOT_UNSAFE_EXPOSE=1 HH_BOT_API_KEY=$KEY python web_app.py
echo "Открой http://<host>:8000/?key=$KEY"Без HH_BOT_API_KEY бот не пустит в режиме LAN-exposure. С ключом —
фронт сам подставит его во все API/WS вызовы.
-
Браузерная сессия: Настройки → Браузерные сессии → «➕ Добавить сессию из браузера». Открой hh.ru в браузере, скопируй любой запрос как cURL (F12 → Network → правая кнопка → Copy as cURL), вставь в форму. Бот вытащит cookies, проверит сессию, найдёт твои резюме.
-
Поисковые URL: Настройки → 🔗 Пул поисковых запросов. Вставь URL поиска со страницы hh.ru/search/vacancy, или жми ✨ Подсказки — бот предложит запросы из аудита твоего резюме с конкуренцией по каждому.
-
(Опц.) LLM: Настройки → 🤖 LLM → ⚡ Быстрая настройка — вставь API-ключ, нажми Enter. Бот сам определит провайдера (OpenAI / DeepSeek / Anthropic / Groq / Gemini / HuggingFace), подставит base_url + model, включит auto-send.
-
Запустить: На главной нажми ▶ Запустить на карточке сессии. Бот начнёт собирать вакансии, отвечать на чаты в реалтайме через WS.
-
Диагностика: На карточке появится жёлтый бейдж если HH видит что-то не так (например
jobSearchStatus=not_looking_for_job— HR в чатах видит «не ищу работу», и % ответов падает). Клик → one-click фикс.
Все настройки в data/config.json, редактируются через GUI или JSON-editor.
| Переменная | По умолчанию | Описание |
|---|---|---|
HH_BOT_HOST |
127.0.0.1 |
Интерфейс сервера |
HH_BOT_PORT |
8000 |
Порт |
HH_BOT_UNSAFE_EXPOSE |
(пусто) | =1 чтобы разрешить host вне loopback |
HH_BOT_API_KEY |
(пусто) | API-ключ (обязателен при LAN-exposure) |
HH_BOT_ALLOWED_ORIGINS |
(пусто) | Доп. хосты в WS Origin whitelist |
HH_CHATIK_BASE |
https://chatik.hh.ru |
Chatik base (allowlist) |
LLM_PROXY |
(пусто) | Прокси только для LLM-трафика |
РФ-сервер → hh.ru работает напрямую (нужен РФ-IP), но LLM-провайдеры
(OpenAI и т.п.) недоступны. Глобальный HTTPS_PROXY завернул бы и
hh.ru. LLM_PROXY разделяет: LLM через прокси, hh.ru напрямую.
LLM_PROXY="http://user:pass@1.2.3.4:8080" python web_app.py
# Или socks5 (нужен pip install httpx[socks] PySocks):
LLM_PROXY="socks5://user:pass@1.2.3.4:1080" python web_app.pyВ Docker — environment: сервиса. Через прокси идут чат-вызовы и
проверка ключа (/api/llm_detect). Реализация:
app/llm.py (_make_openai_client) +
app/routes/llm.py (_llm_proxies).
config.hh_region (через UI или JSON):
- пусто →
https://hh.ruдля всех запросов syktyvkar→https://syktyvkar.hh.ruдля поиска/откликов/переговоров- OAuth и chatik всегда на основном домене
hh.ru-clicker/
├── web_app.py # entrypoint: FastAPI + uvicorn
├── app/
│ ├── config.py # CONFIG + hh_base() + load/save
│ ├── state.py # AccountState
│ ├── storage.py # кэши applied/tests/interviews
│ ├── manager.py # BotManager, workers, snapshot
│ ├── hh_api.py # HTTP-headers, parse_search_page,
│ │ # parse_apply_strategy_meta (autoResponse +
│ │ # chatWritePossibility + hh_labels)
│ ├── hh_apply.py # отклики, popup-классификатор, опросники
│ ├── hh_chat.py # chatik API + ChatikWSClient (WS push)
│ ├── hh_resume.py # парсинг резюме, аудит, конкуренция,
│ │ # диагностика, set_job_search_status
│ ├── hh_negotiations.py # politeness, HR activity, employer rating,
│ │ # similar_vacancies, topics_by_vid
│ ├── llm.py # OpenAI-compat клиент, robot button picker
│ ├── questionnaire.py # парсинг и заполнение анкет
│ ├── oauth.py # HH OAuth токены, send_chat_message_oauth
│ ├── logging_utils.py # log_debug, _is_login_page
│ ├── instances.py # singleton bot
│ └── routes/
│ ├── __init__.py # FastAPI + lifespan + middleware
│ ├── core.py # /, /ws, broadcast_loop
│ ├── accounts.py # /api/account/{idx}/...
│ ├── sessions.py # /api/session/...
│ ├── apply.py # /api/apply/...
│ ├── llm.py # /api/llm_*
│ ├── data.py # /api/applied, /api/interviews, ...
│ ├── settings.py # /api/raw/config, /api/backup
│ └── debug.py # /api/debug/...
├── static/
│ ├── index.html # SPA
│ ├── css/
│ │ ├── style.css # базовая тёмная тема
│ │ └── theme-autoclicker.css # cyberpunk-overlay (опц.)
│ └── js/app.js # vanilla JS (~5000 строк)
├── docs/
│ ├── hh_openapi.yaml # public HH OpenAPI spec (106 paths, 1.2 МБ)
│ ├── HH_OPENAPI_KEY_FINDINGS.md
│ └── HH_API_MAP.md # reverse-engineered API + SSR fields
├── data/ # gitignored
│ ├── config.json
│ ├── accounts.json
│ ├── browser_sessions.json
│ ├── applied_vacancies.json
│ ├── interviews.json
│ ├── oauth_tokens.json
│ ├── llm_log.jsonl
│ └── debug.log
├── tests/ # pytest, 138+ тестов
├── images/ # README screenshots (replayed via Playwright)
├── Dockerfile
├── docker-compose.yml
└── requirements.txt
| Компонент | Стек |
|---|---|
| Backend | Python 3.10+, FastAPI, uvicorn, aiohttp, requests |
| Frontend | Vanilla JS + WebSocket (300мс tick), no framework |
| LLM | OpenAI SDK + httpx (optional proxy) |
| HH API | reverse-engineered chatik.hh.ru + websocket.hh.ru WS push + 106-path public OpenAPI |
| OAuth | hh.ru OAuth2 (Android-app credentials) |
| Тесты | pytest, 138+ unit-тестов |
| Деплой | Docker + docker-compose |
- Python 3.10+ (для локального запуска)
- Активная сессия hh.ru — нужны cookies
hhtoken,_xsrf,crypted_id,hhul(бот сам достаётhhuid/crypted_hhuidпри первом запросе) - API-ключ LLM-провайдера — опционально, только для авто-ответов и заполнения опросников
data/в.gitignore— личные cookies и API-ключи не попадают в репо- Бэкап содержит реальные cookies/ключи — храни как пароль, не публикуй
HH_BOT_API_KEYзащищает дашборд при LAN-exposure- WebSocket Origin-проверка отбрасывает CSWSH-атаки
- CSP-заголовки на статике
- Redact-логи: hhtoken / API-ключи никогда не пишутся в
debug.log - Скриншоты в
images/сгенерированы Playwright'ом с агрессивной PII-маскировкой (имена → рандом-пул фейков, телефоны →•••, чаты blur 4px, raw config-textareas замаскированы)
В docs/ лежит документация по reverse-engineered HH API:
hh_openapi.yaml— полная public OpenAPI spec (106 paths, скачана сapi.hh.ru/openapi/specification/public)HH_OPENAPI_KEY_FINDINGS.md— ключевые находки: webhook-API (HR-only),/common/chatsдля applicant OAuth,/negotiations/{nid}/test/solution, dev.hh.ru ecosystemHH_API_MAP.md— карта 230+ endpoint'ов и SSR-полей с примечаниями где работают cookies vs OAuth
Личный проект. Использование на свой страх и риск. HH.ru может изменить ToS — бот может перестать работать, попасть в shadow-ban и т.д.







