логика, отправка уведомлений всем

This commit is contained in:
Vladless
2024-10-09 02:09:22 +03:00
parent 8588b89421
commit c5e9cb9b18
3 changed files with 61 additions and 130 deletions
-87
View File
@@ -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
View File
@@ -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)
-32
View File
@@ -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()