5.2 KiB
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 # включая сегодня
остаток_на_утро = остаток + траты_сегодня
лимит_на_день = остаток_на_утро / дней_осталось
можно_сегодня = лимит_на_день − траты_сегодня
Лимит дня не сжимается от каждой траты внутри дня (модель «утреннего конверта»). Если сегодня вылез из лимита — завтра лимит пересчитается по новому остатку.
Быстрый старт
- Создай бота у @BotFather, скопируй токен.
- Установи зависимости:
python -m venv .venv
# Windows Git Bash / Linux:
source .venv/Scripts/activate # или .venv/bin/activate
pip install -r requirements.txt
- Создай
.envиз примера:
cp .env.example .env
# пропиши BOT_TOKEN=...
- Запуск:
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. После входа пользователь видит только свой бюджет и траты (/api/me/...).
Настройка BotFather
/setdomain→ укажи домен, с которого открывается кабинет (нужен публичный HTTPS; чистыйlocalhostобычно не работает).- 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
BOT_TOKEN=...
TELEGRAM_BOT_USERNAME=MyPayBot
PROXY_URL=socks5://127.0.0.1:10808
docker compose up -d --build
- кабинет: http://HOST:51290
- API: http://HOST:51291
Docker
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):
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):
BOT_TOKEN=...
PROXY_URL=socks5://127.0.0.1:10808
docker compose up -d --build
Проверка на хосте:
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.