def add_crypto(update, context): """Запрашиваем пару для установки уведомления.""" update.message.reply_text( 'Чтобы установить Alert пришлите пару в формате BTC USDT', reply_markup=cancel_keyboard()) # Сразу записываем в контекст id пользователя context.user_data['ticker'] = [update.effective_user.id] return "add_crypto_step_1"
def set_order(update, context): """ Функция с которой начинается диалог для выставления ордера на бирже. """ update.message.reply_text( 'Пришлите пару для ордера в формате BTC USDT', reply_markup=cancel_keyboard() ) return "set_step_1"
def comm_handler(message): select = "" if (message.text == "Первая игра"): bot.send_message(message.chat.id, description.game_one, reply_markup=keyboards.game_one_keyboard()) elif (message.text == "Вторая игра"): bot.send_message(message.chat.id, description.game_two, reply_markup=keyboards.game_two_bet_keyboard()) elif (message.text == "Третья игра"): bot.send_message(message.chat.id, description.game_three, reply_markup=keyboards.game_three_keyboard()) elif (message.text == "\U0001F4C3" + " " + 'Правила'): bot.send_message(message.chat.id, rules.rule.first_page, reply_markup=keyboards.rules_keyboard_first()) elif (message.text == "\U00002753" + " " + 'Инфо'): bot.send_message(message.chat.id, "Информация", reply_markup=keyboards.info_keyboard()) # pay.send_money(5, 79535780551) # print(db.get_values_game3_db(message.chat.id)) elif (message.text == "\U0001F4C4" + " " + 'Дополнительная информация'): bot.send_message(message.chat.id, info.inform) elif (message.text == "\U0001F464" + " " + 'Партнерская программа'): bot.send_message(message.chat.id, "Скоро!") elif (message.text == "\U0001F4B0" + " " + 'Кошелек'): select == message.text bot.send_message(message.chat.id, "Выберите: ", reply_markup=keyboards.purse_keyboard()) elif (message.text == "\U0001F4B2" + " " + 'Проверить баланс'): bot.send_message( message.chat.id, "\U0001F4B2" + " " + "Ваш баланс: " + str(db.get_balance(message.chat.id))) elif (message.text == "\U0001F4B5" + " " + 'Пополнить баланс'): trans_id = db.new_trans_id(message) bot.send_message(message.chat.id, "Ваш комментарий к переводу: " + str(trans_id), reply_markup=keyboards.payment_keyboard()) elif (message.text == "\U0001F4B8" + " " + 'Вывести монеты'): bot.send_message(message.chat.id, "Введите количество монет для вывода: ", reply_markup=keyboards.cancel_keyboard()) db.update_status_db(message, 1) elif (message.text == "\U000021A9" + " " + 'Назад'): bot.send_message(message.chat.id, "\U0001F4D1" + " " + "Главное меню", reply_markup=keyboards.start_keyboard()) else: bot.send_message(message.chat.id, "Пожалуйста, используйте клавиатуру")
def add_start(update, context): """ Функции для добавления инструмента пользователем, в контекст по ходу функций записывают данные об инструменте, который в конце записывается в БД """ update.message.reply_text( 'Введите название тикера', reply_markup=cancel_keyboard() ) # Сразу записываем в контекст id пользователя context.user_data['ticker'] = [update.effective_user.id] return add_step_1
def choosing_pair(update, context): """ Проверям валидность введёной пары тикеров для ордера """ # Формируем пару тикеров из пользовательского ввода. ticker_pair = update.message.text.upper().split(' ') # Провереяем что пользователь ввёл 2 тикера. if len(ticker_pair) != 2: update.message.reply_text( 'К сожалению, введена неверная пара, попробуйте ещё раз' ' или нажмите "Отмена" для завершения операции.', reply_markup=cancel_keyboard() ) return "set_step_1" # Сохраняем введёную пару тикеров. context.user_data['order_info'] = {} context.user_data['order_info']['ticker_pair'] = ticker_pair # Узнаём текущий курс. current_price = binance_client.get_average_price( ticker_pair[0], ticker_pair[1] ) if current_price is not None: update.message.reply_text( f'Текущая цена заданной пары {current_price}\n' 'Пожалуйста, выберите тип ордера или нажмите "Отмена".', reply_markup=order_type_keyboard() ) return "set_step_2" # Возвращаем на шаг назад если пара тикеров невалидна. update.message.reply_text( 'К сожалению, введена неверная пара, попробуйте ещё раз.', reply_markup=cancel_keyboard() ) return "set_step_1"
def choosing_pair_for_target(update, context): # add_crypto_step_1 """ Проверям валидность введёной пары тикеров для ордера """ # Формируем пару тикеров из прошлого пользовательского ввода. ticker_pair = update.message.text.upper().split(' ') # Провереяем что пользователь ввёл 2 тикера. if len(ticker_pair) != 2: update.message.reply_text( 'К сожалению, введена неверная пара, попробуйте ещё раз' ' или нажмите "Отмена" для завершения операции.', reply_markup=cancel_keyboard()) return "add_crypto_step_1" # Делаем запрос к API и узнаём текущий курс. current_price = binance_client.get_average_price(ticker_pair[0], ticker_pair[1]) if current_price is not None: update.message.reply_text( f'Текущая цена заданной пары {current_price}\n' 'Пожалуйста, введите цену на которой вы хотите получить уведомление.', reply_markup=cancel_keyboard()) current_date = f"{datetime.datetime.now():%Y-%m-%d}" # Сохраняем введёную пару тикеров, текущую цену и дату добавления. context.user_data['ticker'].extend( [ticker_pair, True, current_date, current_price.split(' ')[0]]) return "add_crypto_step_2" # Возвращаем на шаг назад если пара тикеров невалидна. update.message.reply_text( 'К сожалению, введена неверная пара, попробуйте ещё раз.', reply_markup=cancel_keyboard()) return "add_crypto_step_1"
def choosing_order_side(update, context): """ Проверяем выбранную сторону сделки. Доступны 'Купить', 'Продать'. """ # Забираем ранее сохранённые балансы пар. ticker_1_balance = context.user_data['order_info']['ticker_1_balance'] ticker_2_balance = context.user_data['order_info']['ticker_2_balance'] if update.message.text not in ORDERS_SIDE: update.message.reply_text( 'Пожалуйста, выберите сторону сделки или нажмите "Отмена".', reply_markup=buy_sell_keyboard(ticker_1_balance, ticker_2_balance) ) return 'set_step_3' context.user_data['order_info'].pop('ticker_1_balance') context.user_data['order_info'].pop('ticker_2_balance') # Cохраняем сторону сделки. context.user_data['order_info']['order_side'] = update.message.text # Возвращаем в начало шага если баланс выбранного тикера равен 0. allowed_balance = '' if context.user_data['order_info']['order_side'] == 'sell': if float(ticker_2_balance.split()[0]) == 0: update.message.reply_text( 'Недостаточно средств.', keyboard_markup=main_menu_keyboard() ) return 'set_step_3' allowed_balance += ticker_2_balance else: if float(ticker_1_balance.split()[0]) == 0: update.message.reply_text( 'Недостаточно средств.', keyboard_markup=main_menu_keyboard() ) return 'set_step_3' allowed_balance += ticker_1_balance if context.user_data['order_info']['order_type'] == 'limit': update.message.reply_text( 'Введите цену.', reply_markup=cancel_keyboard() ) return 'set_step_4' update.message.reply_text( f'Выберите количество.\n Доступно - {allowed_balance}', reply_markup=quantity_keyboard() ) return 'set_step_5'
def checking_price(update, context): try: price = abs(float(update.message.text)) except (ValueError, TypeError): update.message.reply_text( 'Пожалуйста, введите корректную цену.', reply_markup=cancel_keyboard() ) return 'set_step_4' else: # Сохраняем цену. context.user_data['order_info']['price'] = price update.message.reply_text( 'Выберите количество.', reply_markup=quantity_keyboard() ) return 'set_step_5'
def add_step_1(update, context): """ Пытаемся получить цену введенного тикера. Если получаем True - всё ок. False - значит такого тикера не существует, зацикливаем повторный запрос тикера. """ ticker = update.message.text.split()[0] ticker_current_price = get_ticker_price(ticker) if ticker_current_price is False: update.message.reply_text( 'Введенный тикер не найден. Повторите ввод ' 'или нажмите кнопку "Отмена" чтобы прервать ' 'выполнение операции', reply_markup=cancel_keyboard() ) return add_step_1 current_date = f"{datetime.datetime.now():%Y-%m-%d}" """ Записываем в контекст следующие переменные: - Название тикера - Характеристика, является ли тикер криптой или нет (!Всегда False, не реализовано) - Текущая дата - Текущая стоимость Далее запрашиваем у пользователя, хочет ли он указать иную начальную стоимость или использовать текущую """ context.user_data['ticker'].extend([ ticker, False, current_date, ticker_current_price ]) update.message.reply_text( f'Текущая стоимость {ticker} - {ticker_current_price}. ' 'Если вы хотите отслеживать иную начальную стоимость - ' 'отправьте её ответным сообщением. Для продолжения нажмите' ' на кнопку "Пропустить"', reply_markup=skip_keyboard() ) return add_step_2
def checking_price_for_target(update, context): # add_crypto_step_2 """Проверяем валидность введёной цены""" try: 1 / float(update.message.text) and float(update.message.text) except (ValueError, TypeError, ZeroDivisionError) as err: update.message.reply_text( f'Введите цену отличную от нуля.\nВы ввели {update.message.text}', reply_markup=cancel_keyboard()) logging.info(err) return "add_crypto_step_2" else: # Сохраняем цену для тарегта. target_price = update.message.text context.user_data['ticker'].append(target_price) context.user_data['ticker'].append(0) # Забираем ранее сохранённую пару. ticker_pair = context.user_data['ticker'][1] # Формируем сообщение. message = f'Установить отслеживание для пары {ticker_pair[0]}/{ticker_pair[1]}' message += f' на цену {target_price} {ticker_pair[1]}?' update.message.reply_text(message, reply_markup=yes_no_keyboard()) return "add_crypto_step_3"
def steps_handler(message): try: task = TelegramTask.objects.get(client__telegram_user__user_id=message.from_user.id) except ObjectDoesNotExist: start_handler(message) return if TaskStep(task.current_step) == TaskStep.WAIT_FOR_BRAND: # get position if message.text in r.BRANDS: task.brand = message.text # task.priority = PRIORITY_STATUSES[[x[1] for x in r.USER_POSITIONS if x[0] == message.text][0]] task.current_step = TaskStep.WAIT_FOR_SHOP_FULLNAME.value task.save() add_created_task() bot.send_message(message.chat.id, r.ENTER_SHOP_FULLNAME, reply_markup=kb.cancel_keyboard()) else: bot.send_message(message.chat.id, r.CHOICE_BRAND, reply_markup=kb.brands_keyboard()) elif TaskStep(task.current_step) == TaskStep.WAIT_FOR_SHOP_FULLNAME: task.shop_fullname = message.text task.current_step = TaskStep.WAIT_FOR_MOBILE_NUMBER.value task.save() bot.send_message(message.chat.id, r.MOBILE_NUMBER_SELECT, reply_markup=kb.cancel_keyboard()) elif TaskStep(task.current_step) == TaskStep.WAIT_FOR_MOBILE_NUMBER: if len(message.text) < 4: bot.send_message(message.chat.id, r.MOBILE_NUMBER_SELECT_ERROR, reply_markup=kb.remove_keyboard()) else: task.mobile_number = message.text task.current_step = TaskStep.WAIT_FOR_SERVICE.value task.save() bot.send_message(message.chat.id, r.TASK_DESCRIPTION_SELECT, reply_markup=kb.mass_problems()) elif TaskStep(task.current_step) == TaskStep.WAIT_FOR_SERVICE: description = message.text try: if description in MASS_PROBLEMS: task.description = description if task.description == 'Неисправность ФР': task.current_step = TaskStep.WAIT_FOR_KKM_NUMBER.value task.save() bot.send_message(message.chat.id, r.ENTER_KKM_NUMBER, reply_markup=kb.cancel_keyboard()) else: task.current_step = TaskStep.WAIT_FOR_DESCRIPTION.value task.save() bot.send_message(message.chat.id, r.ENTER_ENTER_TRUE_DESCRIPTION, reply_markup=kb.cancel_keyboard()) else: bot.send_message(message.chat.id, r.TASK_DESCRIPTION_SELECT_ERROR, reply_markup=kb.mass_problems()) except Exception as e: logging.warning(e) bot.send_message(message.chat.id, r.TASK_DESCRIPTION_SELECT_ERROR, reply_markup=kb.remove_keyboard()) elif TaskStep(task.current_step) == TaskStep.WAIT_FOR_KKM_NUMBER: task.kkm_number = message.text task.current_step = TaskStep.WAIT_FOR_DESCRIPTION.value task.save() bot.send_message(message.chat.id, r.ENTER_ENTER_TRUE_DESCRIPTION, reply_markup=kb.cancel_keyboard()) elif TaskStep(task.current_step) == TaskStep.WAIT_FOR_DESCRIPTION: task.true_description = message.text task.current_step = TaskStep.WAIT_FOR_TEAM_VIEWER.value task.save() bot.send_message(message.chat.id, r.ENTER_TEAM_VIEWER, reply_markup=kb.skip_and_cancel_keyboard()) elif TaskStep(task.current_step) == TaskStep.WAIT_FOR_TEAM_VIEWER: if message.text != r.SKIP_BUTTON: task.team_viewer = message.text task.current_step = TaskStep.WAIT_FOR_BLOCK.value task.save() bot.send_message(message.chat.id, r.ENTER_IS_BLOCK, reply_markup=kb.block_keyboard()) elif TaskStep(task.current_step) == TaskStep.WAIT_FOR_BLOCK: if message.text in [r.ENTER_IS_BLOCK_YES, r.ENTER_IS_BLOCK_NO]: task.block_work = message.text == r.ENTER_IS_BLOCK_YES if task.block_work: task.priority = PRIORITY_STATUSES["Критический"] else: if task.description in MASS_PROBLEMS: task.priority = PRIORITY_STATUSES[MASS_PROBLEMS_PRIORITY[task.description]] else: task.priority = PRIORITY_STATUSES["Низкий"] task.current_step = TaskStep.WAIT_FOR_SCREENSHOT.value task.save() bot.send_message(message.chat.id, r.SCREENSHOT_ATTACH_ASK, reply_markup=kb.screenshot_ask_keyboard()) else: bot.send_message(message.chat.id, r.ENTER_IS_BLOCK, reply_markup=kb.block_keyboard()) elif TaskStep(task.current_step) == TaskStep.WAIT_FOR_SCREENSHOT: if message.text == r.SCREENSHOT_ATTACH_YES: bot.send_message(message.chat.id, r.SCREENSHOT_ATTACH_CALL, reply_markup=kb.screenshot_wait_keyboard()) elif message.text == r.SCREENSHOT_ATTACH_CANCEL or message.text == r.SCREENSHOT_ATTACH_NO: task.current_step = TaskStep.FILLED.value task.save() bot.send_message(message.chat.id, r.TASK_FILLED, reply_markup=kb.remove_keyboard()) threading.Thread(target=create_task_threaded, kwargs=({'task': task, 'message': message})).start() start_handler(message) elif message.content_type == "photo": task.current_step = TaskStep.FILLED.value screenshot = get_screenshot(message.photo[-1].file_id) filename = f"{message.from_user.id}_{timezone.now().strftime('%Y-%m-%dT%H:%M:%S')}.jpg" task.screenshot.save(filename, ContentFile(screenshot)) task.save() bot.send_message(message.chat.id, r.TASK_FILLED, reply_markup=kb.remove_keyboard()) threading.Thread(target=create_task_threaded, kwargs=({'task': task, 'message': message})).start() start_handler(message)
def making_order(update, context): if update.message.text not in ORDERS_SIDE: update.message.reply_text( 'Подвтердите сделку или нажмите "Отмена"', reply_markup=aply_order_keyboard( context.user_data['order_info']['order_side'] ) ) return 'set_step_6' (ticker_pair, order_type, price, balance, order_side, quantity) = context.user_data['order_info'].values() # Минимально допустимая сумма сделки в $ min_order_summ_in_usdt = 10 def __preaparing_order_summ(price=price): """ Если ордер создаётся для пары без $ Например BNB/BTC - расчитываем price в $ """ if ticker_pair[1] != 'USDT' and order_type == 'limit': summ_in_usdt = binance_client.get_average_price( ticker_pair[0], 'USDT' ) price *= float(summ_in_usdt.split()[0]) elif ticker_pair[1] != 'USDT' and order_type == 'market': result_usdt = binance_client.get_average_price( ticker_pair[0], 'USDT' ) price = float(result_usdt.split()[0]) elif order_type == 'market': result_usdt = binance_client.get_average_price( ticker_pair[0], 'USDT' ) price = float(result_usdt.split()[0]) current_order_summ = price*quantity return current_order_summ # Сумма ордера. current_order_summ = __preaparing_order_summ() # Проверяем сумму ордера и если она меньше 10$ отправляем обратно. if current_order_summ < min_order_summ_in_usdt: message = f'Ордер должен быть не меньше {min_order_summ_in_usdt}$' message += f'\nВаш - {current_order_summ}$' update.message.reply_text( message, reply_markup=cancel_keyboard() ) return 'set_step_4' if order_type == 'market' and order_side == 'sell': result = binance_client.set_order_market_sell(ticker_pair[0], ticker_pair[1], quantity) elif order_type == 'market' and order_side == 'buy': result = binance_client.set_order_market_buy(ticker_pair[0], ticker_pair[1], quantity) elif order_type == 'limit' and order_side == 'sell': result = binance_client.set_order_limit_sell(ticker_pair[0], ticker_pair[1], quantity, price) elif order_type == 'limit' and order_side == 'buy': result = binance_client.set_order_limit_buy(ticker_pair[0], ticker_pair[1], quantity, price) if result is not None: update.message.reply_text( 'Ордер выставлен!', reply_markup=main_menu_keyboard() ) clear_all_crypto(update, context) return ConversationHandler.END update.message.reply_text( 'Возникла ошибка.', reply_markup=cancel_keyboard() ) clear_all_crypto(update, context) return ConversationHandler.END