Example #1
0
def end_poll_processor(user, bot, update, come_from=None):
    poll = polls_repo.find_one({'name': update.message.text, 'archived': False})
    if come_from and come_from == 'start_rating_processor':
        button_list = [
            KeyboardButton("Показать мои ответы"),
            KeyboardButton("Вернуться в главное меню")
        ]
        reply_markup = ReplyKeyboardMarkup(utils.build_menu(button_list, n_cols=1))
        bot.send_message(chat_id=update.message.chat_id,
                         text="Вы вернулись в меню пройденного опроса",
                         reply_markup=reply_markup)
    elif come_from and come_from == 'poll_processor':
        button_list = [
            KeyboardButton("Показать мои ответы"),
            KeyboardButton("Вернуться в главное меню")
        ]
        reply_markup = ReplyKeyboardMarkup(utils.build_menu(button_list, n_cols=1))
        bot.send_message(chat_id=update.message.chat_id,
                         text="Опрос пройден успешно!",
                         reply_markup=reply_markup)
    elif update.message.text == 'Показать мои ответы':
        answers_record = answers_repo.find_one({'poll_id': str(user['current_poll']), 'user_id': str(user['_id'])})
        message = 'Хэш транзакции: ' + answers_record['hash'] + '\n'
        for answer in answers_record['answers']:
            message += 'Вопрос: ' + answer['question_text'] + '\n'
            message += 'Ответ: ' + str(answer['answer']) + '\n'

        bot.send_message(chat_id=update.message.chat_id,
                         text=message)

    elif update.message.text == 'Оценить ответы других участников':
        user['state'] = 'on_rating_start'
        user = users_repo.update(user)
        rating_start_processor(user, bot, update)
        return
    elif update.message.text == 'Вернуться в главное меню':
        user['state'] = 'on_polls_main_menu'
        user = users_repo.update(user)
        main_menu_processor(user, bot, update)
    elif poll:
        button_list = [
            KeyboardButton("Показать мои ответы"),
            KeyboardButton("Вернуться в главное меню")
        ]
        reply_markup = ReplyKeyboardMarkup(utils.build_menu(button_list, n_cols=1))
        bot.send_message(chat_id=update.message.chat_id,
                         text="Вы уже проходили данный опрос!",
                         reply_markup=reply_markup)
    else:
        button_list = [
            KeyboardButton("Показать мои ответы"),
            KeyboardButton("Вернуться в главное меню")
        ]
        reply_markup = ReplyKeyboardMarkup(utils.build_menu(button_list, n_cols=1))
        bot.send_message(chat_id=update.message.chat_id,
                         text="Вы вернулись в меню пройденного опроса",
                         reply_markup=reply_markup)
Example #2
0
def echo(bot, update):
    msg = update.message.text
    chat_id = update.message.chat_id

    pattern = re.compile("(X|O|_) \d \d")

    if msg == "no":
        bot.sendMessage(chat_id=chat_id, text="See you next time!")
        return
    if msg == "yes":
        bot.sendMessage(chat_id=chat_id,
                        text="Would you like to be crosses or noughts?")
        return
    if msg == "crosses":
        custom_keyboard = can.getNiceField()
        reply_markup = ReplyKeyboardMarkup(custom_keyboard)
        bot.sendMessage(chat_id=chat_id,
                        text="Lets start! Your turn!",
                        reply_markup=reply_markup)
        return
    if msg == "noughts":
        can.smartMove()
        custom_keyboard = can.getNiceField()
        reply_markup = ReplyKeyboardMarkup(custom_keyboard)
        bot.sendMessage(chat_id=chat_id,
                        text="I started! Your turn!",
                        reply_markup=reply_markup)
        return
    if not re.match(pattern, msg):
        bot.sendMessage(chat_id=chat_id, text="Incorrect format :C")
        return
    if re.match(pattern, msg):
        i = int(msg[2])
        j = int(msg[4])
        ans = can.move(i, j)
        if ans != "Your turn!":
            bot.sendMessage(chat_id=chat_id, text=ans)
            return
        if can.checkFinish() is not None:
            gameFinish(bot, update)
        else:
            can.smartMove()

            if can.checkFinish() is not None:
                gameFinish(bot, update)
            else:
                custom_keyboard = can.getNiceField()
                reply_markup = ReplyKeyboardMarkup(custom_keyboard)
                bot.sendMessage(chat_id=chat_id,
                                text=ans,
                                reply_markup=reply_markup)
        return
Example #3
0
def get_permanent_reply_keyboard_markup():
    button_list = [
        [KeyboardButton(text="/random"),
         KeyboardButton(text="/saved")]
        #[ KeyboardButton(text="/all"), KeyboardButton(text="/help")]
    ]
    return ReplyKeyboardMarkup(keyboard=button_list)
Example #4
0
    def start(bot: Bot, update: Update):
        if update.message.chat.type != Chat.PRIVATE:
            bot.send_message(update.message.chat_id, "unsupported")
            return

        bot.send_message(update.message.chat_id,
                         WELCOME_MSG,
                         reply_markup=ReplyKeyboardMarkup([[
                             KeyboardButton(RULES_CMD),
                             KeyboardButton(MATCH_LIST_CMD),
                             KeyboardButton(PISHBINI_CMD)
                         ]]))

        user_temp_data[update.message.from_user.id] = {
            'status': STATUS_IDLE,
            'temp_data': None
        }

        u, created = User.objects.get_or_create(
            first_name=update.message.from_user.first_name,
            id=update.message.from_user.id)
        if update.message.from_user.last_name:
            u.last_name = update.message.from_user.last_name
        if update.message.from_user.username:
            u.username = update.message.from_user.username
        u.save()
Example #5
0
def start(update, context):
    mssg = "🦋Welcome To Email Verification Bot"
    stff = [["Verify Email 📩"]]
    afd = ReplyKeyboardMarkup(stff,
                              one_time_keyboard=False,
                              resize_keyboard=True)
    update.message.reply_text(text=mssg, reply_markup=afd)
Example #6
0
def main_menu(bot, update):
    keyboard = [['List', 'Add']]
    bot.sendMessage(update.message.chat_id,
                    text='Please select an action or /cancel',
                    reply_markup=ReplyKeyboardMarkup(keyboard,
                                                     one_time_keyboard=True))
    return ACTION_SELECTOR
    def __init__(self,
                 chat_id: int,
                 user_id: int,
                 lang_id: str,
                 first_name: str,
                 game_handler: object,
                 message_id: int,
                 send_message: callable,
                 multiplayer: bool = None,
                 game_id: str = None):
        # declare variables and set initial values
        self.players = []
        self.chat_id = chat_id
        self.__game_id = game_id
        self.lang_id = lang_id
        self.deck = CardDeck(lang_id)
        # TODO language of the cards & dealer cannot be changed
        # TODO especially with new multiplayer important!
        self.dealer = Dealer(translate("dealerName", lang_id), self.deck)
        self.game_running = False
        self.current_player = 0
        self.game_handler = game_handler
        self.send_message = send_message
        self.logger = logging.getLogger(__name__)

        if multiplayer:
            self.game_type = self.MULTIPLAYER_GAME
            chat_id = 0
        elif chat_id >= 0:
            self.game_type = self.PRIVATE_CHAT
        else:
            self.game_type = self.GROUP_CHAT

        one_more_button = KeyboardButton(
            translate("keyboardItemOneMore", lang_id))
        no_more_button = KeyboardButton(
            translate("keyboardItemNoMore", lang_id))
        stop_button = KeyboardButton(translate("keyboardItemStop", lang_id))
        self.keyboard_running = ReplyKeyboardMarkup(
            keyboard=[[one_more_button, no_more_button], [stop_button]],
            selective=True)

        self.add_player(user_id, first_name, message_id, silent=True)

        # Only send a "Please join the game" message, when it's a group chat
        if self.game_type == self.GROUP_CHAT:
            keyboard = [[
                InlineKeyboardButton(text=translate("join",
                                                    self.lang_id).capitalize(),
                                     callback_data="join_game")
            ]]
            reply_markup = InlineKeyboardMarkup(keyboard)
            send_message(chat_id,
                         translate("newRound", lang_id),
                         message_id=message_id,
                         reply_markup=reply_markup)
        elif self.game_type == self.MULTIPLAYER_GAME:
            pass
        else:
            self.start_game()
Example #8
0
def handle_payee(update, context):
    username = update.message.chat.username
    payee = update.message.text
    if payee == 'Back':
        payee = context.user_data['payee']
    try:
        response = UserHandler.find_user(payee)
        if payee == username:
            update.message.reply_text(
                'You cannot make transactions to yourself!')
            return handle_exit_to_main(update, context)

        elif response:
            update.message.reply_text(
                f'Payee\'s telegram username is {payee}. Please specify amount to pay in cents. For $1, input: 100',
                reply_markup=ReplyKeyboardMarkup(build_navigation_keyboard(),
                                                 one_time_keyboard=True))
            context.user_data['payee'] = payee
            return TRANSACTION_AMOUNT
        else:
            update.message.reply_text(
                f'Payee: {payee}. does not exist'.format(payee))
            return handle_exit_to_main(update, context)

    except Exception as e:
        print(chalk.blue("handle_payee"))
        print(e)
        update.message.reply_text("An error occur in handle_payee")
def remove_reservation_cron(update: Update, _: CallbackContext) -> int:
    global _IS_ACTIVATED
    global _CRON_INTERACTIONS

    if not _authenticate(update):
        return CmdStatus.UNAUTHORISED_USER

    _LOGGER.debug("Received new request: remove_reservation_cron")

    if _IS_ACTIVATED:
        reply_keyboard = [[
            str(i) for i in range(_CRON_INTERACTIONS.get_num_active_crons())
        ]]
        update.message.reply_text(
            "Select the id you want to remove:\n" +
            " ID | GAME DAY | GAME START TIME | GAME DURATION \n" + "\n".join([
                " " + str(cron_id) + "       " + str(game_day) +
                "                  " + str(game_start_time) +
                "                  " + str(game_duration)
                for cron_id, (game_day, game_start_time, game_duration) in
                enumerate(_CRON_INTERACTIONS.get_active_crons())
            ], ),
            reply_markup=ReplyKeyboardMarkup(reply_keyboard,
                                             one_time_keyboard=True))
    else:
        update.message.reply_text(_INACTIVE_MSG)

    return CmdStatus.REMOVE_RESERVATION_CRON.value
def setup_reservation_cron_game_time(update: Update,
                                     _: CallbackContext) -> int:
    global _IS_ACTIVATED
    global _CREATION_CRON_INFO

    if not _authenticate(update):
        return CmdStatus.UNAUTHORISED_USER

    _LOGGER.debug("Received new request: setup_reservation_cron_game_time")

    if _IS_ACTIVATED:
        if _CREATION_CRON_INFO is None:
            update.message.reply_text(
                "Error: Please set up the game day and time first or restart the whole process"
            )
        else:
            _CREATION_CRON_INFO["start_time"] = update.message.text

            reply_keyboard = [_AVAILABLE_DURATIONS]
            update.message.reply_text("How many time do you want to play?",
                                      reply_markup=ReplyKeyboardMarkup(
                                          reply_keyboard,
                                          one_time_keyboard=True))
    else:
        update.message.reply_text(_INACTIVE_MSG)

    return CmdStatus.SETUP_RESERVATION_CRON_GAME_TIME.value
Example #11
0
def archive_poll_menu_processor(user, bot, update):
    poll = polls_repo.find_one({'name': update.message.text, 'archived': True})
    if poll:
        bot.send_message(chat_id=update.message.chat_id,
                         text="Опрос в архиве")
        # user['state'] = 'on_archive_poll'
        # user = users_repo.update(user)
    elif update.message.text == 'Вернуться в главное меню':
        user['state'] = 'on_polls_main_menu'
        user = users_repo.update(user)
        main_menu_processor(user, bot, update)
    else:
        button_list = []
        archive_polls = polls_repo.get_cursor({'archived': True})

        for poll in archive_polls:
            if (not poll['participants']) or (poll['participants'] and user['username'] in poll['participants']):
                button_list.append(KeyboardButton(poll['name']))
        button_list.append(KeyboardButton('Вернуться в главное меню'))

        reply_markup = ReplyKeyboardMarkup(utils.build_menu(button_list, n_cols=1))
        if len(button_list) > 1:
            bot.send_message(chat_id=update.message.chat_id,
                             text="Эти опросы нельзя пройти",
                             reply_markup=reply_markup)
        else:
            bot.send_message(chat_id=update.message.chat_id,
                             text="Архивных опросов нет",
                             reply_markup=reply_markup)
Example #12
0
def poll_start_processor(user, bot, update):
    poll = polls_repo.find_one({'_id': ObjectId(user['current_poll'])})
    if poll.get('welcome_message'):
        bot.send_message(chat_id=update.message.chat_id,
                         text=poll['welcome_message'],
                         reply_markup={'hide_keyboard': True})
    bot.send_message(chat_id=update.message.chat_id,
                     text='Сейчас вам будут задаваться вопросы.',
                     reply_markup={'hide_keyboard': True})
    if poll.get('type') and poll['type'] == 'kompas':
        user['state'] = 'on_bounty'
        question = user['questions'][0] +\
                   ": напиши, за какие заслуги, ты премируешь его за прошедшую неделю"
        bot.send_message(chat_id=update.message.chat_id,
                         text=question,
                         reply_markup={'hide_keyboard': True})
    else:
        user['state'] = 'on_poll'
        question = poll['questions'][0]
        if question['type'] == 'open':
            bot.send_message(chat_id=update.message.chat_id,
                             text=question['text'],
                             reply_markup={'hide_keyboard': True})
        elif question['type'] in ['select', 'multiselect']:
            button_list = []
            for option in question['options']:
                button_list.append(KeyboardButton(option))
            reply_markup = ReplyKeyboardMarkup(utils.build_menu(button_list, n_cols=1))
            bot.send_message(chat_id=update.message.chat_id,
                             text=question['text'],
                             reply_markup=reply_markup)
    user = users_repo.update(user)
Example #13
0
def on_mark(bot, update: Update, user_data):
    msg: Message = update.message
    max_mark = int(user_data['max_mark'])
    kb = [list(map(str, range(max_mark // 5, max_mark, max_mark // 5)))]

    msg.reply_text('Выберите оценку, или введите свою',
                   reply_markup=ReplyKeyboardMarkup(kb, True, True))
    return State.task_process
Example #14
0
def edit_user(update, context):
    username = update.message.chat.username
    context.user_data['user-action'] = 'edit'
    update.message.reply_text(
        'You have choose to edit current user. Please enter telegram username of user',
        reply_markup=ReplyKeyboardMarkup(build_navigation_keyboard(),
                                         one_time_keyboard=True))
    return INPUT_USERNAME
Example #15
0
def create_new_user(update, context):
    username = update.message.chat.username
    context.user_data['user-action'] = 'create'
    update.message.reply_text(
        'You have choose to create new user. Please enter your telegram username of user.',
        reply_markup=ReplyKeyboardMarkup(build_navigation_keyboard(),
                                         one_time_keyboard=True))
    return INPUT_USERNAME
Example #16
0
def handle_fund_menu(update, context):
    username = update.message.chat.username
    reply_keyboard = [['Make Deposit'], ['Make Withdrawal'],
                      ['View Fund Balance'], ['Back']]

    update.message.reply_text(
        f"Welcome {username} to the fund management! What would you like to do?",
        reply_markup=ReplyKeyboardMarkup(reply_keyboard,
                                         one_time_keyboard=True))
    return FUND_ACTION
Example #17
0
def get_keyboard(db_user=None):
    buttons = [
        [KeyboardButton("Помощь")],
        [KeyboardButton("Список комнат")],
        [KeyboardButton("Кто в топе?")]
    ]
    if db_user is not None:
        for admined_room in db_user["admin_on"]:
            buttons.append([KeyboardButton("Код для комнаты " + admined_room)])
    return ReplyKeyboardMarkup(buttons, resize_keyboard=True)
Example #18
0
def photo(update, context):
    choice = update.message.reply_text(
        "Choose a category of photos and you'll be sent the photos",
        reply_markup=ReplyKeyboardMarkup(reply_keyboard,
                                         one_time_keyboard=True,
                                         resize_keyboard=True))
    print(
        "choice", choice
    )  #use replykeyboardmarkup and set one_time_keyboard to true to make it disappear after selection is made
    return choice
    def garage(self, bot, update):
        return_message = """"""
        sender_id = update.message.chat_id
        # Gives menu to select which garage to open
        if not self.sender_is_admin(sender_id):
            self.logger.warning("Unauthorized user", sender_id=sender_id)
            bot.sendMessage(chat_id=sender_id, text='Not authorized')
            return ConversationHandler.END

        options = []  # Stores the keys for the keyboard reply
        self.logger.info("Got request to open garage.", sender_id=sender_id)

        garage_statuses = self._get_garage_position()
        if not garage_statuses:
            bot.sendMessage(
                chat_id=sender_id,
                text='An exception occured while getting garage status',
                reply_keyboard=None)
            return ConversationHandler.END

        # Handle the reponse and creation of the keyboard
        return_message += "Pick a garage \n"
        for one_garage_dict in garage_statuses:
            garage_name = one_garage_dict['garage_name']
            current_status = one_garage_dict['status']
            return_message += ': '.join([
                garage_name, current_status, one_garage_dict['status_time']
            ]) + '\n'

            # Determine whether this can be opened or closed
            if not one_garage_dict['error']:
                action = 'CLOSE' if current_status == 'OPEN' else 'OPEN'
                key_string = ' '.join(['confirm', action, str(garage_name)])
                options.append([key_string])  # Store the key for the keyboard
        options.append(["CANCEL GARAGE"])  # Store the key for the keyboard

        # Send the message with the keyboard
        reply_keyboard = ReplyKeyboardMarkup(options, one_time_keyboard=True)
        bot.sendMessage(chat_id=sender_id,
                        text=return_message,
                        reply_markup=reply_keyboard)

        # Expires request so that the conversation is not open forever
        def expire_request(bot, job):
            bot.sendMessage(chat_id=sender_id,
                            text='Timeout reached. Please start again',
                            reply_keyboard=None)
            return ConversationHandler.END

        # Add job to expire request
        self.garage_expire_request = Job(expire_request, 15.0, repeat=False)
        self.job_queue.put(self.garage_expire_request)

        # Set the conversation to go to the next state
        return GarageConversationState.CONFIRM
Example #20
0
def accept_cancel_keyboard(language_code: str):
    accept_cancel = localization.accept_cancel_menu(language_code)

    button_list = [
        KeyboardButton(accept_cancel[ACCEPT_BUTTON]),
        KeyboardButton(accept_cancel[CANCEL_BUTTON])
    ]

    reply_markup = ReplyKeyboardMarkup(build_menu(button_list, n_cols=1),
                                       resize_keyboard=True)
    return reply_markup
Example #21
0
def supp(update,context):
        global data1 # to assign new dictionary to external/global variable
    # create new empty dictionary
        data1 = {'typing':""}
        help_msg = (f"<b>📞 You are now in direct contact with our Administrator</b>\nSend here any message you want to submit, you will receive the answer directly here in chat!")
        
        help_layout = [["⬅️ Return"]]
        
        help = ReplyKeyboardMarkup(help_layout,one_time_keyboard=False,resize_keyboard=True)
        
        update.message.reply_text(text=help_msg, parse_mode=ParseMode.HTML,reply_markup=help)
        return TYPING
Example #22
0
def webhook_handler():
    if request.method == "POST":
        update = telegram.Update.de_json(request.get_json(force=True), bot)
        try:
            kb = ReplyKeyboardMarkup([["Обновить"]])
            chat_id = update.message.chat.id
            text = update.message.text
            userid = update.message.from_user.id
            username = update.message.from_user.username
            bot.send_message(chat_id=chat_id, text=get_info(), reply_markup=kb)
        except Exception, e:
            print e
Example #23
0
def handle_transaction_menu(update, context):
    username = update.message.chat.username
    reply_keyboard = [['Make An Order'],
                      ['Make A Transaction', 'View Balance'],
                      ['Transaction History', 'QR code'], ['Back']]

    update.message.reply_text(
        f"Welcome {username} to the transactions dashboard! What would you like to do?",
        reply_markup=ReplyKeyboardMarkup(reply_keyboard,
                                         one_time_keyboard=True))
    return TRANSACTION_ACTION
    """
Example #24
0
def action_selection(bot, update):
    action = update.message.text
    _get_movie_lists()
    reply_keyboard = [[ml['name'] for ml in MOVIE_LISTS]]
    bot.sendMessage(update.message.chat_id,
                    text='Please select a movie list or /cancel',
                    reply_markup=ReplyKeyboardMarkup(reply_keyboard,
                                                     one_time_keyboard=True))
    if action == 'List':
        return LIST_MOVIES
    elif action == 'Add':
        return ADD_MOVIES
Example #25
0
def button_wall(update,context):
    query = update.callback_query
    if query.data == "1":
        if vv != "not set":
            del1.delete()
        else:
            del2.delete()
        itext=("✏️ Send now your TRX Address to use it in future withdrawals!")
        addd_res = [["⬅️ Return"]]
        ad_rs = ReplyKeyboardMarkup(addd_res,one_time_keyboard=False,resize_keyboard=True)
        update.effective_chat.send_message(text=itext, reply_markup=ad_rs)
        return TITLE
Example #26
0
def handle_username(update, context):
    user = update.message.text
    context.user_data['input_username'] = user
    if find_user(user) or context.user_data['user-action'] == 'create':
        update.message.reply_text(
            'User\'s telegram username is {}. Please input the role: ADMIN, SELLER, CONSUMER'
            .format(user),
            reply_markup=ReplyKeyboardMarkup(build_user_role_keyboard(),
                                             one_time_keyboard=True))
        return INPUT_ROLE
    else:
        update.message.reply_text('User not found')
        return done(update, context)
Example #27
0
    def __init__(self, act: dict):
        self.original_dict = act
        self.id = act['id']
        self.triggers = act['triggers']
        self.data = act['data']

        self.follow_up_action_id = None
        if 'follow_up_action_id' in act:
            self.follow_up_action_id = act['follow_up_action_id']
        self.follow_up_action = None

        self.next_action_id = None
        if 'next_action_id' in act:
            self.next_action_id = act['next_action_id']
        self.next_action = None

        self.markup = None
        if 'markup_type' in act:
            markup_type = act['markup_type']

            if 'markup_data' in act:
                markup_string = act['markup_data']
                # convert it to lists in list
                options = [[item for item in row.split(",")]
                           for row in markup_string.split(":")]

                if markup_type == MarkupType.OneTimeReply:
                    self.markup = ReplyKeyboardMarkup(options,
                                                      one_time_keyboard=True)
                if markup_type == MarkupType.StaticReply:
                    self.markup = ReplyKeyboardMarkup(options)

            elif act['markup_type'] == MarkupType.Remove:
                self.markup = ReplyKeyboardRemove()
            else:
                print(
                    'error 15'
                )  # act is not correct , markup_type exist and not 'Remove' but no markup_data
Example #28
0
    def generate_cities_keyboard(self, with_current_location=False):
        # select distinct hometown as city from users union select distinct city from opportunities order by city asc;
        op_cities = self.db.table("opportunities").distinct().select("city")
        cities = self.db.table("users").distinct().select("hometown as city") \
            .union(op_cities).order_by("city", "asc").get()

        keyboard = []

        for c in cities:
            keyboard.append([KeyboardButton(c.city)])

        return ReplyKeyboardMarkup(keyboard,
                                   one_time_keyboard=True,
                                   resize_keyboard=True)
def start(update: Update, context: CallbackContext):
    """
    method to handle the /start command and create keyboard
    """

    # defining the keyboard layout
    kbd_layout = [['Option 1', 'Option 2'], ['Option 3', 'Option 4'],
                  ["Option 5"]]

    # converting layout to markup
    # documentation: https://python-telegram-bot.readthedocs.io/en/stable/telegram.replykeyboardmarkup.html
    kbd = ReplyKeyboardMarkup(kbd_layout)

    # sending the reply so as to activate the keyboard
    update.message.reply_text(text="Select Options", reply_markup=kbd)
def start(bot, update):
    keyboard = [[
        InlineKeyboardButton("Option 1", callback_data='1'),
        InlineKeyboardButton("Option 2", callback_data='2')
    ], [InlineKeyboardButton("Option 3", callback_data='3')]]
    #reply_markup = InlineKeyboardMarkup(keyboard)

    buttons = [[u'녹동', u'소태', u'학동증심사입구'],
               [u'남광주', u'문화전당', u'금남로4가', u'금남로5가'],
               [u'양동시장', u'돌고개', u'농성', u'화정'],
               [u'쌍촌', u'운천', u'상무', u'김대중', u'공항'],
               [u'송정공원', u'광주송정역', u'도선', u'평동']]
    reply_markup = ReplyKeyboardMarkup(buttons, one_time_keyboard=True)

    update.message.reply_text('Please choose:', reply_markup=reply_markup)