# Финансовый Telegram-бот Аккуратный бот для повседневного учёта личных финансов. Расход записывается одной строкой — `467 ярче` или `3000 бензин`. Зарплата распознаётся по словам `зп` и `зарплата`, например `5000 ЗП`. ## Что уже работает - автоматическое определение категорий: Продукты, Развлечения, Машина, Кредиты, Ремонт и Другое; - доходы, расходы и точные суммы с копейками; - изменение категории и удаление только что добавленной записи; - итоги за текущий месяц и за всё время; - аналитика по категориям с процентами и визуальными полосами — за месяц или всё время; - последние 10 операций; - ежедневный отчёт: траты и доходы за день плюс накопительный итог месяца; - отдельные данные для каждого Telegram-пользователя; - защищённый семейный бюджет для двух супругов с подтверждением владельца; - мгновенные уведомления супругу и в подключённый семейный Telegram-чат; - один общий вечерний отчёт в семейный чат; - общий долг: доходы автоматически уменьшают его, расходы увеличивают; - знак `-` у суммы принудительно уменьшает общий долг независимо от категории; - категории и подкатегории с возможностью добавлять собственные; - SQLite в режиме WAL и защита от повторного дневного отчёта; - готовый Docker-запуск на сервере. ## Развёртывание на сервере из GitHub Ниже приведён готовый вариант для чистого сервера с Ubuntu 22.04/24.04 или Debian 12. Установщик сам поставит Docker и Docker Compose, запросит настройки и запустит бота с автоматическим перезапуском. ### 1. Подготовьте доступ к приватному репозиторию Репозиторий приватный, поэтому серверу нужен SSH-ключ. На сервере выполните: ```bash sudo apt update sudo apt install -y git openssh-client ssh-keygen -t ed25519 -C "finance-bot-server" cat ~/.ssh/id_ed25519.pub ``` При создании ключа можно нажимать `Enter`, оставляя предлагаемые значения. Скопируйте строку, которую показала последняя команда. Откройте репозиторий в GitHub и добавьте ключ: **Settings → Deploy keys → Add deploy key**. Галочку **Allow write access** не включайте — серверу достаточно доступа на чтение только к этому репозиторию. Проверьте подключение: ```bash ssh -T git@github.com ``` При первом подключении ответьте `yes`. Сообщение GitHub об успешной аутентификации означает, что доступ настроен. ### 2. Скачайте и установите бота ```bash cd ~ git clone git@github.com:ochenstarik-ui/finance-telegram-bot.git cd finance-telegram-bot sudo bash install.sh ``` Во время установки будут запрошены: - папка установки — обычно достаточно нажать `Enter`, чтобы использовать `/opt/finance-bot`; - токен бота, полученный у [@BotFather](https://t.me/BotFather); - часовой пояс — по умолчанию `Asia/Novosibirsk`; - время ежедневного отчёта — по умолчанию `21:00`; - разрешение установить Docker, если его ещё нет. Токен при вводе не отображается. Настройки сохраняются в `/opt/finance-bot/.env` с доступом только для root, а база данных — в постоянном Docker-томе. ### 3. Проверьте запуск ```bash sudo docker compose -f /opt/finance-bot/compose.yaml ps sudo docker compose -f /opt/finance-bot/compose.yaml logs --tail=100 finance-bot ``` Для просмотра журнала в реальном времени: ```bash sudo docker compose -f /opt/finance-bot/compose.yaml logs -f finance-bot ``` Выход из просмотра журнала — `Ctrl+C`; бот при этом продолжит работать. ### Обновление до новой версии После появления изменений в GitHub выполните: ```bash cd ~/finance-telegram-bot git pull --ff-only sudo bash install.sh ``` Установщик предложит сохранить прежний токен. Повторное развёртывание пересоберёт контейнер, но не удалит `.env`, операции и настройки из базы данных. ### Управление ботом ```bash # Перезапустить sudo docker compose -f /opt/finance-bot/compose.yaml restart finance-bot # Остановить sudo docker compose -f /opt/finance-bot/compose.yaml stop finance-bot # Запустить после остановки sudo docker compose -f /opt/finance-bot/compose.yaml start finance-bot ``` Если `install.sh` запустить отдельно, без остальных файлов проекта рядом, он по-прежнему сможет загрузить резервную копию с Яндекс.Диска. ## Ручной запуск на сервере Понадобятся Docker и Docker Compose. 1. Создайте бота через [@BotFather](https://t.me/BotFather) и скопируйте токен. 2. На сервере скопируйте `.env.example` в `.env`. 3. В `.env` замените `BOT_TOKEN`, при необходимости настройте таймзону и время отчёта. 4. Запустите контейнер: ```bash docker compose up -d --build ``` Посмотреть состояние и журнал: ```bash docker compose ps docker compose logs -f finance-bot ``` Данные сохраняются в Docker-томе `finance-data` и не исчезают при пересборке контейнера. ## Настройки | Переменная | Пример | Назначение | |---|---|---| | `BOT_TOKEN` | `123:ABC...` | токен от BotFather | | `BOT_TIMEZONE` | `Asia/Novosibirsk` | таймзона операций и отчётов | | `DAILY_REPORT_TIME` | `21:00` | локальное время дневного отчёта | | `DATABASE_PATH` | `/app/data/finance.db` | путь к SQLite | | `LOG_LEVEL` | `INFO` | уровень журналирования | ## Семейный бюджет и общий чат 1. Первый супруг открывает кнопку **«Семья»** и выбирает **«Создать общий бюджет»**. 2. Второй супруг запускает этого же бота, открывает **«Семья»**, нажимает **«Ввести код супруга»** и отправляет полученный код. 3. Код не даёт доступ автоматически: создатель бюджета получает запрос с кнопками **«Подтвердить»** и **«Отклонить»**. 4. После подтверждения итоги, аналитика и история становятся общими. Новые записи мгновенно отправляются второму супругу. 5. Для общего журнала создайте Telegram-группу, добавьте туда бота. Создатель семейного бюджета должен быть администратором этой группы и отправить в ней команду `/family_chat`. После привязки каждая новая операция обоих супругов дублируется в группу. В заданное время туда также приходит один общий дневной отчёт. Посторонний человек не сможет подключиться только по коду: требуется ручное подтверждение владельца, семейный бюджет ограничен двумя участниками, а привязать групповой чат может только создатель бюджета, являющийся его администратором. ### Общий долг После создания семейного бюджета откройте кнопку **«💳 Общий долг»** и укажите текущую сумму. Сделать это может только создатель бюджета, второй супруг видит результат. Например, исходный долг составляет `530713`. После записи `400000 зарплата` бот покажет долг `130713`. Следующая запись `5000 продукты` увеличит его до `135713`. Запись `-5000 рабочий закуп` уменьшит долг на `5000`, хотя останется расходом в финансовой аналитике. Расчёт ведётся по операциям после установки исходной суммы: - каждый расход увеличивает долг; - каждый доход уменьшает долг; - сумма со знаком `-` уменьшает долг независимо от категории; сама сумма хранится положительной; - удаление ошибочной операции автоматически пересчитывает сумму; - если доходы превысят долг, бот покажет разницу как семейный резерв; - текущий долг или резерв отображается в подтверждениях, семейном чате и дневном отчёте. Повторная установка текущей суммы начинает новый расчёт с указанного значения, не меняя историю доходов и расходов. ### Категории и подкатегории В семейном бюджете доступна кнопка **«🗂 Категории»**. Категории общие для обоих супругов: каждый участник может добавить новую основную категорию или подкатегорию. При создании основной категории выбирается тип **«Расход»** или **«Доход»**; подкатегория наследует тип родителя. Перенос операции в категорию другого типа меняет её тип и влияние на долг. При создании бюджета бот автоматически добавляет базовое дерево, например: - Машина → Бензин, Ремонт, Запчасти, Мойка и парковка, Страховка; - Продукты → Еда, Алкоголь, Кафе и рестораны, Бытовые товары; - Развлечения → Кино и театр, Игры, Подписки, Хобби; - Кредиты → Ипотека, Кредиты, Рассрочки; - Ремонт → Материалы, Мебель, Работы, Инструменты. Стандартные подкатегории определяются автоматически: запись `3000 бензин` попадёт в **Машина → Бензин**, а `500 пиво` — в **Продукты → Алкоголь**. Чтобы создать свою структуру, нажмите **«🗂 Категории»**, затем **«Добавить категорию»** или **«Добавить подкатегорию»**. Новые пользовательские категории выбираются вручную при изменении записи. После добавления расхода нажмите **«Изменить категорию»**. Можно выбрать как основную категорию, так и любую подкатегорию. Это работает и для записей, которые первоначально попали в **«Другое»**. Изменить категорию может только автор операции; супруг и семейный чат сразу получают уведомление о переносе. ## Локальная разработка Нужен Python 3.11 или новее. ```bash python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -e ".[dev]" cp .env.example .env # Windows: copy .env.example .env ``` Переменные из `.env` нужно загрузить в окружение, затем запустить: ```bash python -m app ``` Тесты: ```bash pytest ``` ## Как расширять категории Названия, иконки и ключевые слова находятся в `app/categories.py`. Новые ключевые слова можно добавлять без изменения базы данных. Суммы хранятся целым числом копеек, поэтому арифметика не накапливает ошибки `float`.