76 lines
9.5 KiB
Markdown
76 lines
9.5 KiB
Markdown
# Выгрузка 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 |
|
||
| Чаты | **все кипрские группы и каналы** (владелец 2026-10-18): `--kinds group supergroup channel --only кипр cyprus @…` — всё с «кипр»/«cyprus» в названии (подстрока, без регистра; новые кипрские группы — сами) плюс явные @username без этих слов (@cylaw, @cymedic, @cyprusinet, @cyschools — заявка ждёт админа, @cyfasttrack, …), Cyprus Car – Chat (`-1001315261949`). Личные переписки и боты — нет. История — **с 2024-10-18**. ⚠️ Выгружаются только чаты, где аккаунт состоит; в группах со скрытой историей — только с даты вступления (CypRus Helpers — с 2026-06-20) |
|
||
| Таймер | `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) читает тексты, но **не видит сессию и ключи**.
|
||
|
||
## Установка и вход
|
||
|
||
```sh
|
||
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`).
|
||
- **Скорость** (2026-10-18, 85 тыс. кусков): векторы всех кусков — `index.emb.npz` рядом с индексом (пересобирается после
|
||
индексации; из SQLite на HDD было ~40 с на запрос); модель держит служба **`tg-embed`** (astra, сокет
|
||
`/run/tg-embed/embed.sock` 0600, ~140 МБ RSS) — загрузка модели в процесс ~11 с (fastembed/ONNX; model2vec ещё
|
||
медленнее, 28 с — проверено, векторы те же). Итого `tg search` ~6 с. Нет службы — `tg` грузит модель сам.
|
||
- `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` — посмотреть.
|
||
- **Вечерний рекап группы целиком** (с 2026-10-18): `tg digest add @чат` (список — `/var/lib/tg-report/digests.json`),
|
||
`tg-digest.timer` 23:50 Asia/Nicosia → `tg digest run`: все куски чата **с прошлого рекапа** (не календарный день —
|
||
сообщения после последней ежечасной докачки уйдут в следующий рекап, без дыр), до 60 тыс. знаков (больше — последние),
|
||
Codex пишет темы дня и «Полезное» со ссылками → очередь outbox. Сейчас: CY Fast Track Talks (@cyfasttrack).
|
||
`tg digest run --dry --hours 24` — посмотреть.
|
||
- **Участники группы с аватарками** — `app/tg_members.py` (`/opt/tg-export/tg_members.py @чат`, от tgexport, ⚠️ не параллельно
|
||
с `tg-export.service` — одна сессия): `/mnt/backup/tg/members/<id>_<название>/members.{json,csv}` + `avatars/<id>.jpg`
|
||
(маленькие). Персональные данные участников — в поиск/индекс не идут. 2026-10-18: CY Fast Track Talks — 2774 из 2774,
|
||
аватарок 1619. Разовая выгрузка, не по таймеру.
|
||
- **Личные каналы участников** — `app/tg_bios.py`: bio и «личный канал» каждого участника (GetFullUser, ~1 запрос/с —
|
||
2765 профилей за ~55 мин без ограничений) → `bios.json`. 2026-10-18 CY Fast Track Talks: личный канал у 145 из 2765,
|
||
топ — `top-personal-channels.txt` в папке участников. ⚠️ Второй шаг скрипта (размер каждой ссылки через
|
||
`get_entity` = ResolveUsername) после ~190 запросов получил **FloodWait 77 545 с (~22 ч)** — остановлен; размеры
|
||
публичных каналов взяты со страниц `t.me/<username>` (без сессии). Массово резолвить username через API нельзя —
|
||
брать `t.me`-страницы или `full.chats` из GetFullUser.
|