151 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import logging.config
 | 
						||
 | 
						||
from aiogram import F, Router
 | 
						||
from aiogram.fsm.context import FSMContext
 | 
						||
from aiogram.types import CallbackQuery, Message
 | 
						||
 | 
						||
import app.telegram.keyboards.inline as kbi
 | 
						||
import app.telegram.keyboards.reply as kbr
 | 
						||
import database.request as rq
 | 
						||
from app.bybit.profile_bybit import user_profile_bybit
 | 
						||
from app.telegram.states.states import AddBybitApiState
 | 
						||
from logger_helper.logger_helper import LOGGING_CONFIG
 | 
						||
 | 
						||
logging.config.dictConfig(LOGGING_CONFIG)
 | 
						||
logger = logging.getLogger("add_bybit_api")
 | 
						||
 | 
						||
router_add_bybit_api = Router(name="add_bybit_api")
 | 
						||
 | 
						||
 | 
						||
@router_add_bybit_api.callback_query(F.data == "connect_platform")
 | 
						||
async def connect_platform(callback: CallbackQuery, state: FSMContext) -> None:
 | 
						||
    """
 | 
						||
    Handles the callback query to initiate Bybit platform connection.
 | 
						||
    Sends instructions on how to create and provide API keys to the bot.
 | 
						||
 | 
						||
    :param callback: CallbackQuery object triggered by user interaction.
 | 
						||
    :param state: FSMContext object to manage state data.
 | 
						||
    :return: None
 | 
						||
    """
 | 
						||
    try:
 | 
						||
        await state.clear()
 | 
						||
        await callback.answer()
 | 
						||
        user = await rq.get_user(tg_id=callback.from_user.id)
 | 
						||
        if user:
 | 
						||
            await callback.message.answer(
 | 
						||
                text=(
 | 
						||
                    "Подключение Bybit аккаунта \n\n"
 | 
						||
                    "1. Зарегистрируйтесь или войдите в свой аккаунт на Bybit по ссылке: "
 | 
						||
                    "[Перейти на Bybit](https://www.bybit.com/invite?ref=YME83OJ).\n"
 | 
						||
                    "2. В личном кабинете выберите раздел API. \n"
 | 
						||
                    "3. Создание нового API ключа\n"
 | 
						||
                    "   - Нажмите кнопку Create New Key (Создать новый ключ).\n"
 | 
						||
                    "   - Выберите системно-сгенерированный ключ.\n"
 | 
						||
                    "   - Укажите название API ключа (любое).  \n"
 | 
						||
                    "   - Выберите права доступа для торговли (Trade).  \n"
 | 
						||
                    "   - Можно ограничить доступ по IP для безопасности.\n"
 | 
						||
                    "4. Подтверждение создания\n"
 | 
						||
                    "   - Подтвердите создание ключа.\n"
 | 
						||
                    "   - Отправьте чат-роботу.\n\n"
 | 
						||
                    "Важно: сохраните отдельно API Key и Secret Key в надежном месте. Secret ключ отображается только один раз."
 | 
						||
                ),
 | 
						||
                parse_mode="Markdown",
 | 
						||
                reply_markup=kbi.add_bybit_api,
 | 
						||
                disable_web_page_preview=True,
 | 
						||
            )
 | 
						||
        else:
 | 
						||
            await rq.create_user(
 | 
						||
                tg_id=callback.from_user.id, username=callback.from_user.username
 | 
						||
            )
 | 
						||
            await rq.set_user_symbol(tg_id=callback.from_user.id, symbol="BTCUSDT")
 | 
						||
            await rq.create_user_additional_settings(tg_id=callback.from_user.id)
 | 
						||
            await rq.create_user_risk_management(tg_id=callback.from_user.id)
 | 
						||
            await rq.create_user_conditional_settings(tg_id=callback.from_user.id)
 | 
						||
            await connect_platform(callback=callback, state=state)
 | 
						||
    except Exception as e:
 | 
						||
        logger.error("Error adding bybit API for user %s: %s", callback.from_user.id, e)
 | 
						||
        await callback.message.answer(
 | 
						||
            text="Произошла ошибка. Пожалуйста, попробуйте позже."
 | 
						||
        )
 | 
						||
 | 
						||
 | 
						||
@router_add_bybit_api.callback_query(F.data == "add_bybit_api")
 | 
						||
async def process_api_key(callback: CallbackQuery, state: FSMContext) -> None:
 | 
						||
    """
 | 
						||
    Starts the FSM flow to add Bybit API keys.
 | 
						||
    Sets the FSM state to prompt user to enter API Key.
 | 
						||
 | 
						||
    :param callback: CallbackQuery object.
 | 
						||
    :param state: FSMContext for managing user state.
 | 
						||
    """
 | 
						||
    try:
 | 
						||
        await state.clear()
 | 
						||
        await state.set_state(AddBybitApiState.api_key_state)
 | 
						||
        await callback.answer()
 | 
						||
        await callback.message.answer(text="Введите API Key:")
 | 
						||
    except Exception as e:
 | 
						||
        logger.error("Error adding bybit API for user %s: %s", callback.from_user.id, e)
 | 
						||
        await callback.message.answer(
 | 
						||
            text="Произошла ошибка. Пожалуйста, попробуйте позже."
 | 
						||
        )
 | 
						||
 | 
						||
 | 
						||
@router_add_bybit_api.message(AddBybitApiState.api_key_state)
 | 
						||
async def process_secret_key(message: Message, state: FSMContext) -> None:
 | 
						||
    """
 | 
						||
    Receives the API Key input from the user, stores it in FSM context,
 | 
						||
    then sets state to collect Secret Key.
 | 
						||
 | 
						||
    :param message: Message object with user's input.
 | 
						||
    :param state: FSMContext for managing user state.
 | 
						||
    """
 | 
						||
    try:
 | 
						||
        api_key = message.text
 | 
						||
        await state.update_data(api_key=api_key)
 | 
						||
        await state.set_state(AddBybitApiState.api_secret_state)
 | 
						||
        await message.answer(text="Введите Secret Key:")
 | 
						||
    except Exception as e:
 | 
						||
        logger.error("Error adding bybit API for user %s: %s", message.from_user.id, e)
 | 
						||
        await message.answer(text="Произошла ошибка. Пожалуйста, попробуйте позже.")
 | 
						||
 | 
						||
 | 
						||
@router_add_bybit_api.message(AddBybitApiState.api_secret_state)
 | 
						||
async def add_bybit_api(message: Message, state: FSMContext) -> None:
 | 
						||
    """
 | 
						||
    Receives the Secret Key input, stores it, saves both API keys in the database,
 | 
						||
    clears FSM state and confirms success to the user.
 | 
						||
 | 
						||
    :param message: Message object with user's input.
 | 
						||
    :param state: FSMContext for managing user state.
 | 
						||
    """
 | 
						||
    try:
 | 
						||
        api_secret = message.text
 | 
						||
        api_key = (await state.get_data()).get("api_key")
 | 
						||
        await state.update_data(api_secret=api_secret)
 | 
						||
 | 
						||
        if not api_key or not api_secret:
 | 
						||
            await message.answer("Введите корректные данные.")
 | 
						||
            return
 | 
						||
 | 
						||
        result = await rq.set_user_api(
 | 
						||
            tg_id=message.from_user.id, api_key=api_key, api_secret=api_secret
 | 
						||
        )
 | 
						||
 | 
						||
        if result:
 | 
						||
            await message.answer(text="Данные добавлены.", reply_markup=kbr.profile)
 | 
						||
            await user_profile_bybit(
 | 
						||
                tg_id=message.from_user.id, message=message, state=state
 | 
						||
            )
 | 
						||
            logger.debug(
 | 
						||
                "Bybit API added successfully for user: %s", message.from_user.id
 | 
						||
            )
 | 
						||
        else:
 | 
						||
            await message.answer(text="Произошла ошибка. Пожалуйста, попробуйте позже.")
 | 
						||
            logger.error(
 | 
						||
                "Error adding bybit API for user %s: %s", message.from_user.id, result
 | 
						||
            )
 | 
						||
        await state.clear()
 | 
						||
    except Exception as e:
 | 
						||
        logger.error("Error adding bybit API for user %s: %s", message.from_user.id, e)
 | 
						||
        await message.answer(text="Произошла ошибка. Пожалуйста, попробуйте позже.")
 |