Skip to content

Magerko/TelegramHelper

Repository files navigation

TelegramHelper

Персональный AI-ассистент для Telegram-аккаунта. Состоит из двух частей в одном процессе:

  • Userbot (Telethon) — подключается к твоему аккаунту через MTProto. Зеркалит все входящие/исходящие сообщения в локальную БД, авто-отвечает оффлайн, отправляет сообщения от твоего имени.
  • Control Bot (aiogram) — Telegram-бот, через который ты управляешь userbot'ом. Понимает команды и свободный текст или голос через LLM-агента.

Только владелец (OWNER_TELEGRAM_ID) может пользоваться. Сессия Telethon, API-ключи и api_hash хранятся в локальной SQLite, зашифрованы Fernet.


Фишка: пишешь как человеку

Скажи или напиши боту обычным языком — агент сам поймёт что сделать.

Фраза владельца Действие
«Напиши Оле, что созвон в 8» Черновик → подтверждение → отправка
«Напиши ему привет» (после разговора про контакт) Помнит последний контакт из диалога
«В одном из чатов я договаривался про мебель — на чём остановились?» Поиск по тексту + по именам контактов → выбор → catchup
«Дай выдержку из чата с Артёмом» Саммари
«Какие задачи в чате с боссом» Извлечение и сохранение обещаний
«Дай новости по AI агентам за 48 часов» Дайджест по подписанным каналам
«Добавь тему AI», «убери тему регулирование» Управление авто-новостями
«Дайджест в 9 утра», «выключи новости», «часовой пояс Europe/Moscow» Меняет настройки разговором
«Напомни завтра в 18:00 позвонить маме» Создаёт напоминание (агент знает твой TZ)
«Поставь напоминания из чата с Артёмом» Извлекает обещания и кладёт в /todos
«Включи новости и дайджест в 7, добавь тему AI» Несколько действий за раз
Голосовое сообщение Транскрипция → агент → действие

Действия, видимые другим (отправка), всегда подтверждаются inline-кнопкой.


Команды

Аккаунт

  • /login — пошагово: api_id → api_hash → телефон → код → 2FA
  • /logout — удалить сохранённую сессию
  • /sync — обновить контакты + фоновый prefetch последних сообщений в топ-30 активных чатов

Настройки

  • /settings — главное меню разделов с inline-кнопками

Чаты

  • /chat <имя> — выбор контакта → саммари / задачи / черновик / catchup
  • /catchup <имя> — сразу к «где мы остановились»
  • /send <инструкция> — «скажи Оле, что созвон в 8» (с подтверждением)
  • /search <текст> — поиск (FTS5 + векторный, если индексировано)
  • /index <имя> — проиндексировать чат для семантического поиска

Память

  • /todos — открытые обещания (мои и мне), кнопки done/cancel
  • /style <имя> — пересчитать профиль моего стиля общения с этим контактом
  • /digest [now|on|off|at HH:MM] — утренний дайджест

Новости

  • /news <тема> [--hours=24] — разовый дайджест из подписанных каналов
  • /news_channels — пометить каналы-источники
  • /news_topics — темы для утренних авто-новостей

Как это устроено

┌──────────────────────────────────────────────────┐
│  Control Bot (aiogram)                           │
│  команды, FSM, inline-меню,                      │
│  free-text + голос → агент                       │
└────────────┬─────────────────────────────────────┘
             │
┌────────────▼─────────────────────────────────────┐
│  Core                                            │
│  • Agent (LLM intent router)                     │
│  • LLM router (OpenAI ↔ Gemini)                  │
│  • ChatService, Summarizer, Style profile        │
│  • Commitments, Reminders, Digest, News          │
│  • Conversation context (краткая память)         │
└────────────┬───────────────────────┬─────────────┘
             │ MTProto                │ embeddings/LLM
┌────────────▼─────────┐     ┌────────▼──────────┐
│ Userbot (Telethon)   │     │ Storage           │
│ • Auth с 2FA         │     │ • SQLite + FTS5   │
│ • NewMessage mirror  │     │ • Qdrant embedded │
│ • UpdateFolderPeers  │     │ • Fernet secrets  │
│ • Auto-reply offline │     │                   │
└──────────────────────┘     └───────────────────┘

Фоновые задачи в одном event loop:

  • digest-scheduler — утренний дайджест в выбранное время по TZ владельца
  • news-scheduler — авто-дайджест по темам-фаворитам
  • reminders-loop — пинги о приближении/просрочке дедлайнов
  • auto-sync — раз в час обновляет контакты и архивный статус

Real-time mirror. Каждое входящее и исходящее сообщение в любом чате тут же пишется в messages таблицу. SQLite FTS5-индекс синхронизируется триггерами — поиск работает локально за миллисекунды (не через Telegram API).

Lazy-транскрипция. Голосовые при mirror'инге сохраняются без транскрипта — она запускается в момент анализа конкретного чата (faster-whisper локально или OpenAI Whisper API, по настройке).

Prefetch при /sync. Один раз для топ-N активных чатов подтягиваются последние ~50 сообщений в БД — заполняет холодный кэш. После этого mirror поддерживает свежесть.


Стек

  • Python 3.12
  • aiogram 3.x — control bot
  • Telethon 1.36+ — userbot (MTProto)
  • SQLAlchemy 2 + aiosqlite + SQLite FTS5 — БД и полнотекстовый поиск
  • Qdrant (embedded) — векторный поиск
  • OpenAI SDK + google-genai — LLM (gpt-5-mini / gpt-5.5, gemini-3-flash / gemini-3.1-pro)
  • faster-whisper + OpenAI Whisper API — транскрипция голоса (local / api / hybrid)
  • pypdf, python-docx — документы
  • rapidfuzz — fuzzy-резолвер контактов
  • cryptography (Fernet) — шифрование секретов

Имена моделей вынесены в src/config.py:LLMDefaults — заменить при выходе новых.


Запуск через Docker

1. Подготовь данные

Что Где взять
BOT_TOKEN @BotFather/newbot
OWNER_TELEGRAM_ID @userinfobot — пришлёт id
ENCRYPTION_KEY Fernet-ключ (см. ниже)
# С пакетом cryptography:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

# Без cryptography:
python -c "import secrets, base64; print(base64.urlsafe_b64encode(secrets.token_bytes(32)).decode())"

2. .env

BOT_TOKEN=123456:AA...
OWNER_TELEGRAM_ID=987654321
ENCRYPTION_KEY=<base64-fernet-key>
DATABASE_URL=sqlite+aiosqlite:///data/app.db

3. Подними

docker compose up -d --build
docker compose logs -f assistant

Первая сборка занимает 3–5 минут (Python + ffmpeg + зависимости). Образ кэшируется.

./data/ смонтирован как volume — там лежат:

  • app.db — SQLite с FTS5 индексом
  • qdrant/ — векторное хранилище
  • media/ — скачанные voice/audio/документы
  • cache/ — кэш моделей faster-whisper (~500 MB после первой транскрипции)

4. Авторизация в боте

В чате с control-ботом:

  1. /start — приветствие
  2. /login — пошагово:
    • api_id (число) с https://my.telegram.org → API development tools
    • api_hash (32 hex)
    • телефон в формате +71234567890
    • код из Telegram — с пробелами между цифрами (1 2 3 4 5), иначе Telegram автоматически инвалидирует код, увидев его открыто в чате
    • 2FA-пароль, если включён (сообщение с паролем удаляется сразу после успеха)
  3. /settings → 🔑 API-ключи — OpenAI или Gemini key (проверится перед сохранением)
  4. /settings → 🌍 Часовой пояс — пресет или произвольный IANA
  5. /sync — подтянуть контакты + фоновый prefetch сообщений

После этого можно писать боту обычным текстом или голосом.


Настройки

/settings — главное меню. Каждая фича — отдельный раздел с описанием и тогглами:

  • 🌍 Часовой пояс — от него отталкиваются шедулеры и отображения времён.
  • 🔄 Авто-ответ — режимы static (заготовленный текст) и smart (LLM в твоём стиле). Кулдаун 5/15/30/60 мин. Только ЛС, не группы и не боты, только когда оффлайн.
  • ☀ Дайджест — утренняя сводка: ждут ответа, горящие обещания, авто-ответы.
  • ⏰ Напоминания — пинги о дедлайнах. Lead 1/2/4/12/24 ч; алерт при просрочке.
  • 📰 Новости — авто-дайджест по темам из /news_topics.
  • 🛡 Приватность — игнорировать архив (по умолчанию ВКЛ): архивные чаты не подгружаются никуда.
  • 🤖 LLM — переключение OpenAI ↔ Gemini, лёгкая ↔ тяжёлая модель.
  • 🎤 Транскрипцияlocal / api / hybrid.
  • 🔑 API-ключи — хранятся зашифрованными.

Любую настройку можно поменять и разговором: «дайджест в 7 утра», «выключи новости», «текст автоответа: Сейчас занят».


Безопасность и приватность

  • Только OWNER_TELEGRAM_ID проходит фильтр OwnerOnly на каждом роутере.
  • Шифрование Fernet для session-string, api_hash, всех LLM-ключей. Ключ из ENCRYPTION_KEY не попадает в БД.
  • Сообщения с 2FA-паролем и API-ключами удаляются из чата сразу после успеха.
  • .env и data/ исключены из git.
  • Mirror пишет сообщения в локальную БД на твоей машине, никуда не отправляет.
  • Архивные чаты по умолчанию исключаются из видимости.
  • Все отправляемые сообщения — через двухшаговое подтверждение (PendingAction).

Структура проекта

src/
├── main.py                  # bootstrap: init_db → restore userbots → schedulers → bot
├── config.py                # pydantic-settings + LLMDefaults
├── crypto.py                # Fernet
├── bot/
│   ├── app.py               # регистрация роутеров (free_text — последним)
│   ├── filters.py           # OwnerOnly
│   ├── states.py            # FSM-states
│   └── handlers/
│       ├── start.py         # /start, /help
│       ├── login.py         # /login (FSM с 2FA), /logout, /cancel
│       ├── settings.py      # /settings — меню + разделы
│       ├── chat_cmd.py      # /chat, /sync (с prefetch)
│       ├── catchup_cmd.py   # /catchup
│       ├── send.py          # /send + подтверждения
│       ├── search.py        # /search, /index
│       ├── todos.py         # /todos
│       ├── digest_cmd.py    # /digest
│       ├── style_cmd.py     # /style
│       ├── news_cmd.py      # /news, /news_channels
│       ├── news_topics.py   # /news_topics
│       └── free_text.py     # AI-агент: текст/голос → intent → действие
├── core/
│   ├── agent.py             # LLM intent router
│   ├── chat_finder.py       # smart_find: FTS5 + LLM-classify имён + Tg fallback
│   ├── conversation_context.py  # краткая память диалога с агентом
│   ├── notifier.py          # bridge userbot → control bot
│   ├── contact_resolver.py  # rapidfuzz по локальной БД контактов
│   ├── chat_service.py      # load_chat: incremental + lazy транскрипция
│   ├── transcription.py     # faster-whisper / OpenAI Whisper hybrid
│   ├── documents.py         # PDF/DOCX/TXT
│   ├── summarizer.py        # summary / draft / catchup промпты
│   ├── style_profile.py     # JSON-профиль стиля per-контакт
│   ├── commitment_extractor.py  # извлечение обещаний
│   ├── digest.py            # утренний дайджест + scheduler
│   ├── news.py              # дайджест по каналам + scheduler
│   ├── reminders.py         # пинги о дедлайнах
│   ├── auto_sync.py         # фоновый re-sync контактов раз в час
│   ├── timeutil.py          # zoneinfo helpers
│   ├── text_sanitizer.py    # привод HTML к Telegram-whitelist
│   ├── vector_store.py      # Qdrant embedded
│   └── indexer.py           # batch индексация → embeddings
├── userbot/
│   ├── manager.py           # UserbotManager + pending login
│   ├── dialogs.py           # sync_dialogs, prefetch_recent_messages
│   ├── auto_reply.py        # NewMessage handler (offline + cooldown)
│   ├── dialog_events.py     # UpdateFolderPeers → Contact.is_archived
│   └── mirror.py            # Real-time mirror всех сообщений в БД и FTS5
├── llm/
│   ├── base.py              # ChatMessage + Protocol
│   ├── openai_provider.py
│   ├── gemini_provider.py
│   └── router.py            # build_provider по UserSettings
└── db/
    ├── models.py            # User, Settings, Session, ApiKey, Contact, Message,
    │                        # Commitment, AutoReplyLog, IndexJob, TranscriptionCache,
    │                        # PendingAction, NewsTopic
    ├── session.py           # async engine + init_db (включая FTS5 schema)
    └── repo.py              # CRUD с (де)шифрованием на границе + fts_search

Известные ограничения

  • Telegram ToS: userbot с авто-ответом — серая зона. По умолчанию авто-ответ выключен и шлёт нейтральный заготовленный текст с кулдауном между ответами.
  • Один инстанс: Qdrant embedded держит lock на data/qdrant/ — параллельно бот не запустишь.
  • Single-tenant: фильтр OwnerOnly рассчитан на одного владельца.
  • Миграций нет: при изменении моделей удали data/app.db (или подключи Alembic).

Шпаргалка

# логи
docker compose logs -f assistant

# зайти в контейнер
docker compose exec assistant sh

# полный сброс БД (сессия Telethon, ключи, контакты — всё)
docker compose down
rm -f data/app.db data/app.db-journal data/app.db-shm data/app.db-wal
docker compose up -d

# смена версий моделей: src/config.py → LLMDefaults

Лицензия

MIT.

About

Персональный AI-ассистент для Telegram: userbot + control bot с агентом, понимающим голос и свободный текст. SQLite FTS5, Qdrant, Whisper, OpenAI/Gemini.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors