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

158 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Финансовый Telegram-бот
Аккуратный бот для повседневного учёта личных финансов. Расход записывается одной строкой — `467 ярче` или `3000 бензин`. Доход — через `+ 85000 зарплата` или `доход 5000 подработка`.
## Что уже работает
- автоматическое определение категорий: Продукты, Развлечения, Машина, Кредиты, Ремонт и Другое;
- доходы, расходы и точные суммы с копейками;
- изменение категории и удаление только что добавленной записи;
- итоги за текущий месяц и за всё время;
- аналитика по категориям с процентами и визуальными полосами — за месяц или всё время;
- последние 10 операций;
- ежедневный отчёт: траты и доходы за день плюс накопительный итог месяца;
- отдельные данные для каждого Telegram-пользователя;
- защищённый семейный бюджет для двух супругов с подтверждением владельца;
- мгновенные уведомления супругу и в подключённый семейный Telegram-чат;
- один общий вечерний отчёт в семейный чат;
- общий долг: доходы автоматически уменьшают его, расходы увеличивают;
- категории и подкатегории с возможностью добавлять собственные;
- SQLite в режиме WAL и защита от повторного дневного отчёта;
- готовый Docker-запуск на сервере.
## Автоматическая установка на сервер
Для Ubuntu или Debian используйте интерактивный установщик `install.sh`. Он скачивает актуальную копию проекта с публичной папки Яндекс.Диска, при необходимости устанавливает Docker, спрашивает токен и настройки отчётов, после чего запускает бота.
Скопируйте `install.sh` на сервер и выполните:
```bash
sudo bash install.sh
```
Или скачайте сам установщик из публичной папки прямо на сервере:
```bash
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](https://t.me/BotFather);
- часовой пояс;
- время ежедневного отчёта.
Повторный запуск обновляет код, но сохраняет `.env` и базу данных в Docker-томе. Публичная ссылка проекта уже записана в скрипте. При необходимости её можно переопределить:
```bash
sudo FINANCE_BOT_PUBLIC_URL="https://disk.yandex.ru/d/другая-ссылка" bash 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`.
Расчёт ведётся по операциям после установки исходной суммы:
- каждый расход увеличивает долг;
- каждый доход уменьшает долг;
- удаление ошибочной операции автоматически пересчитывает сумму;
- если доходы превысят долг, бот покажет разницу как семейный резерв;
- текущий долг или резерв отображается в подтверждениях, семейном чате и дневном отчёте.
Повторная установка текущей суммы начинает новый расчёт с указанного значения, не меняя историю доходов и расходов.
### Категории и подкатегории
В семейном бюджете доступна кнопка **«🗂 Категории»**. Категории общие для обоих супругов: каждый участник может добавить новую основную категорию или подкатегорию.
При создании бюджета бот автоматически добавляет базовое дерево, например:
- Машина → Бензин, Ремонт, Запчасти, Мойка и парковка, Страховка;
- Продукты → Еда, Алкоголь, Кафе и рестораны, Бытовые товары;
- Развлечения → Кино и театр, Игры, Подписки, Хобби;
- Кредиты → Ипотека, Кредиты, Рассрочки;
- Ремонт → Материалы, Мебель, Работы, Инструменты.
Стандартные подкатегории определяются автоматически: запись `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`.