11 KiB
Финансовый Telegram-бот
Аккуратный бот для повседневного учёта личных финансов. Расход записывается одной строкой — 467 ярче или 3000 бензин. Доход — через + 85000 зарплата или доход 5000 подработка.
Что уже работает
- автоматическое определение категорий: Продукты, Развлечения, Машина, Кредиты, Ремонт и Другое;
- доходы, расходы и точные суммы с копейками;
- изменение категории и удаление только что добавленной записи;
- итоги за текущий месяц и за всё время;
- аналитика по категориям с процентами и визуальными полосами — за месяц или всё время;
- последние 10 операций;
- ежедневный отчёт: траты и доходы за день плюс накопительный итог месяца;
- отдельные данные для каждого Telegram-пользователя;
- защищённый семейный бюджет для двух супругов с подтверждением владельца;
- мгновенные уведомления супругу и в подключённый семейный Telegram-чат;
- один общий вечерний отчёт в семейный чат;
- общий долг: доходы автоматически уменьшают его, расходы увеличивают;
- категории и подкатегории с возможностью добавлять собственные;
- SQLite в режиме WAL и защита от повторного дневного отчёта;
- готовый Docker-запуск на сервере.
Автоматическая установка на сервер
Для Ubuntu или Debian используйте интерактивный установщик install.sh. Он скачивает актуальную копию проекта с публичной папки Яндекс.Диска, при необходимости устанавливает Docker, спрашивает токен и настройки отчётов, после чего запускает бота.
Скопируйте install.sh на сервер и выполните:
sudo bash install.sh
Или скачайте сам установщик из публичной папки прямо на сервере:
PUBLIC_URL='https://disk.yandex.ru/d/hhbDTO08CB030Q'
INSTALLER_URL="$(curl -fsSG 'https://cloud-api.yandex.net/v1/disk/public/resources/download' \
--data-urlencode "public_key=$PUBLIC_URL" --data-urlencode 'path=/install.sh' \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["href"])')"
curl -fsSL "$INSTALLER_URL" -o install.sh
sudo bash install.sh
Установщик спросит:
- папку установки;
- токен, полученный у @BotFather;
- часовой пояс;
- время ежедневного отчёта.
Повторный запуск обновляет код, но сохраняет .env и базу данных в Docker-томе. Публичная ссылка проекта уже записана в скрипте. При необходимости её можно переопределить:
sudo FINANCE_BOT_PUBLIC_URL="https://disk.yandex.ru/d/другая-ссылка" bash install.sh
Ручной запуск на сервере
Понадобятся Docker и Docker Compose.
- Создайте бота через @BotFather и скопируйте токен.
- На сервере скопируйте
.env.exampleв.env. - В
.envзаменитеBOT_TOKEN, при необходимости настройте таймзону и время отчёта. - Запустите контейнер:
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 |
уровень журналирования |
Семейный бюджет и общий чат
- Первый супруг открывает кнопку «Семья» и выбирает «Создать общий бюджет».
- Второй супруг запускает этого же бота, открывает «Семья», нажимает «Ввести код супруга» и отправляет полученный код.
- Код не даёт доступ автоматически: создатель бюджета получает запрос с кнопками «Подтвердить» и «Отклонить».
- После подтверждения итоги, аналитика и история становятся общими. Новые записи мгновенно отправляются второму супругу.
- Для общего журнала создайте 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.