логика, отправка уведомлений всем
This commit is contained in:
@@ -1,87 +0,0 @@
|
||||
# 🚀 SoloBot
|
||||
|
||||
**[SoloBot]**!
|
||||
[Бот для API x-ray]
|
||||
|
||||
## 📋 Оглавление
|
||||
1. [Описание](#описание)
|
||||
2. [Требования](#требования)
|
||||
3. [Установка](#установка)
|
||||
4. [Конфигурация](#конфигурация)
|
||||
5. [Запуск](#запуск)
|
||||
6. [Автор](#автор)
|
||||
|
||||
---
|
||||
|
||||
## 📖 Описание
|
||||
|
||||
[Бот предназначен для автоматизирования выдачи ключей, хранении их в базе данных и управления подключениями]
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 💻 Требования
|
||||
|
||||
Для работы проекта необходимы следующие компоненты:
|
||||
|
||||
- **Python** версии 3.8 или выше
|
||||
- **Git** для клонирования репозитория
|
||||
- **Virtualenv** для создания виртуального окружения (рекомендуется)
|
||||
- **postgresql** для работы базы данных
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Установка
|
||||
|
||||
### 1️⃣ Шаг 1: Клонирование репозитория
|
||||
|
||||
Клонируйте репозиторий и перейдите в его директорию:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Vladless/Solo_bot.git
|
||||
cd solo_bot
|
||||
```
|
||||
|
||||
### 2️⃣ Шаг 2: Создание и активация виртуального окружения
|
||||
|
||||
```
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
```
|
||||
|
||||
### 3️⃣ Шаг 3: Установка зависимостей
|
||||
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 🛠️ Конфигурация
|
||||
|
||||
Для правильной работы вам нужно установить и запустить postgresql, создать пользователя для работы с базой данных и выдать ему права
|
||||
|
||||
Также создайте файл config.py в корневой папке проекта с вашими данными:
|
||||
|
||||
```
|
||||
API_TOKEN = токен вашего бота телеграм
|
||||
API_URL = домен вашего x-ray сервера с указанием порта и дополнительным путем панели вида "https://{domen}:{port}/{путь}" без слэша в конце
|
||||
ADMIN_USERNAME = логин от вашей панели x-ray
|
||||
ADMIN_PASSWORD = пароль от вашей панели x-ray
|
||||
ADD_CLIENT_URL = f"{API_URL}/panel/api/inbounds/addClient"
|
||||
GET_INBOUNDS_URL = f"{API_URL}/panel/api/inbounds/list/"
|
||||
AUTH_URL = f"{API_URL}/login/"
|
||||
DOMEN = "{ваш домен без https://}:443"
|
||||
DATABASE_URL = путь к вашей базе данных, имеет вид "postgresql://{user}:{password}@{Ip-adress}:{port}/{имя базы данных}"
|
||||
ADMIN_ID = ID телеграм профиля администратора
|
||||
CHANNEL_URL = ссылка на ваш телеграм канал
|
||||
```
|
||||
|
||||
### 🚀 Запуск
|
||||
|
||||
введите команду из виртуального окружения
|
||||
|
||||
```
|
||||
python main.py
|
||||
```
|
||||
🔗 SoloBot в Telegram
|
||||
|
||||
Попробуйте SoloBot прямо сейчас в Telegram [по этой ссылке](https://t.me/SoloNetVPN_bot).
|
||||
+61
-11
@@ -1,6 +1,7 @@
|
||||
import re
|
||||
import uuid
|
||||
from datetime import datetime, timedelta
|
||||
from aiogram.filters import Command
|
||||
|
||||
import asyncpg
|
||||
from aiogram import F, Router, types
|
||||
@@ -10,12 +11,11 @@ from aiogram.types import (CallbackQuery, InlineKeyboardButton,
|
||||
InlineKeyboardMarkup, Message)
|
||||
|
||||
from auth import link, login_with_credentials
|
||||
from bot import dp
|
||||
from bot import dp, bot
|
||||
from client import add_client
|
||||
from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL, SERVERS
|
||||
from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL, SERVERS, ADMIN_ID
|
||||
from database import add_connection, get_balance, store_key, update_balance
|
||||
from handlers.instructions import send_instructions
|
||||
from handlers.notifications import send_message_to_all_clients
|
||||
from handlers.profile import process_callback_view_profile
|
||||
from handlers.start import start_command
|
||||
|
||||
@@ -28,6 +28,7 @@ class Form(StatesGroup):
|
||||
waiting_for_server_selection = State()
|
||||
waiting_for_key_name = State()
|
||||
viewing_profile = State()
|
||||
waiting_for_message = State()
|
||||
|
||||
@dp.callback_query(F.data == 'create_key')
|
||||
async def process_callback_create_key(callback_query: CallbackQuery, state: FSMContext):
|
||||
@@ -122,26 +123,75 @@ async def cancel_create_key(callback_query: CallbackQuery, state: FSMContext):
|
||||
await process_callback_view_profile(callback_query, state)
|
||||
await callback_query.answer()
|
||||
|
||||
@dp.message()
|
||||
async def handle_text(message: Message, state: FSMContext):
|
||||
@router.message(Command('start'))
|
||||
async def handle_start(message: types.Message, state: FSMContext):
|
||||
# Обработка команды /start
|
||||
await start_command(message)
|
||||
|
||||
@router.message(Command('menu'))
|
||||
async def handle_menu(message: types.Message, state: FSMContext):
|
||||
# Обработка команды /menu
|
||||
await start_command(message)
|
||||
|
||||
@router.message(Command('send_to_all'))
|
||||
async def send_message_to_all_clients(message: types.Message, state: FSMContext):
|
||||
if message.from_user.id != ADMIN_ID:
|
||||
await message.answer("У вас нет прав для выполнения этой команды.")
|
||||
return
|
||||
|
||||
await message.answer("Введите текст сообщения, который вы хотите отправить всем клиентам:")
|
||||
await state.set_state(Form.waiting_for_message) # Устанавливаем состояние ожидания сообщения
|
||||
|
||||
@router.message(Form.waiting_for_message)
|
||||
async def process_message_to_all(message: types.Message, state: FSMContext):
|
||||
text_message = message.text # Получаем текст сообщения
|
||||
|
||||
try:
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
tg_ids = await conn.fetch('SELECT tg_id FROM connections')
|
||||
|
||||
for record in tg_ids:
|
||||
tg_id = record['tg_id']
|
||||
try:
|
||||
await bot.send_message(chat_id=tg_id, text=text_message)
|
||||
except Exception as e:
|
||||
print(f"Ошибка при отправке сообщения пользователю {tg_id}: {e}. Пропускаем этого пользователя.")
|
||||
|
||||
await message.answer("Сообщение было отправлено всем клиентам.")
|
||||
except Exception as e:
|
||||
print(f"Ошибка при подключении к базе данных: {e}")
|
||||
await message.answer("Произошла ошибка при отправке сообщения.")
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
await state.clear() # Очистка состояния после отправки сообщения
|
||||
|
||||
@router.message()
|
||||
async def handle_text(message: types.Message, state: FSMContext):
|
||||
current_state = await state.get_state()
|
||||
|
||||
# Обработка команд
|
||||
if message.text in ["/start", "/menu"]:
|
||||
await start_command(message)
|
||||
if message.text in ["/send_to_all"]:
|
||||
await send_message_to_all_clients(message, state) # Передаем состояние
|
||||
return
|
||||
|
||||
if message.text == "Мой профиль":
|
||||
await process_callback_view_profile(message)
|
||||
callback_query = types.CallbackQuery(
|
||||
id="1",
|
||||
from_user=message.from_user,
|
||||
chat_instance='',
|
||||
data='view_profile',
|
||||
message=message
|
||||
)
|
||||
await process_callback_view_profile(callback_query, state)
|
||||
return
|
||||
|
||||
# Проверка текущего состояния
|
||||
if current_state == Form.waiting_for_key_name.state:
|
||||
await handle_key_name_input(message, state)
|
||||
|
||||
else:
|
||||
elif current_state is None: # Если состояние не задано, обрабатываем обычные сообщения
|
||||
await start_command(message)
|
||||
|
||||
|
||||
async def handle_key_name_input(message: Message, state: FSMContext):
|
||||
tg_id = message.from_user.id
|
||||
key_name = sanitize_key_name(message.text)
|
||||
|
||||
@@ -96,35 +96,3 @@ async def notify_expiring_keys(bot: Bot):
|
||||
await conn.close()
|
||||
except Exception as e:
|
||||
print(f"Ошибка при отправке уведомлений: {e}")
|
||||
|
||||
|
||||
@router.message(Command('send_to_all'))
|
||||
async def send_message_to_all_clients(message: types.Message):
|
||||
if message.from_user.id != ADMIN_ID:
|
||||
await message.answer("У вас нет прав для выполнения этой команды.")
|
||||
return
|
||||
|
||||
text = message.text.split(maxsplit=1)
|
||||
if len(text) < 2:
|
||||
await message.answer("Пожалуйста, введите текст сообщения после команды.")
|
||||
return
|
||||
|
||||
text_message = text[1]
|
||||
|
||||
try:
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
tg_ids = await conn.fetch('SELECT tg_id FROM connections')
|
||||
|
||||
for record in tg_ids:
|
||||
tg_id = record['tg_id']
|
||||
try:
|
||||
await bot.send_message(chat_id=tg_id, text=text_message)
|
||||
except Exception as e:
|
||||
print(f"Ошибка при отправке сообщения пользователю {tg_id}: {e}. Пропускаем этого пользователя.")
|
||||
|
||||
await message.answer("Сообщение было отправлено всем клиентам.")
|
||||
except Exception as e:
|
||||
print(f"Ошибка при подключении к базе данных: {e}")
|
||||
await message.answer("Произошла ошибка при отправке сообщения.")
|
||||
finally:
|
||||
await conn.close()
|
||||
Reference in New Issue
Block a user