finance-telegram-bot/README.md
2026-07-14 12:31:06 +07:00

14 KiB
Raw Blame History

Финансовый Telegram-бот

Аккуратный бот для повседневного учёта личных финансов. Расход записывается одной строкой — 467 ярче или 3000 бензин. Доход — через + 85000 зарплата или доход 5000 подработка.

Что уже работает

  • автоматическое определение категорий: Продукты, Развлечения, Машина, Кредиты, Ремонт и Другое;
  • доходы, расходы и точные суммы с копейками;
  • изменение категории и удаление только что добавленной записи;
  • итоги за текущий месяц и за всё время;
  • аналитика по категориям с процентами и визуальными полосами — за месяц или всё время;
  • последние 10 операций;
  • ежедневный отчёт: траты и доходы за день плюс накопительный итог месяца;
  • отдельные данные для каждого Telegram-пользователя;
  • защищённый семейный бюджет для двух супругов с подтверждением владельца;
  • мгновенные уведомления супругу и в подключённый семейный Telegram-чат;
  • один общий вечерний отчёт в семейный чат;
  • общий долг: доходы автоматически уменьшают его, расходы увеличивают;
  • категории и подкатегории с возможностью добавлять собственные;
  • SQLite в режиме WAL и защита от повторного дневного отчёта;
  • готовый Docker-запуск на сервере.

Развёртывание на сервере из GitHub

Ниже приведён готовый вариант для чистого сервера с Ubuntu 22.04/24.04 или Debian 12. Установщик сам поставит Docker и Docker Compose, запросит настройки и запустит бота с автоматическим перезапуском.

1. Подготовьте доступ к приватному репозиторию

Репозиторий приватный, поэтому серверу нужен SSH-ключ. На сервере выполните:

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 не включайте — серверу достаточно доступа на чтение только к этому репозиторию.

Проверьте подключение:

ssh -T git@github.com

При первом подключении ответьте yes. Сообщение GitHub об успешной аутентификации означает, что доступ настроен.

2. Скачайте и установите бота

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;
  • часовой пояс — по умолчанию Asia/Novosibirsk;
  • время ежедневного отчёта — по умолчанию 21:00;
  • разрешение установить Docker, если его ещё нет.

Токен при вводе не отображается. Настройки сохраняются в /opt/finance-bot/.env с доступом только для root, а база данных — в постоянном Docker-томе.

3. Проверьте запуск

sudo docker compose -f /opt/finance-bot/compose.yaml ps
sudo docker compose -f /opt/finance-bot/compose.yaml logs --tail=100 finance-bot

Для просмотра журнала в реальном времени:

sudo docker compose -f /opt/finance-bot/compose.yaml logs -f finance-bot

Выход из просмотра журнала — Ctrl+C; бот при этом продолжит работать.

Обновление до новой версии

После появления изменений в GitHub выполните:

cd ~/finance-telegram-bot
git pull --ff-only
sudo bash install.sh

Установщик предложит сохранить прежний токен. Повторное развёртывание пересоберёт контейнер, но не удалит .env, операции и настройки из базы данных.

Управление ботом

# Перезапустить
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 и скопируйте токен.
  2. На сервере скопируйте .env.example в .env.
  3. В .env замените BOT_TOKEN, при необходимости настройте таймзону и время отчёта.
  4. Запустите контейнер:
docker compose up -d --build

Посмотреть состояние и журнал:

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.

Расчёт ведётся по операциям после установки исходной суммы:

  • каждый расход увеличивает долг;
  • каждый доход уменьшает долг;
  • удаление ошибочной операции автоматически пересчитывает сумму;
  • если доходы превысят долг, бот покажет разницу как семейный резерв;
  • текущий долг или резерв отображается в подтверждениях, семейном чате и дневном отчёте.

Повторная установка текущей суммы начинает новый расчёт с указанного значения, не меняя историю доходов и расходов.

Категории и подкатегории

В семейном бюджете доступна кнопка «🗂 Категории». Категории общие для обоих супругов: каждый участник может добавить новую основную категорию или подкатегорию.

При создании бюджета бот автоматически добавляет базовое дерево, например:

  • Машина → Бензин, Ремонт, Запчасти, Мойка и парковка, Страховка;
  • Продукты → Еда, Алкоголь, Кафе и рестораны, Бытовые товары;
  • Развлечения → Кино и театр, Игры, Подписки, Хобби;
  • Кредиты → Ипотека, Кредиты, Рассрочки;
  • Ремонт → Материалы, Мебель, Работы, Инструменты.

Стандартные подкатегории определяются автоматически: запись 3000 бензин попадёт в Машина → Бензин, а 500 пиво — в Продукты → Алкоголь.

Чтобы создать свою структуру, нажмите «🗂 Категории», затем «Добавить категорию» или «Добавить подкатегорию». Новые пользовательские категории выбираются вручную при изменении записи.

После добавления расхода нажмите «Изменить категорию». Можно выбрать как основную категорию, так и любую подкатегорию. Это работает и для записей, которые первоначально попали в «Другое». Изменить категорию может только автор операции; супруг и семейный чат сразу получают уведомление о переносе.

Локальная разработка

Нужен Python 3.11 или новее.

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 нужно загрузить в окружение, затем запустить:

python -m app

Тесты:

pytest

Как расширять категории

Названия, иконки и ключевые слова находятся в app/categories.py. Новые ключевые слова можно добавлять без изменения базы данных. Суммы хранятся целым числом копеек, поэтому арифметика не накапливает ошибки float.