Обновление зависимостей, устранение хардкода, оплата через Telegram
Библиотеки: - миграция с aiogram 2.25.2 (EOL) на aiogram 3.31: aiohttp обновился с 3.8.6 до 3.14.3, так как aiogram 2 жёстко требовал aiohttp<3.9 - самодельный словарь состояний заменён на FSM aiogram (MemoryStorage); это убирает падение на user_state.startswith(), когда состояния нет - из requirements убраны неиспользуемые пакеты (Babel 2.9.1, humanize, aiofiles, yookassa, YooMoney); оставлены только прямые зависимости Хардкод: - пути вычисляются от расположения файлов бота (awg/config.py), больше нет привязки к /root/amnezia-bot и к запуску из конкретного каталога - вместо 'python3.11' используется sys.executable; awg-decode.py переименован в awg_decode.py и импортируется напрямую вместо запуска через subprocess - newclient.sh и removeclient.sh определяют каталог по своему расположению, а не по cwd - install.sh: каталог, репозиторий, ветка и Python настраиваются переменными окружения, зависимости ставятся из requirements.txt - секреты можно задавать переменными окружения вместо config.json Оплата (встроенные платежи Telegram, провайдер ЮKassa): - счёт, pre_checkout_query и successful_payment; публичный HTTPS-адрес и вебхук не нужны - обработчик платежей вынесен в отдельный роутер и подключён первым: successful_payment приходит без текста и иначе перехватывался бы обработчиком, ожидающим ввода в FSM - выдача ключа идемпотентна по id платежа, повторная доставка апдейта не создаёт второй ключ - если после оплаты ключ создать не удалось, уведомляются администраторы - промокоды разделены на validate/consume: использование засчитывается только после фактической выдачи ключа, а не при проверке кода - поддержаны скидочные промокоды, уменьшающие сумму счёта - опциональные чеки по 54-ФЗ через provider_data Исправленные ошибки: - db.root_add и db.deactive_user_db передавали скриптам 2 аргумента вместо 4, из-за чего создание и удаление клиентов всегда падало; публичный ключ для удаления теперь вычисляется из конфига клиента - в create_backup не был импортирован zipfile (NameError при бэкапе) - планировщик запускался без задач, подписки никогда не истекали; добавлена ежечасная проверка с отключением доступа и уведомлением - callback_data вида renew_period_<имя>_<период> разбирался неверно для имён с подчёркиваниями; разделителем стало двоеточие - статус клиента брался из status.json, который никто не создавал; теперь используется wg show latest-handshakes - продление подписки сбрасывало остаток, теперь период добавляется к нему - Markdown-разметка ломалась на именах с подчёркиваниями; используется HTML с экранированием - vpn:// ключ уходит отдельным сообщением, а не в подписи к файлу, где мог не поместиться в лимит 1024 символа - блокирующие вызовы docker и скриптов вынесены в отдельные потоки - при удалении клиента связь с Telegram ID удаляется, а не пишется None Удалён мёртвый код: awg/wg.py (нигде не импортировался, содержал подсеть 10.0.0.0/24 вместо используемой 10.8.1.0/24) и handlers/add_client.py (импортировал несуществующий модуль loader).
Этот коммит содержится в:
+71
-16
@@ -1,27 +1,32 @@
|
||||
# AmneziaVPN Telegram Bot
|
||||
|
||||
Телеграм-бот на Python для управления [AmneziaVPN](https://github.com/amnezia-vpn/amnezia-client). Этот бот позволяет легко управлять клиентами.
|
||||
Телеграм-бот на Python для управления [AmneziaVPN](https://github.com/amnezia-vpn/amnezia-client). Этот бот позволяет легко управлять клиентами и продавать доступ через встроенные платежи Telegram.
|
||||
|
||||
Используется библиотека `aiogram` версии 2.25.2.
|
||||
Протестировано на Ubuntu, версии 20.04, 22.04, 24.04.
|
||||
Используется библиотека `aiogram` версии 3.x.
|
||||
Требуется Python 3.10 или новее. Протестировано на Ubuntu 20.04, 22.04, 24.04.
|
||||
|
||||
## Оглавление
|
||||
|
||||
- [Возможности](#возможности)
|
||||
- [Установка](#установка)
|
||||
- [Настройка оплаты](#настройка-оплаты)
|
||||
- [Конфигурация](#конфигурация)
|
||||
- [Запуск](#запуск)
|
||||
- [Заметки](#заметки)
|
||||
- [Поддержка](#поддержка)
|
||||
|
||||
## Возможности
|
||||
|
||||
- Добавление администраторов и модераторов для упралением VPN
|
||||
- Добавление клиентов
|
||||
- Удаление клиентов
|
||||
- Получение информации об IP-адресе клиента (берется из Endpoint, используется API ресурса [ip-api.com](http://ip-api.com))
|
||||
- Создание ключа в формате `vpn://` при генерации нового клиента (так же, при получении конфигурации клиента), для использования в [AmneziaVPN](https://github.com/amnezia-vpn/amnezia-client)
|
||||
- Роли: администраторы, модераторы и обычные пользователи
|
||||
- Добавление и удаление клиентов
|
||||
- Создание ключа в формате `vpn://` при генерации нового клиента (и при получении конфигурации), для использования в [AmneziaVPN](https://github.com/amnezia-vpn/amnezia-client)
|
||||
- Статус клиента онлайн/офлайн по реальному времени последнего handshake
|
||||
- Подписки на 1, 3, 6 и 12 месяцев с автоматическим отключением по истечении срока
|
||||
- Продление подписки на период или до произвольной даты; остаток активной подписки не сгорает
|
||||
- **Оплата подписки прямо в Telegram** (провайдер — ЮKassa), с чеками по 54-ФЗ при необходимости
|
||||
- Промокоды двух видов: выдающие ключ бесплатно и дающие скидку при оплате
|
||||
- Настраиваемые цены из интерфейса бота
|
||||
- Создание резервной копии
|
||||
- Инструкции по работе с VPN
|
||||
|
||||
## Установка
|
||||
|
||||
@@ -38,14 +43,65 @@
|
||||
- Придумать уникальное имя пользователя для бота (например, `AmneziaWGManagerBot_bot`). Оно должно оканчиваться на `_bot`.
|
||||
- После создания бота BotFather отправит вам токен для доступа к API. Его запросит бот во время первоначальной инициализации.
|
||||
|
||||
4. Получите ваш Telegram ID с помощью [Get My ID](https://t.me/getmyid_bot), просто написав боту.
|
||||
4. Получите ваш Telegram ID с помощью [Get My ID](https://t.me/getmyid_bot), просто написав боту.
|
||||
|
||||
5. Загрузите и запустите скрипт `install.sh`, с помощью которого будет автоматически установлен бот, со всеми зависимостями, в том числе, в качестве системной службы (автозапуск):
|
||||
|
||||
```bash
|
||||
curl -O https://raw.githubusercontent.com/stevefoxru/amnezia-bot/main/install.sh && chmod +x install.sh && ./install.sh
|
||||
curl -O https://raw.githubusercontent.com/viktor138irk/amnezia-bot/main/install.sh && chmod +x install.sh && ./install.sh
|
||||
```
|
||||
|
||||
## Настройка оплаты
|
||||
|
||||
Оплата работает на встроенных платежах Telegram, поэтому боту **не нужен публичный
|
||||
HTTPS-адрес, домен или сертификат** — Telegram сам подтверждает платёж.
|
||||
|
||||
1. Откройте [BotFather](https://t.me/BotFather) → `/mybots` → ваш бот → **Payments**.
|
||||
2. Выберите провайдера **ЮKassa** и подключите свой магазин.
|
||||
3. BotFather выдаст **токен провайдера** (для тестов — с пометкой `TEST`).
|
||||
4. Положите его в `awg/files/config.json` как `payment_provider_token` либо задайте
|
||||
переменной окружения `AWG_PAYMENT_PROVIDER_TOKEN`.
|
||||
|
||||
Если токен не задан, бот работает без оплаты: кнопка «Купить ключ» скрывается, ключи
|
||||
выдаются только по промокодам.
|
||||
|
||||
Минимальная сумма счёта в Telegram — 60 ₽, бот не даст выставить счёт меньше.
|
||||
|
||||
Для чеков по 54-ФЗ включите блок `payment_receipt` в конфигурации — тогда бот будет
|
||||
запрашивать email покупателя и передавать данные чека в ЮKassa.
|
||||
|
||||
## Конфигурация
|
||||
|
||||
Настройки лежат в `awg/files/config.json`, образец — в
|
||||
[`awg/files/config.json.example`](awg/files/config.json.example).
|
||||
|
||||
Любую настройку можно переопределить переменной окружения, чтобы не хранить секреты
|
||||
в файле:
|
||||
|
||||
| Переменная | Назначение |
|
||||
| --- | --- |
|
||||
| `AWG_BOT_HOME` | Каталог с данными бота (по умолчанию — каталог `awg/`) |
|
||||
| `AWG_BOT_TOKEN` | Токен бота |
|
||||
| `AWG_PAYMENT_PROVIDER_TOKEN` | Токен платёжного провайдера |
|
||||
| `AWG_PAYMENT_CURRENCY` | Валюта счетов (по умолчанию `RUB`) |
|
||||
| `AWG_ENDPOINT` | Адрес VPN-сервера |
|
||||
| `AWG_DOCKER_CONTAINER` | Имя контейнера Amnezia |
|
||||
| `AWG_WG_CONFIG_FILE` | Путь к конфигу WireGuard внутри контейнера |
|
||||
| `AWG_LOG_LEVEL` | Уровень логирования (по умолчанию `INFO`) |
|
||||
|
||||
Каталог установки больше не зашит в код: пути вычисляются относительно расположения
|
||||
файлов бота. `install.sh` тоже понимает `AWG_BOT_HOME`, `AWG_PYTHON_BIN`,
|
||||
`AWG_REPO_URL` и `AWG_REPO_BRANCH`.
|
||||
|
||||
### Промокоды
|
||||
|
||||
Формат добавления: `<код> <скидка%> <дней_действия> <макс_использований|none> <период|none>`
|
||||
|
||||
- `FREE1M 100 30 10 1_month` — бесплатный ключ на месяц, 10 активаций, промокод живёт 30 дней
|
||||
- `SALE20 20 30 none none` — скидка 20% при оплате, без ограничения по количеству
|
||||
|
||||
Использование промокода засчитывается только после фактической выдачи ключа.
|
||||
|
||||
## Запуск
|
||||
|
||||
1. Добавьте бота в Telegram и отправьте команду `/start` или `/help` для начала работы.
|
||||
@@ -54,11 +110,10 @@
|
||||
|
||||
Для обновления бота, необходимо запустить скрипт `install.sh`. В меню, необходимо выбрать пункт `Проверить обновления`.
|
||||
|
||||
При создании резервной копии, в архив добавляется директория connections (создается и содержит в себе логи подключений клиентов), conf, png, и сам конфигурационный файл.
|
||||
При создании резервной копии, в архив добавляется директория `users` (конфигурации клиентов), `files` (настройки, промокоды, платежи, сроки подписок) и скрипты бота.
|
||||
|
||||
Подписки проверяются раз в час: по истечении срока клиент удаляется с сервера, а его владелец получает уведомление.
|
||||
|
||||
## Поддержка
|
||||
|
||||
Поддержать разработчика можете следующими способами:
|
||||
|
||||
|
||||
Если у вас возникли вопросы или проблемы с установкой и использованием бота, создайте [issue](https://github.com/stevefoxru/amnezia-bot/issues) в этом репозитории или обратитесь к разработчику.
|
||||
Если у вас возникли вопросы или проблемы с установкой и использованием бота, создайте [issue](https://github.com/viktor138irk/amnezia-bot/issues) в этом репозитории или обратитесь к разработчику.
|
||||
|
||||
Ссылка в новой задаче
Block a user