[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80079":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":15,"stars30d":15,"stars90d":14,"forks30d":14,"starsTrendScore":14,"compositeScore":16,"rankGlobal":9,"rankLanguage":9,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":14,"starSnapshotCount":14,"syncStatus":13,"lastSyncTime":25,"discoverSource":26},80079,"TelegramHelper","Magerko\u002FTelegramHelper","Magerko","Персональный AI-ассистент для Telegram: userbot + control bot с агентом, понимающим голос и свободный текст. SQLite FTS5, Qdrant, Whisper, OpenAI\u002FGemini.",null,"Python",61,10,2,0,1,43.72,"MIT License",false,"main",true,[],"2026-06-12 04:01:26","# TelegramHelper\n\nПерсональный AI-ассистент для Telegram-аккаунта. Состоит из двух частей в одном процессе:\n\n- **Userbot** (Telethon) — подключается к твоему аккаунту через MTProto. Зеркалит все входящие\u002Fисходящие сообщения в локальную БД, авто-отвечает оффлайн, отправляет сообщения от твоего имени.\n- **Control Bot** (aiogram) — Telegram-бот, через который ты управляешь userbot'ом. Понимает команды и **свободный текст или голос** через LLM-агента.\n\nТолько владелец (`OWNER_TELEGRAM_ID`) может пользоваться. Сессия Telethon, API-ключи и api_hash хранятся в локальной SQLite, зашифрованы Fernet.\n\n---\n\n## Фишка: пишешь как человеку\n\nСкажи или напиши боту обычным языком — агент сам поймёт что сделать.\n\n| Фраза владельца | Действие |\n|---|---|\n| «Напиши Оле, что созвон в 8» | Черновик → подтверждение → отправка |\n| «Напиши ему привет» (после разговора про контакт) | Помнит последний контакт из диалога |\n| «В одном из чатов я договаривался про мебель — на чём остановились?» | Поиск по тексту + по именам контактов → выбор → catchup |\n| «Дай выдержку из чата с Артёмом» | Саммари |\n| «Какие задачи в чате с боссом» | Извлечение и сохранение обещаний |\n| «Дай новости по AI агентам за 48 часов» | Дайджест по подписанным каналам |\n| «Добавь тему AI», «убери тему регулирование» | Управление авто-новостями |\n| «Дайджест в 9 утра», «выключи новости», «часовой пояс Europe\u002FMoscow» | Меняет настройки разговором |\n| «Напомни завтра в 18:00 позвонить маме» | Создаёт напоминание (агент знает твой TZ) |\n| «Поставь напоминания из чата с Артёмом» | Извлекает обещания и кладёт в \u002Ftodos |\n| «Включи новости и дайджест в 7, добавь тему AI» | Несколько действий за раз |\n| Голосовое сообщение | Транскрипция → агент → действие |\n\nДействия, видимые другим (отправка), всегда подтверждаются inline-кнопкой.\n\n---\n\n## Команды\n\n**Аккаунт**\n- `\u002Flogin` — пошагово: api_id → api_hash → телефон → код → 2FA\n- `\u002Flogout` — удалить сохранённую сессию\n- `\u002Fsync` — обновить контакты + фоновый prefetch последних сообщений в топ-30 активных чатов\n\n**Настройки**\n- `\u002Fsettings` — главное меню разделов с inline-кнопками\n\n**Чаты**\n- `\u002Fchat \u003Cимя>` — выбор контакта → саммари \u002F задачи \u002F черновик \u002F catchup\n- `\u002Fcatchup \u003Cимя>` — сразу к «где мы остановились»\n- `\u002Fsend \u003Cинструкция>` — «скажи Оле, что созвон в 8» (с подтверждением)\n- `\u002Fsearch \u003Cтекст>` — поиск (FTS5 + векторный, если индексировано)\n- `\u002Findex \u003Cимя>` — проиндексировать чат для семантического поиска\n\n**Память**\n- `\u002Ftodos` — открытые обещания (мои и мне), кнопки done\u002Fcancel\n- `\u002Fstyle \u003Cимя>` — пересчитать профиль моего стиля общения с этим контактом\n- `\u002Fdigest [now|on|off|at HH:MM]` — утренний дайджест\n\n**Новости**\n- `\u002Fnews \u003Cтема> [--hours=24]` — разовый дайджест из подписанных каналов\n- `\u002Fnews_channels` — пометить каналы-источники\n- `\u002Fnews_topics` — темы для утренних авто-новостей\n\n---\n\n## Как это устроено\n\n```\n┌──────────────────────────────────────────────────┐\n│  Control Bot (aiogram)                           │\n│  команды, FSM, inline-меню,                      │\n│  free-text + голос → агент                       │\n└────────────┬─────────────────────────────────────┘\n             │\n┌────────────▼─────────────────────────────────────┐\n│  Core                                            │\n│  • Agent (LLM intent router)                     │\n│  • LLM router (OpenAI ↔ Gemini)                  │\n│  • ChatService, Summarizer, Style profile        │\n│  • Commitments, Reminders, Digest, News          │\n│  • Conversation context (краткая память)         │\n└────────────┬───────────────────────┬─────────────┘\n             │ MTProto                │ embeddings\u002FLLM\n┌────────────▼─────────┐     ┌────────▼──────────┐\n│ Userbot (Telethon)   │     │ Storage           │\n│ • Auth с 2FA         │     │ • SQLite + FTS5   │\n│ • NewMessage mirror  │     │ • Qdrant embedded │\n│ • UpdateFolderPeers  │     │ • Fernet secrets  │\n│ • Auto-reply offline │     │                   │\n└──────────────────────┘     └───────────────────┘\n```\n\n**Фоновые задачи** в одном event loop:\n- `digest-scheduler` — утренний дайджест в выбранное время по TZ владельца\n- `news-scheduler` — авто-дайджест по темам-фаворитам\n- `reminders-loop` — пинги о приближении\u002Fпросрочке дедлайнов\n- `auto-sync` — раз в час обновляет контакты и архивный статус\n\n**Real-time mirror.** Каждое входящее и исходящее сообщение в любом чате тут же пишется в `messages` таблицу. SQLite FTS5-индекс синхронизируется триггерами — поиск работает локально за миллисекунды (не через Telegram API).\n\n**Lazy-транскрипция.** Голосовые при mirror'инге сохраняются без транскрипта — она запускается в момент анализа конкретного чата (faster-whisper локально или OpenAI Whisper API, по настройке).\n\n**Prefetch при `\u002Fsync`.** Один раз для топ-N активных чатов подтягиваются последние ~50 сообщений в БД — заполняет холодный кэш. После этого mirror поддерживает свежесть.\n\n---\n\n## Стек\n\n- Python 3.12\n- **aiogram 3.x** — control bot\n- **Telethon 1.36+** — userbot (MTProto)\n- **SQLAlchemy 2** + **aiosqlite** + **SQLite FTS5** — БД и полнотекстовый поиск\n- **Qdrant** (embedded) — векторный поиск\n- **OpenAI SDK** + **google-genai** — LLM (gpt-5-mini \u002F gpt-5.5, gemini-3-flash \u002F gemini-3.1-pro)\n- **faster-whisper** + OpenAI Whisper API — транскрипция голоса (local \u002F api \u002F hybrid)\n- **pypdf**, **python-docx** — документы\n- **rapidfuzz** — fuzzy-резолвер контактов\n- **cryptography (Fernet)** — шифрование секретов\n\nИмена моделей вынесены в `src\u002Fconfig.py:LLMDefaults` — заменить при выходе новых.\n\n---\n\n## Запуск через Docker\n\n### 1. Подготовь данные\n\n| Что | Где взять |\n|---|---|\n| `BOT_TOKEN` | [@BotFather](https:\u002F\u002Ft.me\u002FBotFather) → `\u002Fnewbot` |\n| `OWNER_TELEGRAM_ID` | [@userinfobot](https:\u002F\u002Ft.me\u002Fuserinfobot) — пришлёт `id` |\n| `ENCRYPTION_KEY` | Fernet-ключ (см. ниже) |\n\n```powershell\n# С пакетом cryptography:\npython -c \"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())\"\n\n# Без cryptography:\npython -c \"import secrets, base64; print(base64.urlsafe_b64encode(secrets.token_bytes(32)).decode())\"\n```\n\n### 2. `.env`\n\n```env\nBOT_TOKEN=123456:AA...\nOWNER_TELEGRAM_ID=987654321\nENCRYPTION_KEY=\u003Cbase64-fernet-key>\nDATABASE_URL=sqlite+aiosqlite:\u002F\u002F\u002Fdata\u002Fapp.db\n```\n\n### 3. Подними\n\n```bash\ndocker compose up -d --build\ndocker compose logs -f assistant\n```\n\nПервая сборка занимает 3–5 минут (Python + ffmpeg + зависимости). Образ кэшируется.\n\n`.\u002Fdata\u002F` смонтирован как volume — там лежат:\n- `app.db` — SQLite с FTS5 индексом\n- `qdrant\u002F` — векторное хранилище\n- `media\u002F` — скачанные voice\u002Faudio\u002Fдокументы\n- `cache\u002F` — кэш моделей `faster-whisper` (~500 MB после первой транскрипции)\n\n### 4. Авторизация в боте\n\nВ чате с control-ботом:\n\n1. `\u002Fstart` — приветствие\n2. `\u002Flogin` — пошагово:\n   - `api_id` (число) с https:\u002F\u002Fmy.telegram.org → API development tools\n   - `api_hash` (32 hex)\n   - телефон в формате `+71234567890`\n   - код из Telegram — **с пробелами между цифрами** (`1 2 3 4 5`), иначе Telegram автоматически инвалидирует код, увидев его открыто в чате\n   - 2FA-пароль, если включён (сообщение с паролем удаляется сразу после успеха)\n3. `\u002Fsettings → 🔑 API-ключи` — OpenAI или Gemini key (проверится перед сохранением)\n4. `\u002Fsettings → 🌍 Часовой пояс` — пресет или произвольный IANA\n5. `\u002Fsync` — подтянуть контакты + фоновый prefetch сообщений\n\nПосле этого можно писать боту обычным текстом или голосом.\n\n---\n\n## Настройки\n\n`\u002Fsettings` — главное меню. Каждая фича — отдельный раздел с описанием и тогглами:\n\n- **🌍 Часовой пояс** — от него отталкиваются шедулеры и отображения времён.\n- **🔄 Авто-ответ** — режимы `static` (заготовленный текст) и `smart` (LLM в твоём стиле). Кулдаун 5\u002F15\u002F30\u002F60 мин. Только ЛС, не группы и не боты, только когда оффлайн.\n- **☀ Дайджест** — утренняя сводка: ждут ответа, горящие обещания, авто-ответы.\n- **⏰ Напоминания** — пинги о дедлайнах. Lead 1\u002F2\u002F4\u002F12\u002F24 ч; алерт при просрочке.\n- **📰 Новости** — авто-дайджест по темам из `\u002Fnews_topics`.\n- **🛡 Приватность** — игнорировать архив (по умолчанию ВКЛ): архивные чаты не подгружаются никуда.\n- **🤖 LLM** — переключение OpenAI ↔ Gemini, лёгкая ↔ тяжёлая модель.\n- **🎤 Транскрипция** — `local` \u002F `api` \u002F `hybrid`.\n- **🔑 API-ключи** — хранятся зашифрованными.\n\nЛюбую настройку можно поменять и **разговором**: «дайджест в 7 утра», «выключи новости», «текст автоответа: Сейчас занят».\n\n---\n\n## Безопасность и приватность\n\n- Только `OWNER_TELEGRAM_ID` проходит фильтр `OwnerOnly` на каждом роутере.\n- Шифрование Fernet для session-string, api_hash, всех LLM-ключей. Ключ из `ENCRYPTION_KEY` не попадает в БД.\n- Сообщения с 2FA-паролем и API-ключами удаляются из чата сразу после успеха.\n- `.env` и `data\u002F` исключены из git.\n- Mirror пишет сообщения в **локальную БД на твоей машине**, никуда не отправляет.\n- Архивные чаты по умолчанию исключаются из видимости.\n- Все отправляемые сообщения — через двухшаговое подтверждение (`PendingAction`).\n\n---\n\n## Структура проекта\n\n```\nsrc\u002F\n├── main.py                  # bootstrap: init_db → restore userbots → schedulers → bot\n├── config.py                # pydantic-settings + LLMDefaults\n├── crypto.py                # Fernet\n├── bot\u002F\n│   ├── app.py               # регистрация роутеров (free_text — последним)\n│   ├── filters.py           # OwnerOnly\n│   ├── states.py            # FSM-states\n│   └── handlers\u002F\n│       ├── start.py         # \u002Fstart, \u002Fhelp\n│       ├── login.py         # \u002Flogin (FSM с 2FA), \u002Flogout, \u002Fcancel\n│       ├── settings.py      # \u002Fsettings — меню + разделы\n│       ├── chat_cmd.py      # \u002Fchat, \u002Fsync (с prefetch)\n│       ├── catchup_cmd.py   # \u002Fcatchup\n│       ├── send.py          # \u002Fsend + подтверждения\n│       ├── search.py        # \u002Fsearch, \u002Findex\n│       ├── todos.py         # \u002Ftodos\n│       ├── digest_cmd.py    # \u002Fdigest\n│       ├── style_cmd.py     # \u002Fstyle\n│       ├── news_cmd.py      # \u002Fnews, \u002Fnews_channels\n│       ├── news_topics.py   # \u002Fnews_topics\n│       └── free_text.py     # AI-агент: текст\u002Fголос → intent → действие\n├── core\u002F\n│   ├── agent.py             # LLM intent router\n│   ├── chat_finder.py       # smart_find: FTS5 + LLM-classify имён + Tg fallback\n│   ├── conversation_context.py  # краткая память диалога с агентом\n│   ├── notifier.py          # bridge userbot → control bot\n│   ├── contact_resolver.py  # rapidfuzz по локальной БД контактов\n│   ├── chat_service.py      # load_chat: incremental + lazy транскрипция\n│   ├── transcription.py     # faster-whisper \u002F OpenAI Whisper hybrid\n│   ├── documents.py         # PDF\u002FDOCX\u002FTXT\n│   ├── summarizer.py        # summary \u002F draft \u002F catchup промпты\n│   ├── style_profile.py     # JSON-профиль стиля per-контакт\n│   ├── commitment_extractor.py  # извлечение обещаний\n│   ├── digest.py            # утренний дайджест + scheduler\n│   ├── news.py              # дайджест по каналам + scheduler\n│   ├── reminders.py         # пинги о дедлайнах\n│   ├── auto_sync.py         # фоновый re-sync контактов раз в час\n│   ├── timeutil.py          # zoneinfo helpers\n│   ├── text_sanitizer.py    # привод HTML к Telegram-whitelist\n│   ├── vector_store.py      # Qdrant embedded\n│   └── indexer.py           # batch индексация → embeddings\n├── userbot\u002F\n│   ├── manager.py           # UserbotManager + pending login\n│   ├── dialogs.py           # sync_dialogs, prefetch_recent_messages\n│   ├── auto_reply.py        # NewMessage handler (offline + cooldown)\n│   ├── dialog_events.py     # UpdateFolderPeers → Contact.is_archived\n│   └── mirror.py            # Real-time mirror всех сообщений в БД и FTS5\n├── llm\u002F\n│   ├── base.py              # ChatMessage + Protocol\n│   ├── openai_provider.py\n│   ├── gemini_provider.py\n│   └── router.py            # build_provider по UserSettings\n└── db\u002F\n    ├── models.py            # User, Settings, Session, ApiKey, Contact, Message,\n    │                        # Commitment, AutoReplyLog, IndexJob, TranscriptionCache,\n    │                        # PendingAction, NewsTopic\n    ├── session.py           # async engine + init_db (включая FTS5 schema)\n    └── repo.py              # CRUD с (де)шифрованием на границе + fts_search\n```\n\n---\n\n## Известные ограничения\n\n- **Telegram ToS**: userbot с авто-ответом — серая зона. По умолчанию авто-ответ выключен и шлёт нейтральный заготовленный текст с кулдауном между ответами.\n- **Один инстанс**: Qdrant embedded держит lock на `data\u002Fqdrant\u002F` — параллельно бот не запустишь.\n- **Single-tenant**: фильтр `OwnerOnly` рассчитан на одного владельца.\n- **Миграций нет**: при изменении моделей удали `data\u002Fapp.db` (или подключи Alembic).\n\n---\n\n## Шпаргалка\n\n```bash\n# логи\ndocker compose logs -f assistant\n\n# зайти в контейнер\ndocker compose exec assistant sh\n\n# полный сброс БД (сессия Telethon, ключи, контакты — всё)\ndocker compose down\nrm -f data\u002Fapp.db data\u002Fapp.db-journal data\u002Fapp.db-shm data\u002Fapp.db-wal\ndocker compose up -d\n\n# смена версий моделей: src\u002Fconfig.py → LLMDefaults\n```\n\n---\n\n## Лицензия\n\nMIT.\n","TelegramHelper 是一个针对 Telegram 账号的个人 AI 助手，由用户机器人和控制机器人两部分组成。用户机器人通过 MTProto 协议连接到用户的账号，能够镜像所有进出的消息至本地数据库，并在离线时自动回复；控制机器人则允许用户通过自然语言或语音命令来管理用户机器人的行为。项目使用了 SQLite FTS5、Qdrant、Whisper 和 OpenAI\u002FGemini 等技术，支持消息搜索、摘要生成、任务提取等功能。适用于需要高效管理和自动化处理日常通信任务的场景，比如安排会议、跟踪对话中的承诺事项或是获取特定主题的新闻摘要等。","2026-06-11 03:59:09","CREATED_QUERY"]