parser-tg-bot
Парсер публичных Telegram-каналов на Telethon (MTProto). Сохраняет сообщения в Postgres,
управляется через REST API. Период опроса настраивается через .env. На следующем шаге
легко перевести на realtime через events.NewMessage.
Стек
- Python 3.11, Telethon, FastAPI, SQLAlchemy 2 (async) + Alembic, APScheduler, Postgres 16
Структура
src/parser_bot/
├── api/ # FastAPI роуты + Pydantic-схемы
├── db/ # SQLAlchemy модели + сессии
├── scheduler/ # APScheduler-воркер периодического опроса
├── telegram/ # Telethon-клиент (resolve, fetch)
├── web/static/ # SPA-странички (HTML/CSS/JS, без бандлера)
├── config.py # pydantic-settings
└── main.py # FastAPI lifespan + uvicorn
alembic/ # миграции
Первый запуск (локально, через Docker)
-
Получить
api_idиapi_hashна my.telegram.org → API development tools. -
Скопировать
.env.exampleв.envи заполнитьTG_API_ID,TG_API_HASH,TG_PHONE. -
Поднять Postgres + накатить миграции:
docker compose up -d db docker compose run --rm app alembic upgrade head -
Запуск:
docker compose up -d docker compose logs app --tail=50 -
Авторизация Telegram — открыть http://localhost:8000/auth.html и нажать «Отправить код». Telegram пришлёт код на номер из
TG_PHONE→ ввести код (и 2FA-пароль, если включён). Готово, парсер начнёт опрос.Сессия сохраняется в
./data/session/parser.session— рестарты её переиспользуют, повторно входить не нужно.
Админ-доступ и коды подразделов
ADMIN_PASSWORD— дополнительный пароль для админских функций. Если не задан, остаётся прежний режим: доступ определяется толькоADMIN_ALLOWED_IPS.- http://localhost:8000/admin.html — вход по админ-паролю. После входа доступны удаление и редактирование подразделов, просмотр их кодов, управление каналами, ручной опрос, промпты, авторизация Telegram и Swagger.
- При создании подраздела обязательно задаётся
Код доступа. Пользователь вводит этот код при первом открытии данных подраздела; после входа он может добавлять каналы в этот подраздел. Админ видит код в списке подразделов.
Прод-вариант: без UI и без volume (k8s-friendly)
Сделай интерактивный логин один раз на dev-машине и получи опаковую строку:
docker compose run --rm -it app python -m parser_bot.auth
Скрипт напечатает строку вида TG_SESSION_STRING=1AbcD.... Положи её в
.env или k8s Secret — после этого приложение поднимается без UI и без
монтирования сессионного файла:
TG_SESSION_STRING=1AbcDef... # вместо TG_SESSION_PATH/volume
⚠️
ApiIdPublishedFloodError— Telegram заблокировал твою паруapi_id/api_hash(попала в публичный доступ). Создай новое приложение на my.telegram.org и не публикуй креды нигде. Старыйapi_idвосстановить нельзя.
UI
После запуска доступны страницы:
- Дашборд — общая статистика, топ каналов, кнопка опросить всех
- Каналы — добавить / удалить / включить-выключить / опросить вручную
- Сообщения — фильтр по каналу, поиск по тексту, пагинация, raw JSON
- Настройки — текущая конфигурация и подсказки
- Авторизация — веб-логин в Telegram (код + 2FA)
- Swagger UI — интерактивный API
Глубокая ссылка messages.html?channel_id=42 открывает ленту конкретного канала.
API
GET /healthz— health checkGET /api/v1/auth/status— авторизован ли клиентPOST /api/v1/auth/send-code— отправить код наTG_PHONEPOST /api/v1/auth/submit-code{"code": "12345"}— подтвердить кодPOST /api/v1/auth/submit-password{"password": "..."}— 2FA-парольPOST /api/v1/auth/logout— завершить сессиюGET /api/v1/stats— глобальные счётчикиGET /api/v1/settings— read-only вид конфигурацииGET /api/v1/channels— список каналовPOST /api/v1/channels{"identifier": "@durov"}— добавитьGET /api/v1/channels/{id}— карточкаPATCH /api/v1/channels/{id}{"is_active": false}— включить/выключитьDELETE /api/v1/channels/{id}— удалитьGET /api/v1/channels/{id}/stats— счётчики по каналуPOST /api/v1/channels/{id}/poll— форсировать опрос одного каналаPOST /api/v1/poll— форсировать опрос всех активных каналовGET /api/v1/messages?channel_id=...&q=...&limit=50&offset=0— лентаGET /api/v1/messages/{id}— одно сообщение (сrawJSONB)
Дальше
- Realtime: заменить APScheduler на
client.add_event_handler(handler, events.NewMessage), оставив periodic poll как фоновый «доводчик» для пропущенных сообщений. - Go-микросервис: контракт = таблицы
channels/messagesв Postgres. Go-сервис может либо читать ту же БД, либо ходить в/api/v1/messages. - k8s: добавить Helm-чарт;
data/session/маппится на PVC,.env— в Secret.