создание ключа в 1 кнопку
This commit is contained in:
+44
-10
@@ -1,22 +1,22 @@
|
||||
import os
|
||||
|
||||
from aiogram import Router
|
||||
from aiogram.filters import Command
|
||||
from aiogram.fsm.state import State, StatesGroup
|
||||
from aiogram.types import (BufferedInputFile, CallbackQuery,
|
||||
InlineKeyboardButton, InlineKeyboardMarkup, Message)
|
||||
from handlers.texts import ABOUT_VPN, WELCOME_TEXT
|
||||
|
||||
from bot import bot
|
||||
from config import CHANNEL_URL, SUPPORT_CHAT_URL
|
||||
from database import add_connection, add_referral, check_connection_exists
|
||||
from database import add_connection, add_referral, check_connection_exists, get_trial
|
||||
from handlers.trial_key import create_trial_key
|
||||
from handlers.texts import INSTRUCTIONS_TRIAL
|
||||
|
||||
router = Router()
|
||||
|
||||
class FeedbackState(StatesGroup):
|
||||
waiting_for_feedback = State()
|
||||
|
||||
async def send_welcome_message(chat_id: int):
|
||||
async def send_welcome_message(chat_id: int, trial_status: int):
|
||||
welcome_text = WELCOME_TEXT
|
||||
|
||||
image_path = os.path.join(os.path.dirname(__file__), 'pic.jpg')
|
||||
@@ -26,12 +26,15 @@ async def send_welcome_message(chat_id: int):
|
||||
return
|
||||
|
||||
inline_keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text='🔗 Подключить VPN', callback_data='connect_vpn')] if trial_status == 0 else [],
|
||||
[InlineKeyboardButton(text='👤 Мой профиль', callback_data='view_profile')],
|
||||
[InlineKeyboardButton(text='🔒 О VPN', callback_data='about_vpn')],
|
||||
[InlineKeyboardButton(text='📞 Поддержка', url=SUPPORT_CHAT_URL)],
|
||||
[InlineKeyboardButton(text='📢 Наш канал', url=CHANNEL_URL)]
|
||||
[InlineKeyboardButton(text='📞 Поддержка', url=SUPPORT_CHAT_URL)],
|
||||
[InlineKeyboardButton(text='📢 Наш канал', url=CHANNEL_URL)],
|
||||
])
|
||||
|
||||
inline_keyboard.inline_keyboard = [row for row in inline_keyboard.inline_keyboard if row]
|
||||
|
||||
with open(image_path, 'rb') as image_from_buffer:
|
||||
await bot.send_photo(
|
||||
chat_id,
|
||||
@@ -49,13 +52,43 @@ async def start_command(message: Message):
|
||||
print(f"Referral ID: {referrer_tg_id}")
|
||||
if not await check_connection_exists(message.from_user.id):
|
||||
await add_connection(message.from_user.id)
|
||||
|
||||
await add_referral(message.from_user.id, referrer_tg_id)
|
||||
|
||||
await message.answer("Вас пригласил друг, добро пожаловать!")
|
||||
else:
|
||||
await message.answer("Вы уже зарегистрированы в системе!")
|
||||
await send_welcome_message(message.chat.id)
|
||||
|
||||
trial_status = await get_trial(message.from_user.id)
|
||||
await send_welcome_message(message.chat.id, trial_status)
|
||||
|
||||
@router.callback_query(lambda c: c.data == 'connect_vpn')
|
||||
async def handle_connect_vpn(callback_query: CallbackQuery):
|
||||
await callback_query.message.delete()
|
||||
user_id = callback_query.from_user.id
|
||||
|
||||
# Создаём триальный ключ
|
||||
trial_key_info = await create_trial_key(user_id)
|
||||
|
||||
if 'error' in trial_key_info:
|
||||
await callback_query.message.answer(trial_key_info['error'])
|
||||
else:
|
||||
# Формируем сообщение с ключом и инструкциями
|
||||
key_message = (
|
||||
f"<b>Ваш ключ доступа:</b>\n<pre>{trial_key_info['key']}</pre>\n\n"
|
||||
f"<b>Инструкции:</b>\n{INSTRUCTIONS_TRIAL}"
|
||||
)
|
||||
|
||||
# Кнопка "В профиль"
|
||||
button_profile = InlineKeyboardButton(text='👤 Мой профиль', callback_data='view_profile')
|
||||
inline_keyboard_profile = InlineKeyboardMarkup(inline_keyboard=[[button_profile]])
|
||||
|
||||
# Отправляем текст с ключом и инструкциями в виде цитаты
|
||||
await callback_query.message.answer(
|
||||
key_message,
|
||||
parse_mode='HTML',
|
||||
reply_markup=inline_keyboard_profile
|
||||
)
|
||||
|
||||
await callback_query.answer()
|
||||
|
||||
@router.callback_query(lambda c: c.data == 'about_vpn')
|
||||
async def handle_about_vpn(callback_query: CallbackQuery):
|
||||
@@ -75,5 +108,6 @@ async def handle_about_vpn(callback_query: CallbackQuery):
|
||||
@router.callback_query(lambda c: c.data == 'back_to_menu')
|
||||
async def handle_back_to_menu(callback_query: CallbackQuery):
|
||||
await callback_query.message.delete()
|
||||
await send_welcome_message(callback_query.from_user.id)
|
||||
trial_status = await get_trial(callback_query.from_user.id)
|
||||
await send_welcome_message(callback_query.from_user.id, trial_status)
|
||||
await callback_query.answer()
|
||||
|
||||
+19
-6
@@ -68,15 +68,28 @@ INSTRUCTIONS = (
|
||||
"💬 Если у вас возникнут вопросы, не стесняйтесь обращаться в [поддержку](https://t.me/solonet_sup)."
|
||||
)
|
||||
|
||||
KEY_EXPIRY_10H = "🔔 Уведомление: Ваш ключ для сервера {server_id} истекает через 10 часов.\n" \
|
||||
"Email: {email}\n" \
|
||||
"Дата истечения: {expiry_date}"
|
||||
INSTRUCTIONS_TRIAL = (
|
||||
"<b>📋 Инструкции по использованию вашего ключа:</b>\n\n"
|
||||
"1. <b>Скачайте приложение для вашего устройства:</b>\n"
|
||||
" - <b>Для Android:</b> <a href='https://play.google.com/store/apps/details?id=com.v2ray.ang&hl=ru&pli=1'>V2Ray</a>\n"
|
||||
" - <b>Для iPhone:</b> <a href='https://apps.apple.com/ru/app/streisand/id6450534064'>Streisand</a>\n"
|
||||
" - <b>Для Windows:</b> <a href='https://github.com/hiddify/hiddify-next/releases/latest/download/Hiddify-Windows-Setup-x64.Msix'>Hiddify Next</a>\n\n"
|
||||
"2. <b>Скопируйте предоставленный ключ</b>, который вы получили ранее.\n"
|
||||
"3. <b>Откройте приложение и нажмите на плюсик сверху справа.</b>\n"
|
||||
"4. <b>Выберите 'Вставить из буфера обмена' для добавления ключа.</b>\n\n"
|
||||
"💬 Если у вас возникнут вопросы, не стесняйтесь обращаться в <a href='https://t.me/solonet_sup'>поддержку</a>."
|
||||
)
|
||||
|
||||
KEY_EXPIRY_24H = "⏳ Уведомление: Ваш ключ для сервера {server_id} истекает через 24 часа.\n" \
|
||||
"Email: {email}\n" \
|
||||
|
||||
KEY_EXPIRY_10H = "🔔 Уведомление: Ваш ключ {email} для сервера {server_id} истекает через 10 часов.\n" \
|
||||
"Дата истечения: {expiry_date}"\
|
||||
"Перейдите в профиль и пополните баланс, всего 100 рублей на целый месяц"\
|
||||
"ключ продлится автоматически"
|
||||
|
||||
KEY_EXPIRY_24H = "🔔 Уведомление: Ваш ключ {email} для сервера {server_id} истекает через 24 часа.\n" \
|
||||
"Осталось времени: {hours_left} часов\n" \
|
||||
"Дата истечения: {expiry_date}\n" \
|
||||
"Баланс: {balance:.2f} руб."
|
||||
"Баланс: {balance:.2f} руб."\
|
||||
|
||||
KEY_RENEWED = "Ваш ключ был продлен на месяц."
|
||||
KEY_RENEWAL_FAILED = "Не удалось продлить ключ на панели, обратитесь в поддержку."
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import random
|
||||
import asyncpg
|
||||
import time
|
||||
import uuid # Импортируем модуль для генерации UUID
|
||||
from config import DATABASE_URL, SERVERS, ADMIN_USERNAME, ADMIN_PASSWORD
|
||||
from auth import login_with_credentials, link # Импортируйте необходимые функции
|
||||
from client import add_client
|
||||
from database import store_key, add_connection
|
||||
from handlers.texts import INSTRUCTIONS
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
def generate_random_email():
|
||||
"""Генерирует случайный набор символов."""
|
||||
random_string = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=6))
|
||||
return random_string
|
||||
|
||||
async def create_trial_key(tg_id: int):
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
try:
|
||||
server_id = await get_least_loaded_server(conn)
|
||||
session = await login_with_credentials(server_id, ADMIN_USERNAME, ADMIN_PASSWORD)
|
||||
current_time = datetime.utcnow()
|
||||
|
||||
expiry_time = current_time + timedelta(days=30, hours=3)
|
||||
expiry_timestamp = int(expiry_time.timestamp() * 1000)
|
||||
|
||||
client_id = str(uuid.uuid4())
|
||||
email = generate_random_email()
|
||||
response = await add_client(
|
||||
session, server_id, client_id, email, tg_id,
|
||||
limit_ip=1, total_gb=0, expiry_time=expiry_timestamp,
|
||||
enable=True, flow="xtls-rprx-vision"
|
||||
)
|
||||
if response.get("success"):
|
||||
connection_link = await link(session, server_id, client_id, email)
|
||||
|
||||
existing_connection = await conn.fetchrow('SELECT * FROM connections WHERE tg_id = $1', tg_id)
|
||||
|
||||
if existing_connection:
|
||||
await conn.execute('UPDATE connections SET trial = 1 WHERE tg_id = $1', tg_id)
|
||||
else:
|
||||
await add_connection(tg_id, 0, 1)
|
||||
|
||||
await store_key(tg_id, client_id, email, expiry_timestamp, connection_link, server_id)
|
||||
|
||||
instructions = INSTRUCTIONS
|
||||
return {
|
||||
'key': connection_link,
|
||||
'instructions': instructions
|
||||
}
|
||||
else:
|
||||
return {'error': 'Не удалось добавить клиента на панель'}
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
async def get_least_loaded_server(conn):
|
||||
least_loaded_server_id = None
|
||||
min_load_percentage = float('inf')
|
||||
|
||||
for server_id, server in SERVERS.items():
|
||||
count = await conn.fetchval('SELECT COUNT(*) FROM keys WHERE server_id = $1', server_id)
|
||||
percent_full = (count / 60) * 100 if count <= 60 else 100
|
||||
if percent_full < min_load_percentage:
|
||||
min_load_percentage = percent_full
|
||||
least_loaded_server_id = server_id
|
||||
|
||||
return least_loaded_server_id
|
||||
Reference in New Issue
Block a user