Семейный дневник, который ведёт себя сам
Автор: Степан Д. @StefanDKO
FamilyLog превращает голосовые сообщения, фото, текст и документы из Telegram в красивые структурированные заметки в вашем личном Obsidian vault — автоматически, без лишних действий.
Вы просто пишете боту как обычно. Выбираете тип записи кнопкой, отправляете голосовые сообщения, фото или текст — и всё. Раз в день (или когда вам удобно) запускаете один скрипт, и FamilyLog:
- расшифровывает голосовые сообщения в текст
- описывает фотографии
- группирует всё в логичные сессии
- генерирует красивые markdown-заметки с тегами, связями и frontmatter
- записывает в ваш Obsidian vault
- делает записи в ваш Google Calendar, если вы установили интеграцию и делаете календарную заметку
Периодически бот присылает сводку — что было записано за неделю.
Нажмите на кнопку внизу экрана — и начнётся новая сессия записи:
| Кнопка | Что сохраняется |
|---|---|
| 📝 Заметка | Мысль, идея, информация, контент из сети (все что угодно) Каждая заметка - отдельный md файл |
| 📔 Дневник | События дня — добавляется в файл текущего дня (один день - один md файл) |
| 📅 Календарь | Событие или напоминание — отдельный файл + запись в гугл календаре (если настроена интеграция) |
| ✅ Задание | Задача с чекбоксом — в файл текущей недели |
Как пользоваться:
- Нажмите кнопку (например, 📔 Дневник) — сессия открыта
- Отправляйте голосовые, фото, текст — всё войдёт в одну запись
- Когда закончили — нажмите ту же кнопку снова (или любую другую — предыдущая сессия закроется)
- Можно пересылать сообщения из каналов — источник сохранится автоматически
FamilyLog фиксирует сообщения в момент их отправки — независимо от того, как они выглядят в чате после. Telegram хранит историю всех событий, и бот получает их все при сборе, даже если вы что-то удалили или отредактировали. Что из этого следует:
- Не удаляйте маркеры (📝 заметка, 📔 дневник и т.д.) — удалённый маркер всё равно будет обработан ботом и закроет/откроет сессию
- Не удаляйте контентные сообщения — удалённое сообщение всё равно попадёт в заметку, потому что бот уже получил его от Telegram
- Редактирование не учитывается — бот видит оригинальный текст, не исправленный вариант
- Сессия определяется последовательностью событий, а не тем, как выглядит чат. Если вы отправили 📝, потом сообщение, потом удалили 📝 и написали ещё два сообщения — бот создаст две разные сессии, хотя в чате всё выглядит как одна
- Это не касается редактирования сообщения перед его отправкой, но как только сообщение отправлено его лучше не редактировать иначе сессии будут рваные и вы получите не то что хотели в Obsidian.
Простое правило: отправили — считайте, что записано. Манипуляции с уже отправленными сообщениями не меняют того, что увидит бот.
Telegram Bot (polling)
|
v
[Collector] --- сообщения --> SQLite DB
|
v
[STT] --- голосовые --> текст (onnx-asr: GigaAM/Parakeet)
|
v
[Vision] --- фото --> описание (Qwen3-VL через LM Studio)
|
v
[Documents] --- файлы --> метаданные
|
v
[Assembler] --- собирает все части сессии в assembled_content
|
v
[LLM] --- assembled_content --> JSON (title, content, tags, related...) + summarization(once a week)
|
v
[Obsidian Writer] --- JSON --> markdown файл в vault через Local REST API
- Collector — polling Telegram API, сохранение в SQLite
- STT — транскрипция voice через GigaAM (offline, online планируется)
- Vision — описание фото через Qwen3-VL (offline, online планируется)
- Documents — скачивание файлов, формирование метаданных
- Assembler — объединение всех частей сессии в
assembled_content - LLM — генерация JSON: title, content (markdown + frontmatter), tags, related, people, context_summary
- Obsidian Writer — запись файла через Local REST API, обновление системных файлов (CURRENT_CONTEXT, TAGS_GLOSSARY, FAMILY_MEMORY), поиск related по тегам, backlinks
Перед установкой убедитесь, что у вас есть:
- Python 3.12+ (Тестировалось на 3.12. На других версиях работа не гарантируется.)
- uv — менеджер пакетов Python
- ffmpeg — для обработки голосовых сообщений
- LM Studio — для локальной обработки через LLM (если используете offline режим (пока только offline))
- Obsidian + плагин Local REST API. Он есть в официальных плагинах обсидиан.
- Telegram бот — создаётся через @BotFather
git clone https://github.com/JustStepan/familylog.git
cd familylog
uv syncuv run download_models.pyЭто загрузит модель для распознавания речи (~225–892 MB в зависимости от выбранной модели).
cp .env.example .envОткройте .env и заполните:
# Telegram
BOT_TOKEN=ваш_токен_от_BotFather
FAMILY_CHAT_IDS=[123456789, 987654321] # Telegram ID всех членов семьи
# Obsidian
OBSIDIAN_VAULT_PATH=/путь/к/вашему/vault
OBSIDIAN_API_KEY=ключ_из_плагина_Local_REST_API
# OBSIDIAN_API_KEY Берем в настройках плагина.
# Для локальной работы вполне подойдет "Enable Non-encrypted(HTTP) Server"(см. настройки плагина)
# с адресом "http://127.0.0.1:27123/"
OBSIDIAN_API_URL=http://localhost:27123Остальные настройки приложения меняются в src/config.py
Как узнать свой Telegram ID: напишите боту @userinfobot
Скопируйте шаблоны системных файлов в ваш vault:
cp -r vault_templates/_system /путь/к/vault/_systemИли вручную из папки проекта
Структура которая должна получиться:
vault/
_system/
AGENT_CONFIG.md ← инструкции для LLM-агента
FAMILY_MEMORY.md ← информация о членах семьи (заполните вручную)
TAGS_GLOSSARY.md ← глоссарий тегов
LAST_SUMMARY.md ← время последней сводки
intents/
note.md
diary.md
calendar.md
task.md
Откройте _system/FAMILY_MEMORY.md и добавьте информацию о членах семьи — имена, Telegram ID, роли. Это поможет боту правильно определять авторов записей.
uv run download_models.pyuv run setup_bot.pyОтправляет reply-клавиатуру всем членам семьи. Запускайте при первой настройке или если клавиатура пропала.
uv run run.pyЗапускает полный цикл: сбор сообщений → STT → Vision → LLM → запись в Obsidian.
Если с момента последней суммаризации прошло SUMMARY_INTERVAL_DAYS дней — автоматически сгенерирует сводку и отправит в Telegram.
uv run run.py --summaryГенерирует и отправляет сводку прямо сейчас, независимо от расписания.
vault/
notes/ ← заметки (отдельный файл на каждую)
diary/ ← дневник (один файл на день, записи добавляются)
calendar/ ← события (отдельный файл на каждое)
tasks/ ← задания (один файл на неделю, чекбоксы)
summaries/ ← еженедельные сводки
attachments/
photos/ ← фотографии из Telegram
documents/ ← документы (PDF, EPUB и др.)
_system/ ← конфигурация (не трогайте руками кроме FAMILY_MEMORY)
familylog/
├── run.py ← главная точка входа (+ --summary флаг)
├── setup_bot.py ← отправка клавиатуры
├── auth_google.py ← одноразовая авторизация Google Calendar
├── download_models.py ← скачивание STT моделей
├── vault_templates/ ← шаблоны системных файлов Obsidian
└── src/
├── config.py ← все настройки (pydantic-settings + .env)
├── constants.py ← текстовые константы и кнопки бота
└── familylog/
├── collector/
│ └── telegram.py ← сбор сообщений из Telegram
├── processor/
│ ├── stt.py ← расшифровка голосовых (GigaAM / Parakeet)
│ ├── vision.py ← описание фото (Qwen-VL)
│ ├── documents.py ← обработка документов
│ ├── assembler.py ← сборка сессий
│ ├── summary.py ← генерация сводок
│ └── obsidian/
│ ├── api.py ← Obsidian REST API
│ ├── general_data.py ← загрузка системных файлов
│ ├── utils.py ← генерация имён файлов
│ └── write_files.py ← запись и обновление vault
├── integrations/
│ └── google_calendar.py ← создание событий в Google Calendar
├── LLMs_calls/
│ ├── client.py ← OpenAI-совместимый клиент (lru_cache)
│ ├── calls.py ← вызовы LLM
│ └── model_manager.py ← управление моделями LM Studio
├── storage/
│ ├── database.py ← SQLAlchemy async
│ ├── models.py ← таблицы БД
│ └── telegram_files.py ← скачивание файлов из Telegram
└── bot/
├── keyboards.py ← построение клавиатуры (build_reply_keyboard)
└── sender.py ← отправка сообщений в Telegram
| Компонент | Технология |
|---|---|
| Backend | Python 3.12, asyncio |
| БД | SQLite + SQLAlchemy async |
| Telegram | aiogram, httpx |
| STT (offline) | onnx-asr: GigaAM v3 (русский язык) |
| STT (online) В разработке | Google Gemini via OpenRouter |
| Vision (offline) | Qwen3.5-VL через LM Studio |
| Vision (online) В разработке | Qwen-VL-Plus via OpenRouter |
| LLM (offline) | LM Studio (любая совместимая модель) |
| LLM (online) В разработке | OpenRouter (Claude, GPT и др.) |
| Obsidian | Local REST API плагин |
| Настройки | pydantic-settings |
Бот не отвечает на сообщения в реальном времени — это нормально?
Да. FamilyLog не работает в режиме реального времени. Бот принимает сообщения, Telegram хранит их в очереди. Когда вы запускаете run.py — всё накопленное обрабатывается разом.
Можно ли использовать без LM Studio? Нет. Пока эта возможность находится в разработке. Если будут запросы автор проекта добваит эту возможность.
Что если сессия не закрылась?
Сессии закрываются автоматически если последнее сообщение было более SESSION_TIMEOUT_MINUTES минут назад (по умолчанию 30). Это значение можно изменить в .env.
Как добавить нового члена семьи?
Добавьте его Telegram ID в FAMILY_CHAT_IDS в .env и опишите в _system/FAMILY_MEMORY.md в vault.
А что нужно ручками запускать скрипт? Да, это нужно для того чтобы запустить сборщика сообщений. Для того чтобы реализовать "бесчеловечную" работу приложения нужно устанавливать его на отдельном сервере и запрашивать ответы моделей по API. Однако первоначальная задумака в том, чтобы все работало локально.
Степан — @StefanDKO
Сейчас приложение работает с моделью распознования голоса от СберБанка - GigaAM. Однако, несмотря на хвалебные отзывы, мне она показалась менее качественной чем parekeet-0.6b от NVIDIA (https://huggingface.co/istupakov/parakeet-tdt-0.6b-v3-onnx). Если будут запросы я скину int-8 модель которую использую сам. По умолчанию установлена модель от GigaAM.