правки

This commit is contained in:
Vlad
2024-09-23 16:35:46 +03:00
parent 9413065ea3
commit 60c7fa14c8
10 changed files with 111 additions and 111 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ import json
import requests
from config import GET_INBOUNDS_URL, API_URL
from config import API_URL, GET_INBOUNDS_URL
session = None
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+18 -11
View File
@@ -6,6 +6,7 @@ from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from database import get_balance, get_key_count
from bot import bot # Импортируем объект bot
router = Router()
@@ -15,6 +16,7 @@ class ReplenishBalanceState(StatesGroup):
async def process_callback_view_profile(callback_query: types.CallbackQuery, state: FSMContext):
tg_id = callback_query.from_user.id
username = callback_query.from_user.full_name # Получаем имя пользователя
try:
# Получаем количество ключей
@@ -26,38 +28,43 @@ async def process_callback_view_profile(callback_query: types.CallbackQuery, sta
balance = 0 # По умолчанию 0, если баланс неизвестен
profile_message = (
f"<b>Профиль пользователя</b>\n\n"
f"<b>Профиль: {username}</b>\n\n"
f"🔹 <b>ID:</b> {tg_id}\n"
f"🔹 <b>Количество ключей:</b> {key_count}\n"
f"🔹 <b>Баланс:</b> {balance} RUB\n"
f"🔹 <b>Дата регистрации:</b> {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')}\n"
f"🔹 <b>Количество ключей:</b> {key_count}\n"
)
# Кнопки для действий в профиле
button_create_key = InlineKeyboardButton(text='Создать ключ', callback_data='create_key')
button_view_keys = InlineKeyboardButton(text='Мои ключи', callback_data='view_keys')
button_replenish_balance = InlineKeyboardButton(text='Пополнить баланс', callback_data='replenish_balance')
# Кнопки для действий в профиле с добавленными смайликами
button_create_key = InlineKeyboardButton(text='🔑 Создать ключ', callback_data='create_key')
button_view_keys = InlineKeyboardButton(text='🔐 Мои ключи', callback_data='view_keys')
button_replenish_balance = InlineKeyboardButton(text='💳 Пополнить баланс', callback_data='replenish_balance')
button_back = InlineKeyboardButton(text='⬅️ Назад', callback_data='back_to_menu') # Добавляем кнопку "Назад"
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[button_create_key], # Добавляем кнопку "Создать ключ"
[button_create_key],
[button_view_keys],
[button_replenish_balance],
[button_back] # Добавляем кнопку "Назад" в клавиатуру
[button_back]
])
except Exception as e:
profile_message = f"❗️ Ошибка при получении данных профиля: {e}"
keyboard = None
# Редактируем существующее сообщение, а не отправляем новое
await callback_query.message.edit_text(
# Удаляем текущее сообщение
await callback_query.message.delete()
# Отправляем новое сообщение с профилем через bot
await bot.send_message(
chat_id=tg_id, # ID чата, куда отправляем сообщение
text=profile_message,
parse_mode='HTML',
reply_markup=keyboard
)
await callback_query.answer()
@router.callback_query(lambda c: c.data == 'view_profile')
async def view_profile_handler(callback_query: types.CallbackQuery, state: FSMContext):
await process_callback_view_profile(callback_query, state)
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

+55 -74
View File
@@ -3,8 +3,9 @@ from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import (CallbackQuery, InlineKeyboardButton,
InlineKeyboardMarkup, KeyboardButton, Message,
ReplyKeyboardMarkup)
InlineKeyboardMarkup, Message)
from aiogram.types import BufferedInputFile
import os
from bot import bot
from config import ADMIN_ID, CHANNEL_URL
@@ -14,37 +15,52 @@ router = Router()
class FeedbackState(StatesGroup):
waiting_for_feedback = State()
async def start_command(message: types.Message):
async def send_welcome_message(chat_id: int):
# Новый текст приветствия
welcome_text = (
"*Добро пожаловать в наш сервис!*\n\n"
"Вы можете воспользоваться следующими функциями:\n\n"
"🔑 *Создать ключ для подключения VPN* - Получите уникальный ключ для доступа к VPN.\n"
"📅 *Узнать дату окончания ключа* - Проверьте, когда истекает срок действия вашего ключа.\n"
"👤 *Просмотреть ваш профиль* - Получите информацию о вашем аккаунте и балансе.\n\n"
"Нажмите на соответствующую кнопку ниже, чтобы начать!"
"*SoloNet -- ваш провайдер в бесцензурный интернет!*\n\n"
"Получите высокую скорость и самый безопасный протокол VPN, "
"который работает даже в Китае."
)
button_view_profile = InlineKeyboardButton(text='👤 Мой профиль', callback_data='view_profile')
button_about_vpn = InlineKeyboardButton(text='🔒 О VPN', callback_data='about_vpn')
button_feedback = InlineKeyboardButton(text='📝 Обратная связь', callback_data='feedback')
button_channel = InlineKeyboardButton(text='📢 Наш канал', url=CHANNEL_URL)
# Путь к изображению
image_path = os.path.join(os.path.dirname(__file__), 'solo_pic.png')
# Проверка существования файла
if not os.path.isfile(image_path):
await bot.send_message(chat_id, "Файл изображения не найден.")
return
# Создаем клавиатуру
inline_keyboard = InlineKeyboardMarkup(inline_keyboard=[
[button_view_profile],
[button_about_vpn],
[button_feedback],
[button_channel]
[InlineKeyboardButton(text='👤 Мой профиль', callback_data='view_profile')],
[InlineKeyboardButton(text='🔒 О VPN', callback_data='about_vpn')],
[InlineKeyboardButton(text='📝 Обратная связь', callback_data='feedback')],
[InlineKeyboardButton(text='📢 Наш канал', url=CHANNEL_URL)]
])
await message.bot.send_message(
chat_id=message.chat.id,
text=welcome_text,
parse_mode='Markdown',
reply_markup=inline_keyboard
)
# Используем BufferedInputFile для отправки изображения
with open(image_path, 'rb') as image_from_buffer:
await bot.send_photo(
chat_id,
BufferedInputFile(
image_from_buffer.read(),
filename="solo_pic.png"
),
caption=welcome_text,
parse_mode='Markdown',
reply_markup=inline_keyboard
)
@router.message(Command('start'))
async def start_command(message: Message):
await send_welcome_message(message.chat.id)
@router.callback_query(lambda c: c.data == 'about_vpn')
async def handle_about_vpn(callback_query: CallbackQuery):
# Удаляем сообщение главного меню
await callback_query.message.delete()
info_message = (
"*О VPN*\n\n"
"Мы используем VLESS для обеспечения безопасного и надежного подключения к интернету. "
@@ -52,69 +68,39 @@ async def handle_about_vpn(callback_query: CallbackQuery):
"Этот ключ необходим для использования нашего VPN-сервиса."
)
# Кнопка "Назад"
button_back = InlineKeyboardButton(text='⬅️ Назад', callback_data='back_to_menu')
inline_keyboard_back = InlineKeyboardMarkup(inline_keyboard=[[button_back]])
# Обновлённая клавиатура с кнопкой "Назад"
inline_keyboard_back = InlineKeyboardMarkup(inline_keyboard=[
[button_back]
])
await callback_query.message.edit_text(
await callback_query.message.answer(
info_message,
parse_mode='Markdown',
reply_markup=inline_keyboard_back # Добавление клавиатуры с кнопкой "Назад"
reply_markup=inline_keyboard_back
)
await callback_query.answer()
@router.callback_query(lambda c: c.data == 'back_to_menu')
async def handle_back_to_menu(callback_query: CallbackQuery):
welcome_text = (
"*Добро пожаловать в наш сервис!*\n\n"
"Вы можете воспользоваться следующими функциями:\n\n"
"🔑 *Создать ключ для подключения VPN* - Получите уникальный ключ для доступа к VPN.\n"
"📅 *Узнать дату окончания ключа* - Проверьте, когда истекает срок действия вашего ключа.\n"
"👤 *Просмотреть ваш профиль* - Получите информацию о вашем аккаунте и балансе.\n\n"
"Нажмите на соответствующую кнопку ниже, чтобы начать!"
)
button_view_profile = InlineKeyboardButton(text='👤 Мой профиль', callback_data='view_profile')
button_about_vpn = InlineKeyboardButton(text='🔒 О VPN', callback_data='about_vpn')
button_feedback = InlineKeyboardButton(text='📝 Обратная связь', callback_data='feedback')
button_channel = InlineKeyboardButton(text='📢 Наш канал', url=CHANNEL_URL)
inline_keyboard = InlineKeyboardMarkup(inline_keyboard=[
[button_view_profile],
[button_about_vpn],
[button_feedback],
[button_channel]
])
# Редактирование сообщения на главное меню
await callback_query.message.edit_text(
welcome_text,
parse_mode='Markdown',
reply_markup=inline_keyboard
)
# Удаляем текущее сообщение
await callback_query.message.delete()
# Отправляем приветственное сообщение
await send_welcome_message(callback_query.from_user.id)
await callback_query.answer()
@router.callback_query(lambda c: c.data == 'feedback')
async def handle_feedback(callback_query: CallbackQuery, state: FSMContext):
# Удаляем сообщение главного меню
await callback_query.message.delete()
feedback_text = "Напишите нам, если у вас возникли трудности с подключением, есть отзыв или предложение. @pocomacho"
# Кнопка "Назад"
button_back = InlineKeyboardButton(text='⬅️ Назад', callback_data='back_to_menu')
inline_keyboard_back = InlineKeyboardMarkup(inline_keyboard=[[button_back]])
# Обновлённая клавиатура с кнопкой "Назад"
inline_keyboard_back = InlineKeyboardMarkup(inline_keyboard=[
[button_back]
])
# Редактирование сообщения с кнопкой "Назад"
await callback_query.message.edit_text(
await callback_query.message.answer(
feedback_text,
parse_mode='Markdown',
reply_markup=inline_keyboard_back # Клавиатура с кнопкой "Назад"
reply_markup=inline_keyboard_back
)
await state.set_state(FeedbackState.waiting_for_feedback)
@@ -130,17 +116,12 @@ async def receive_feedback(message: types.Message, state: FSMContext):
f"Обратная связь от пользователя {user_id}:\n\n"
f"{message.text}"
)
try:
await bot.send_message(ADMIN_ID, feedback_message)
await message.answer("Спасибо за ваше сообщение! Мы свяжемся с вами, если это будет необходимо.")
except Exception as e:
await message.answer("Произошла ошибка при отправке вашего сообщения.")
print(f"Ошибка при отправке обратной связи: {e}") # Логирование ошибок
await state.clear()
# Пример обработки команды старт
@router.message(Command('start'))
async def cmd_start(message: Message):
await start_command(message)
await state.clear()
+37 -25
View File
@@ -45,7 +45,7 @@ async def process_callback_create_key(callback_query: CallbackQuery, state: FSMC
if trial_status == 1:
await callback_query.message.edit_text(
"У вас уже был пробный ключ. Вы можете создать новый за 100 рублей. "
"У вас уже был пробный ключ. Новый стоит 100 рублей и сразу на месяц. \n\n"
"Хотите продолжить?",
reply_markup=InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text='Да, создать новый ключ', callback_data='confirm_create_new_key')],
@@ -68,11 +68,15 @@ async def confirm_create_new_key(callback_query: CallbackQuery, state: FSMContex
if balance < 100:
replenish_button = InlineKeyboardButton(text='Перейти в профиль', callback_data='view_profile')
keyboard = InlineKeyboardMarkup(inline_keyboard=[[replenish_button]])
await callback_query.message.edit_text("Недостаточно средств на балансе для создания нового ключа.", reply_markup=keyboard)
await callback_query.message.edit_text(
"❗️ Недостаточно средств на балансе для создания нового ключа. "
"Пожалуйста, пополните баланс.",
reply_markup=keyboard
)
await state.clear()
return
await callback_query.message.edit_text("Пожалуйста, выберите имя для вашего нового ключа:")
await callback_query.message.edit_text("🔑 Пожалуйста, выберите имя для вашего нового ключа:")
await state.set_state(Form.waiting_for_key_name)
await state.update_data(creating_new_key=True)
@@ -112,8 +116,8 @@ async def handle_key_name_input(message: Message, state: FSMContext):
key_name = sanitize_key_name(message.text)
if not key_name:
await message.bot.send_message(tg_id, "Назовите профиль на английском языке.")
return # Прерываем выполнение функции
await message.bot.send_message(tg_id, "📝 Пожалуйста, назовите профиль на английском языке.")
return
data = await state.get_data()
creating_new_key = data.get('creating_new_key', False)
@@ -122,28 +126,32 @@ async def handle_key_name_input(message: Message, state: FSMContext):
client_id = str(uuid.uuid4())
email = key_name.lower()
current_time = datetime.utcnow()
expiry_time = int((current_time + timedelta(days=1)).timestamp() * 1000)
expiry_time = None
if creating_new_key:
# Проверяем, занято ли имя ключа
conn = await asyncpg.connect(DATABASE_URL)
try:
existing_key = await conn.fetchrow('SELECT * FROM keys WHERE email = $1', email)
if existing_key:
await message.bot.send_message(tg_id, "Это имя уже занято. Пожалуйста, выберите другое имя.")
return # Прерываем выполнение функции
finally:
await conn.close()
# Получаем статус пробного ключа из базы данных
conn = await asyncpg.connect(DATABASE_URL)
try:
existing_connection = await conn.fetchrow('SELECT trial FROM connections WHERE tg_id = $1', tg_id)
finally:
await conn.close()
trial_status = existing_connection['trial'] if existing_connection else 0
if trial_status == 0:
# Создаем пробный ключ на 1 день
expiry_time = int((current_time + timedelta(days=1)).timestamp() * 1000)
else:
# Проверяем баланс перед созданием нового ключа
balance = await get_balance(tg_id)
if balance < 100:
replenish_button = InlineKeyboardButton(text='Перейти в профиль', callback_data='view_profile')
keyboard = InlineKeyboardMarkup(inline_keyboard=[[replenish_button]])
await message.bot.send_message(tg_id, "Недостаточно средств на балансе для создания нового ключа.", reply_markup=keyboard)
await message.bot.send_message(tg_id, "❗️ Недостаточно средств на балансе для создания нового ключа.", reply_markup=keyboard)
await state.clear()
return
await update_balance(tg_id, -100)
expiry_time = int((current_time + timedelta(days=30)).timestamp() * 1000)
try:
add_client(session, client_id, email, tg_id, limit_ip=1, total_gb=0, expiry_time=expiry_time, enable=True, flow="xtls-rprx-vision")
@@ -165,32 +173,36 @@ async def handle_key_name_input(message: Message, state: FSMContext):
await store_key(tg_id, client_id, email, expiry_time, connection_link)
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text='Инструкции по использованию', callback_data='instructions')],
[InlineKeyboardButton(text='Перейти в профиль', callback_data='view_profile')]
[InlineKeyboardButton(text='📖 Инструкции по использованию', callback_data='instructions')],
[InlineKeyboardButton(text='🔙 Перейти в профиль', callback_data='view_profile')]
])
key_message = f"Ключ создан:\n<pre>{connection_link}</pre>"
key_message = (
"✅ Ключ успешно создан:\n"
f"<pre>{connection_link}</pre>"
)
await message.bot.send_message(tg_id, key_message, parse_mode="HTML", reply_markup=keyboard)
except Exception as e:
await message.bot.send_message(tg_id, f"Ошибка при создании ключа: {e}")
await message.bot.send_message(tg_id, f"Ошибка при создании ключа: {e}")
await state.clear()
@dp.callback_query(F.data == 'instructions')
async def handle_instructions(callback_query: CallbackQuery):
instructions_message = (
"*Инструкции по использованию вашего ключа:*\n\n"
"*📋 Инструкции по использованию вашего ключа:*\n\n"
"1. Скачайте приложение для вашего устройства:\n"
" - Для Android: [V2Ray](https://play.google.com/store/apps/details?id=com.v2ray.ang&hl=ru&pli=1)\n"
" - Для iPhone: [Streisand](https://apps.apple.com/ru/app/streisand/id6450534064)\n\n"
"2. Скопируйте предоставленный ключ, который вы получили ранее.\n"
"3. Откройте приложение и нажмите на плюсик сверху справа.\n"
"4. Выберите 'Вставить из буфера обмена' для добавления ключа.\n\n"
"Если у вас возникнут вопросы, не стесняйтесь обращаться в поддержку."
"💬 Если у вас возникнут вопросы, не стесняйтесь обращаться в поддержку."
)
back_button = InlineKeyboardButton(text='Назад', callback_data='back_to_main')
back_button = InlineKeyboardButton(text='🔙 Назад', callback_data='back_to_main')
keyboard = InlineKeyboardMarkup(inline_keyboard=[[back_button]])
await callback_query.message.edit_text(instructions_message, parse_mode='Markdown', reply_markup=keyboard)