Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bebd051f47 | |||
| 56babedde6 | |||
| e9e4973dc9 | |||
| 8eb76ff9e4 | |||
| 69de84d430 | |||
| 52b41fe521 |
@@ -1,6 +1,7 @@
|
|||||||
# 🚀 SoloBot
|
# 🚀 SoloBot
|
||||||
|
|
||||||
**SoloBot** — ваш идеальный помощник для управления API 3x-UI VPN на протоколе VLESS.
|
**SoloBot** — ваш идеальный помощник для управления API 3x-UI VPN на протоколе VLESS.
|
||||||
|
*релиз 1.4 — полная доработка работы с ключами.
|
||||||
|
|
||||||
## 📋 Оглавление
|
## 📋 Оглавление
|
||||||
1. [Описание](#описание)
|
1. [Описание](#описание)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from aiogram.fsm.state import State, StatesGroup
|
|||||||
from aiogram.types import (CallbackQuery, InlineKeyboardButton,
|
from aiogram.types import (CallbackQuery, InlineKeyboardButton,
|
||||||
InlineKeyboardMarkup, Message)
|
InlineKeyboardMarkup, Message)
|
||||||
|
|
||||||
from auth import link, login_with_credentials
|
from auth import login_with_credentials, link_subscription
|
||||||
from client import add_client
|
from client import add_client
|
||||||
from config import (ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL,
|
from config import (ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL,
|
||||||
SERVERS)
|
SERVERS)
|
||||||
@@ -170,7 +170,7 @@ async def handle_key_name_input(message: Message, state: FSMContext):
|
|||||||
else:
|
else:
|
||||||
raise Exception(error_msg)
|
raise Exception(error_msg)
|
||||||
|
|
||||||
connection_link = await link(session, server_id, client_id, email)
|
connection_link = await link_subscription(email, server_id)
|
||||||
|
|
||||||
conn = await asyncpg.connect(DATABASE_URL)
|
conn = await asyncpg.connect(DATABASE_URL)
|
||||||
try:
|
try:
|
||||||
|
|||||||
+19
-7
@@ -4,10 +4,10 @@ from datetime import datetime, timedelta
|
|||||||
import asyncpg
|
import asyncpg
|
||||||
from aiogram import Router, types
|
from aiogram import Router, types
|
||||||
|
|
||||||
from auth import link, login_with_credentials
|
from auth import login_with_credentials, link_subscription
|
||||||
from bot import bot
|
from bot import bot
|
||||||
from client import add_client, delete_client, extend_client_key
|
from client import add_client, delete_client, extend_client_key
|
||||||
from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL, SERVERS
|
from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL, SERVERS, APP_URL
|
||||||
from database import get_balance, update_balance
|
from database import get_balance, update_balance
|
||||||
from handlers.texts import NO_KEYS
|
from handlers.texts import NO_KEYS
|
||||||
from handlers.texts import key_message, key_relocated
|
from handlers.texts import key_message, key_relocated
|
||||||
@@ -331,7 +331,7 @@ async def process_callback_select_server(callback_query: types.CallbackQuery):
|
|||||||
if not new_client_data:
|
if not new_client_data:
|
||||||
raise Exception("Ошибка при создании клиента на новом сервере.")
|
raise Exception("Ошибка при создании клиента на новом сервере.")
|
||||||
|
|
||||||
new_key = await link(session_new, server_id, client_id, email)
|
new_key = await link_subscription(email, server_id)
|
||||||
|
|
||||||
await conn.execute(
|
await conn.execute(
|
||||||
'UPDATE keys SET server_id = $1, key = $2 WHERE client_id = $3',
|
'UPDATE keys SET server_id = $1, key = $2 WHERE client_id = $3',
|
||||||
@@ -345,9 +345,7 @@ async def process_callback_select_server(callback_query: types.CallbackQuery):
|
|||||||
if not success_delete:
|
if not success_delete:
|
||||||
raise Exception(f"Ошибка при удалении клиента с сервера {current_server_id}")
|
raise Exception(f"Ошибка при удалении клиента с сервера {current_server_id}")
|
||||||
|
|
||||||
response_message = (
|
response_message = key_relocated(new_key)
|
||||||
key_relocated(new_key)
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
response_message = f"Ключ перемещен, но возникла ошибка при удалении клиента с текущего сервера: {e}"
|
response_message = f"Ключ перемещен, но возникла ошибка при удалении клиента с текущего сервера: {e}"
|
||||||
|
|
||||||
@@ -355,7 +353,21 @@ async def process_callback_select_server(callback_query: types.CallbackQuery):
|
|||||||
response_message = "Ключ не найден или уже удален."
|
response_message = "Ключ не найден или уже удален."
|
||||||
|
|
||||||
back_button = types.InlineKeyboardButton(text='Назад', callback_data='view_keys')
|
back_button = types.InlineKeyboardButton(text='Назад', callback_data='view_keys')
|
||||||
keyboard = types.InlineKeyboardMarkup(inline_keyboard=[[back_button]])
|
iphone_button = types.InlineKeyboardButton(
|
||||||
|
text='🍏IPhone',
|
||||||
|
url=f'{APP_URL}/?url=streisand://import/{new_key}'
|
||||||
|
)
|
||||||
|
android_button = types.InlineKeyboardButton(
|
||||||
|
text='🤖Android',
|
||||||
|
url=f'{APP_URL}/?url=v2rayng://install-sub?url={new_key}'
|
||||||
|
)
|
||||||
|
|
||||||
|
keyboard = types.InlineKeyboardMarkup(
|
||||||
|
inline_keyboard=[
|
||||||
|
[back_button],
|
||||||
|
[iphone_button, android_button]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
await bot.edit_message_text(
|
await bot.edit_message_text(
|
||||||
response_message, chat_id=tg_id, message_id=callback_query.message.message_id,
|
response_message, chat_id=tg_id, message_id=callback_query.message.message_id,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import asyncpg
|
import asyncpg
|
||||||
import uuid
|
import uuid
|
||||||
from config import DATABASE_URL, SERVERS, ADMIN_USERNAME, ADMIN_PASSWORD
|
from config import DATABASE_URL, SERVERS, ADMIN_USERNAME, ADMIN_PASSWORD
|
||||||
from auth import login_with_credentials, link
|
from auth import login_with_credentials, link_subscription
|
||||||
from client import add_client
|
from client import add_client
|
||||||
from database import store_key, add_connection
|
from database import store_key, add_connection
|
||||||
from handlers.texts import INSTRUCTIONS
|
from handlers.texts import INSTRUCTIONS
|
||||||
@@ -19,15 +19,17 @@ async def create_trial_key(tg_id: int):
|
|||||||
expiry_time = current_time + timedelta(days=1, hours=3)
|
expiry_time = current_time + timedelta(days=1, hours=3)
|
||||||
expiry_timestamp = int(expiry_time.timestamp() * 1000)
|
expiry_timestamp = int(expiry_time.timestamp() * 1000)
|
||||||
|
|
||||||
client_id = str(uuid.uuid4())
|
client_id = str(uuid.uuid4())
|
||||||
email = generate_random_email()
|
email = generate_random_email()
|
||||||
response = await add_client(
|
response = await add_client(
|
||||||
session, server_id, client_id, email, tg_id,
|
session, server_id, client_id, email, tg_id,
|
||||||
limit_ip=1, total_gb=0, expiry_time=expiry_timestamp,
|
limit_ip=1, total_gb=0, expiry_time=expiry_timestamp,
|
||||||
enable=True, flow="xtls-rprx-vision"
|
enable=True, flow="xtls-rprx-vision"
|
||||||
)
|
)
|
||||||
if response.get("success"):
|
|
||||||
connection_link = await link(session, server_id, client_id, email)
|
if response.get("success"):
|
||||||
|
# Генерация ссылки подписки
|
||||||
|
connection_link = await link_subscription(email, server_id)
|
||||||
|
|
||||||
existing_connection = await conn.fetchrow('SELECT * FROM connections WHERE tg_id = $1', tg_id)
|
existing_connection = await conn.fetchrow('SELECT * FROM connections WHERE tg_id = $1', tg_id)
|
||||||
|
|
||||||
|
|||||||
+18
-5
@@ -6,7 +6,7 @@ from aiogram.types import (BufferedInputFile, CallbackQuery,
|
|||||||
InlineKeyboardButton, InlineKeyboardMarkup, Message)
|
InlineKeyboardButton, InlineKeyboardMarkup, Message)
|
||||||
from handlers.texts import ABOUT_VPN, WELCOME_TEXT
|
from handlers.texts import ABOUT_VPN, WELCOME_TEXT
|
||||||
from bot import bot
|
from bot import bot
|
||||||
from config import CHANNEL_URL, SUPPORT_CHAT_URL
|
from config import CHANNEL_URL, SUPPORT_CHAT_URL, APP_URL
|
||||||
from database import add_connection, add_referral, check_connection_exists, get_trial
|
from database import add_connection, add_referral, check_connection_exists, get_trial
|
||||||
from handlers.keys.trial_key import create_trial_key
|
from handlers.keys.trial_key import create_trial_key
|
||||||
from handlers.texts import INSTRUCTIONS_TRIAL
|
from handlers.texts import INSTRUCTIONS_TRIAL
|
||||||
@@ -74,16 +74,29 @@ async def handle_connect_vpn(callback_query: CallbackQuery):
|
|||||||
f"<b>Ваш ключ доступа:</b>\n<pre>{trial_key_info['key']}</pre>\n\n"
|
f"<b>Ваш ключ доступа:</b>\n<pre>{trial_key_info['key']}</pre>\n\n"
|
||||||
f"<b>Инструкции:</b>\n{INSTRUCTIONS_TRIAL}"
|
f"<b>Инструкции:</b>\n{INSTRUCTIONS_TRIAL}"
|
||||||
)
|
)
|
||||||
|
|
||||||
button_profile = InlineKeyboardButton(text='👤 Мой профиль', callback_data='view_profile')
|
button_profile = InlineKeyboardButton(text='👤 Мой профиль', callback_data='view_profile')
|
||||||
inline_keyboard_profile = InlineKeyboardMarkup(inline_keyboard=[[button_profile]])
|
|
||||||
|
button_iphone = InlineKeyboardButton(
|
||||||
|
text='🍏IPhone',
|
||||||
|
url=f'{APP_URL}/?url=streisand://import/{trial_key_info["key"]}'
|
||||||
|
)
|
||||||
|
button_android = InlineKeyboardButton(
|
||||||
|
text='🤖Android',
|
||||||
|
url=f'{APP_URL}/?url=v2rayng://install-sub?url={trial_key_info["key"]}'
|
||||||
|
)
|
||||||
|
|
||||||
|
inline_keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||||
|
[button_iphone, button_android],
|
||||||
|
[button_profile]
|
||||||
|
])
|
||||||
|
|
||||||
await callback_query.message.answer(
|
await callback_query.message.answer(
|
||||||
key_message,
|
key_message,
|
||||||
parse_mode='HTML',
|
parse_mode='HTML',
|
||||||
reply_markup=inline_keyboard_profile
|
reply_markup=inline_keyboard
|
||||||
)
|
)
|
||||||
|
|
||||||
await callback_query.answer()
|
await callback_query.answer()
|
||||||
|
|
||||||
@router.callback_query(lambda c: c.data == 'about_vpn')
|
@router.callback_query(lambda c: c.data == 'about_vpn')
|
||||||
|
|||||||
Reference in New Issue
Block a user