2
0
forked from kodorvan/stcs
Files
stcs/app/telegram/handlers/add_bybit_api.py

151 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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="Произошла ошибка. Пожалуйста, попробуйте позже.")