Telegram-бот, который в реальном времени мониторит биржу заказов kwork.ru/projects и через локальный DeepSeek (github.com/afterburnerr/FreeDeepSeekAPI) отбирает интересные заказы для разработчика / инженера.
Важно: проект работает в паре с локальным OpenAI-совместимым прокси к chat.deepseek.com. Ванильный
LeadroyaL/FreeDeepSeekAPIиз-за смены стримингового формата и AWS-WAF не заработает без патчей из этого репо (см.DEPLOY.md— раздел про установку и наши изменения вdsk/api.py,main.py,refresh_cookies.sh). Проще всего поднять через приложенныйdocker-compose.yml— он собирает прокси из сиблинг-директории../FreeDeepSeekAPI.
- Читает
window.stateDataпрямо с HTML-страницы биржи (без входа, без API, без Playwright). - Переключает режимы:
- все проекты — присылает каждый новый заказ.
- только интересные (по умолчанию) — сначала отсекает заведомо неинтересные категории (весь дизайн, 3D, видео-монтаж, музыка, озвучка), потом отправляет описание в DeepSeek. Бот присылает только те, что попадают под профиль инженера.
- Помнит уже показанные проекты в SQLite, так что при рестарте ничего не дублируется.
- Команда
/scanпроходится по всем ~50 страницам биржи разом и пушит в чат все интересные проекты с живым прогрессом. - AI-промпт редактируется на лету (
/filter ...), сброс —/filter_reset. - Пауза/возобновление —
/pause,/resume.
| Команда | Что делает |
|---|---|
/start |
Приветствие + закрепление chat_id как владельца |
/status |
Режим, пауза, число seen-проектов, время последнего опроса |
/mode_all |
Присылать все новые проекты без AI-фильтра |
/mode_interesting |
Только интересные (AI) — дефолт |
/pause, /resume |
Выключить / включить уведомления |
/check |
Прямо сейчас проверить 1-ю страницу |
/scan [N] |
Пройти всю биржу (или первые N страниц) и найти интересные |
/cancel |
Прервать текущий /scan |
/filter [текст] |
Показать / задать AI-промпт |
/filter_reset |
Сбросить AI-промпт к дефолту |
kwork.ru/projects (HTML, window.stateData)
│
▼
kwork_parser.py ── Project dataclass
│
▼ (для каждого unseen проекта)
pipeline.process_project ──▶ DeepSeek (FreeDeepSeekAPI 127.0.0.1:8080/v1)
│ │
│ ▼
│ {interesting, reason}
▼
notifier.send_project ─▶ aiogram 3 ─▶ Telegram
│
▼
storage.mark_seen (SQLite)
Два триггера пайплайна:
poller.Poller— циклwhile True: fetch page 1; process unseen.scanner.Scanner— по/scan: обходитpagination.last_pageстраниц.
-
Поднят и работает
FreeDeepSeekAPI:cd ../FreeDeepSeekAPI cp .env.example .env # положи туда свой DeepSeek auth token pip install -r requirements.txt python main.py # слушает 127.0.0.1:8080
-
Создай бота у @BotFather и возьми токен.
-
Настрой
.env:cp .env.example .env $EDITOR .envМинимум:
TELEGRAM_BOT_TOKEN. Остальное — по вкусу.TELEGRAM_OWNER_CHAT_IDможно не указывать: первый пользователь, написавший/start, автоматически станет владельцем и запишется в конфиг-стейт бота. -
Зависимости:
python -m venv .venv && source .venv/bin/activate pip install -r requirements.txt
Если системный Python слишком свежий для сборки
pydantic-core, поставь Python 3.12 через uv:uv venv --python 3.12 .venv uv pip install --python .venv/bin/python -r requirements.txt
-
Запусти:
python run.py # или python -m kwork_bot.main
cp .env.example .env # и отредактируй
docker compose up --build -d
docker compose logs -f kwork-botdocker-compose.yml поднимает и FreeDeepSeekAPI, и бота в одной сети.
Если прокси уже запущен отдельно — закомментируй сервис deepseek и
пропиши DEEPSEEK_API_BASE в .env.
- При первом запуске бот помечает
KWORK_SEED_SEEN(по умолчанию 12 — ровно одна страница) самых старых проектов как «уже видел», чтобы не завалить чат сразу всеми текущими заказами. - На цикл опроса бот тратит максимум
KWORK_MAX_AI_PER_CYCLEAI-вызовов (по умолчанию 8). Если бот был долго оффлайн и накопилось много новых проектов, остаток обработается в следующих циклах. - Команда
/scanобрабатывает только новые проекты (те, что бот ещё не видел). Если хочешь переклассифицировать всё с нуля — удали файлdata/kwork_bot.sqlite3и запусти бота заново. - Фильтр «заведомо неинтересных» категорий (
HARD_BLOCKED_CATEGORIESвkwork_parser.py) срабатывает ДО AI, чтобы сэкономить запросы: дизайн, 3D, видео, озвучка, музыка отбрасываются сразу. - DeepSeek используется в не-reasoning режиме (
deepseek-chat) — быстрее и дешевле для бинарной классификации. Хотите умнее, но медленнее — поставьтеDEEPSEEK_MODEL=deepseek-reasoner.