Files
infra/stacks/rpi-tg-export

Выгрузка Telegram — второй аккаунт владельца (rpi)

Проект tg_export (Telethon, MTProto) перенесён с Mac 2026-10-17: на малине — второй аккаунт владельца, регулярная докачка только текста (медиа — позже, если понадобится), поиск (RAG) и утренняя сводка по темам. Старая выгрузка первого аккаунта (~14 ГБ) осталась на Mac в ~/pets/tg_export/out, сюда не переносилась; анализ (stats, trips, presence…) — там же.

Что Где
Код /opt/tg-export/ (export.py, fetch_public.py, channel_comments.py), venv /opt/tg-export/venv
Обёртка /usr/local/bin/tg-export — подставляет --session и --out, ключи из env
Ключи приложения (TG_API_ID/TG_API_HASH, my.telegram.org) /etc/tg-export/env — root:tgexport 640, в git нет
Сессия (= полный доступ к аккаунту) /var/lib/tg-export/tg.session — tgexport 600
Выгрузка /mnt/backup/tg/ — dialogs.json, chats/<id>_<название>/{messages.jsonl,messages.txt,meta.json,_state.json}; tgexport:astra, каталоги 2750, файлы 640
Чаты только выбранные владельцем (--only в юните, 2026-10-18): @CupRusHelpers, @cyvisaorg, @cymedic, @CypRusSale, @cyprusdiy, @cylang, @badcyprus, @cyschools (заявка на вступление ждёт одобрения админа), @cyprusit, @cyprusinet, @cylaw, @cyprussport, Cyprus Car – Chat (-1001315261949). Личные переписки и боты (в т.ч. рабочие) — нет. История — с 2024-10-18 (--since, последние 2 года на момент запуска; дата фиксирована, дальше копится всё новое). ⚠️ В группах со скрытой для новых участников историей видно только с даты вступления (CypRus Helpers — с 2026-06-20). ⚠️ Выгружаются только чаты, где аккаунт состоит: не вступивший --only молча пропускает
Таймер tg-export.timer — каждый час ±5 мин (было 04:30 раз в сутки), tg-export.service (oneshot, run --no-media --archived, затем tgrag.py index)
Мониторинг ExecStopPost=+backup-metrics backup_tg_export → алерты BackupFailed / BackupStale (>30 ч)

Пользователь tgexport — системный, без шелла: Astra (группа astra) читает тексты, но не видит сессию и ключи.

Установка и вход

sudo sh install.sh                                   # код, venv, пользователь, каталоги, юниты
sudo install -o root -g tgexport -m 640 env /etc/tg-export/env   # ключи приложения (как .env.example)
ssh -t rpi sudo -u tgexport tg-export login          # номер, код из Telegram, 2FA — делает владелец
sudo systemctl enable --now tg-export.timer

Вручную: sudo -u tgexport tg-export list (диалоги), sudo -u tgexport tg-export run --no-media --only @чат. Повторный запуск догружает только новое (_state.json в каждом чате), --full — перезалить чат.

⚠️ Первый прогон долгий: Telegram троттлит массовое чтение (FloodWait, скрипт ждёт до 24 ч) — BackupStale может сработать, пока он идёт; следующий запуск таймера не стартует поверх идущего. ⚠️ Медиа выключены (--no-media); включить — убрать флаг в юните (лимит по умолчанию 50 МБ на файл).

Поиск (RAG) и утренняя сводка — tg (с 2026-10-18)

/opt/tg-export/tgrag.py, обёртка /usr/local/bin/tg (запускает astra):

  • Индекс /mnt/backup/tg/index.db (SQLite, журнал DELETE — не WAL, чтобы astra читала без записи в -shm): кусок = подряд идущие сообщения одного чата с паузами < 20 мин, до ~800 знаков, строки «Автор: текст»; FTS5 + эмбеддинги. Пишет tgexport (ExecStartPost после каждой докачки), инкрементально по id; последний кусок пересобирается, если разговор продолжился.
  • Модель — minishlab/potion-multilingual-128M (fastembed, статические эмбеддинги, /opt/tg-export/models). Сравнение на 8 тыс. сообщений групп 2026-10-18: potion 57 с, paraphrase-multilingual-MiniLM-L12-v2 915 с при сопоставимом качестве поиска (MiniLM к тому же видит только ~128 токенов куска). e5-large/jina-v3 на Pi 4 — дни на историю. Сменить — TG_EMB_MODEL + переиндексация (удалить index.db).
  • tg search ЗАПРОС [--chat] [--since 90d] [-n] — гибрид BM25 + косинус (RRF), куски со ссылками t.me (t.me/<username>/<id> или t.me/c/<id>/<msg>). ⚠️ Одна формулировка часто промахивается («посоветуйте спортзал» не нашло «фитнес в отелях») — Astra по навыку tg переформулирует 2–4 раза.
  • Сводка: темы tg topic add "Тема" --query "ключевые слова" → /var/lib/tg-report/topics.json; tg-report.timer 08:00 Asia/Nicosia (не съедет при переходе Кипра на зимнее время) → tg report: по теме — найденное за 24 ч (словами — всегда, по смыслу — близость ≥ 0.4), сжимает Codex (codex exec, подписка Astra — не лимит Claude читалки) → очередь /var/lib/astra-google/outbox/ → gcal remind шлёт владельцу. ⚠️ Очередь шлёт одним sendMessage без разбиения: сводка режется на части ≤ 3800 знаков (иначе файл > 4096 застрял бы и заблокировал очередь). Тем нет или индекса нет — ничего не шлёт. tg report --dry — посмотреть.