feat(proj): init
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
# Please Pay Me Bot
|
||||
|
||||
Telegram-бот + web-кабинет для жизни «от зарплаты до зарплаты».
|
||||
|
||||
**Стек сейчас:** Telegram bot (Python) · **API ASP.NET Core + PostgreSQL** (`src/PleasePayMe.*`) · React web.
|
||||
Python-папка `api/` устарела; HTTP-контракт `/api/...` для бота и web сохранён.
|
||||
|
||||
## Возможности
|
||||
|
||||
- Задать бюджет: сумма + дата до зарплаты
|
||||
- Пересчёт дневного лимита по остатку и числу дней
|
||||
- Быстрый ввод трат: `250`, `250 кофе`, `кофе 250`
|
||||
- Статус / траты за сегодня / отмена последней траты
|
||||
- Кнопки внизу чата для частых действий
|
||||
|
||||
## Логика лимита
|
||||
|
||||
```
|
||||
остаток = бюджет − все траты периода
|
||||
дней_осталось = (дата_конца − сегодня) + 1 # включая сегодня
|
||||
остаток_на_утро = остаток + траты_сегодня
|
||||
лимит_на_день = остаток_на_утро / дней_осталось
|
||||
можно_сегодня = лимит_на_день − траты_сегодня
|
||||
```
|
||||
|
||||
Лимит дня не сжимается от каждой траты внутри дня (модель «утреннего конверта»). Если сегодня вылез из лимита — завтра лимит пересчитается по новому остатку.
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
1. Создай бота у [@BotFather](https://t.me/BotFather), скопируй токен.
|
||||
2. Установи зависимости:
|
||||
|
||||
```bash
|
||||
python -m venv .venv
|
||||
# Windows Git Bash / Linux:
|
||||
source .venv/Scripts/activate # или .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
3. Создай `.env` из примера:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# пропиши BOT_TOKEN=...
|
||||
```
|
||||
|
||||
4. Запуск:
|
||||
|
||||
```bash
|
||||
python -m bot.main
|
||||
```
|
||||
|
||||
## Команды
|
||||
|
||||
| Команда / кнопка | Действие |
|
||||
|---|---|
|
||||
| `/budget` | Новый бюджет (сумма → дата) |
|
||||
| `/status` | Лимит и остаток |
|
||||
| `/today` | Список трат за сегодня |
|
||||
| `/history` | Траты за период бюджета (постранично) |
|
||||
| `/day 12.09` | Список трат за дату |
|
||||
| `/spend` | Диалог: трата за другую дату |
|
||||
| `/undo` | Удалить последнюю трату |
|
||||
| `/help` | Справка |
|
||||
|
||||
Трата за дату одним сообщением: `за 12.09 250 кофе`, `12.09 250`, `250 кофе 12.09`.
|
||||
|
||||
Данные хранятся локально в SQLite: `data/budget.db`.
|
||||
|
||||
## Web-кабинет (личный, через Telegram)
|
||||
|
||||
Вход через [Telegram Login Widget](https://core.telegram.org/widgets/login). После входа пользователь видит **только свой** бюджет и траты (`/api/me/...`).
|
||||
|
||||
### Настройка BotFather
|
||||
|
||||
1. `/setdomain` → укажи домен, с которого открывается кабинет (нужен публичный HTTPS; чистый `localhost` обычно не работает).
|
||||
2. Username бота без `@` положи в `.env` как `TELEGRAM_BOT_USERNAME`.
|
||||
|
||||
### API
|
||||
|
||||
| Метод | Путь | Auth | Описание |
|
||||
|---|---|---|---|
|
||||
| POST | `/api/auth/telegram` | — | обмен данных Login Widget на JWT |
|
||||
| GET | `/api/me` | Bearer JWT | профиль |
|
||||
| GET | `/api/me/budget` | Bearer JWT | свой бюджет |
|
||||
| GET | `/api/me/expenses` | Bearer JWT | свои траты |
|
||||
| GET | `/api/budgets`… | `API_TOKEN` | админский список (опционально) |
|
||||
|
||||
### Docker
|
||||
|
||||
```env
|
||||
BOT_TOKEN=...
|
||||
TELEGRAM_BOT_USERNAME=MyPayBot
|
||||
PROXY_URL=socks5://127.0.0.1:10808
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
- кабинет: http://HOST:51290
|
||||
- API: http://HOST:51291
|
||||
|
||||
## Docker
|
||||
|
||||
```bash
|
||||
docker build -t please-pay-me-bot .
|
||||
docker run --rm -e BOT_TOKEN=your_token -v "$(pwd)/data:/app/data" please-pay-me-bot
|
||||
```
|
||||
|
||||
На Windows (PowerShell):
|
||||
|
||||
```powershell
|
||||
docker build -t please-pay-me-bot .
|
||||
docker run --rm -e BOT_TOKEN=your_token -v ${PWD}/data:/app/data please-pay-me-bot
|
||||
```
|
||||
|
||||
Том `data` сохраняет SQLite между перезапусками.
|
||||
|
||||
### Прокси (Xray на хосте + бот в Docker)
|
||||
|
||||
**Рекомендуемый способ:** `network_mode: host` — контейнер видит `127.0.0.1` хоста, Xray можно оставить на loopback.
|
||||
|
||||
В `.env` (токен только здесь, не в compose):
|
||||
|
||||
```env
|
||||
BOT_TOKEN=...
|
||||
PROXY_URL=socks5://127.0.0.1:10808
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Проверка на хосте:
|
||||
|
||||
```bash
|
||||
curl -x socks5h://127.0.0.1:10808 https://api.telegram.org
|
||||
```
|
||||
|
||||
Если без `host` сети (bridge): Xray должен слушать `0.0.0.0`, а в `PROXY_URL` — gateway хоста (`172.17.0.1` или `host.docker.internal`). Скрипт: `./scripts/open_xray_listen.sh`. У Portainer custom-сеть часто **не** имеет маршрута к `172.17.0.1`, из‑за этого был timeout.
|
||||
Reference in New Issue
Block a user