mirror of
https://gitverse.ru/kpa39l/vesti.git
synced 2026-09-29 18:05:03 +00:00
5.4 KiB
5.4 KiB
Tasks: publisher-service
1. Скелет сервиса
- 1.1 Создать services/publisher/ (app/, requirements.txt, .env.example, README.md)
Проверка:
ls services/publisher/app/→ main.py, config.py, telegram.py, channels.py - 1.2 requirements.txt: fastapi, uvicorn, httpx[socks], pydantic, python-dotenv
Проверка:
.venv/bin/pip install -r services/publisher/requirements.txtбез ошибок - 1.3 config.py: env VESTI_BOT_TOKEN, TG_PROXY, VESTI_BOT_CHANNELS, PUBLISHER_PORT
Проверка:
python -c "from services.publisher.app.config import Settings; print(Settings().channels)"→ ['@dedinit_vesti']- Замечание: токен не читался из-за порядка (os.getenv при ClassVar, до load_dotenv) и неверного пути BASE (3x parent → /opt/vesti/services, нужно parents[3] → /opt/vesti). Исправлено: Settings → @dataclass + post_init, load_dotenv(override=True), BASE=parents[3].
2. Telegram-клиент (Bot API через SOCKS5)
- 2.1 telegram.py: клиент httpx с proxy=socks5://127.0.0.1:1080, методы sendMessage/sendPhoto/getMessage
- 2.2 channels.py: разбор VESTI_BOT_CHANNELS ("@a,@b" → ["@a","@b"])
- 2.3 Обработка ошибок: 403 (бот не админ), сеть (прокси) → 502
3. FastAPI-эндпоинты
- 3.1 main.py: GET /healthz (status, bot, proxy, channels)
Проверка:
curl -s :8410/healthz→ ok + бот + каналы. Реальное: {"status":"ok","bot":"dedinit_controller_bot","token_set":true,"proxy":"socks5://127.0.0.1:1080","channels":["@dedinit_vesti"]} - 3.2 main.py: POST /api/v1/publish (card {text, media?, direction, lang}, channels?) → results по каналам
Проверка:
curl -X POST :8410/api/v1/publish -d '{"card":{"text":"тест","direction":"linux","lang":"ru"}}'→ ok, message_id в @dedinit_vesti. Реальное: {"ok":true,"results":{"@dedinit_vesti":{"message_id":2,...}}} - 3.3 views: эндпоинт GET /api/v1/views/{channel}/{mid} (в main.py) + поле views в ответе publish (get_views при публикации)
4. Контейнеризация
- 4.1 Dockerfile: python:slim, non-root, read-only fs, expose 8410
- 4.2 docker-compose.yml: сервис publisher, порт 127.0.0.1:8410, env из .env, healthcheck curl /healthz
- Проверено 2026-09-09:
docker compose up -d --build→ vesti-publisher Up (healthy), 127.0.0.1:8410, healthz: bot=dedinit_controller_bot, proxy=host.docker.internal. - Питфолы Docker: (1) пути в compose отсчитываются от services/publisher/ → .env надо
../../.env, media../../media; (2) TG_PROXY=127.0.0.1 в контейнере = сам контейнер → заменить на socks5://host.docker.internal:1080 + extra_hosts host-gateway; (3) load_dotenv(override=True) перебивал env контейнера → override=False (env окружения приоритетнее .env); (4) dataclass-дефолт tg_proxy="socks5://127.0.0.1:1080" был truthy → os.getenv не срабатывал → дефолт сделан пустым.
- Проверено 2026-09-09:
5. Интеграция с вебом
- 5.1 web/app.py: убрать
from publisher.bot import publish_multi/get_views_multi; вместо них web/publisher_client.py (HTTP POST на PUBLISHER_URL, default http://127.0.0.1:8410)- Проверка: grep — импорт publisher.bot убран; карточка шлёт card{direction,lang}, сервис берёт каналы из VESTI_BOT_CHANNELS.
- 5.2 Обновить .env.example (VESTI_BOT_CHANNELS, TG_PROXY, PUBLISHER_URL)
- 5.3 Реальный approve через веб: сквозной путь веб → HTTP → publisher(Docker) → канал.
- Проверено 2026-09-09: approve постов 136 и 137 через POST /posts//approve — 302 → /published, статус published, бандл, tg_message_id=3 и 4 в @dedinit_vesti.
- Веб-баги, найденные при проверке: (1)
raise RedirectResponse(...)в _require_auth → TypeError (исключение не BaseException) → 500 на /candidates; фикс: HTTPException(303, headers={"Location": "/login"}); (2) tg_message_id для внешних постов искался по направлению (results["linux"]), а ключи results — каналы (@dedinit_vesti) → 0; фикс: брать первый message_id из results.values().
6. Проверка и документация
- 6.1
openspec validate publisher-service→ 0 ошибок (valid) - 6.2 Реальная публикация тестовой карточки в @dedinit_vesti (бот админ) → message_id в ответе. Реальное: message_id=2, ok.
- Бот добавлен админом канала (подтверждено пользователем).
- 6.3 Обновить STATUS.md / TODO.md — сделано; WALKTHROUGH/PRD — обновлено (см. PRD.md)
Открытые пункты
- publisher: медиа из card.media — путь в БД /opt/vesti/media/... не совпадает с монтированием в контейнере (/srv/publisher/media) → send_photo не уходит при Docker-запуске (нужен маппинг путей или передача имени файла)