Example #1
0
async def warn_func(message: Message, chat, user, text, strings, filter_action=False):
    chat_id = chat["chat_id"]
    chat_title = chat["chat_title"]
    by_id = BOT_ID if filter_action is True else message.from_user.id
    user_id = user["user_id"] if filter_action is False else user

    if user_id == BOT_ID:
        await message.reply(strings["warn_sofi"])
        return

    if not filter_action:
        if user_id == message.from_user.id:
            await message.reply(strings["warn_self"])
            return

    if await is_user_admin(chat_id, user_id):
        if not filter_action:
            await message.reply(strings["warn_admin"])
        return

    reason = text
    warn_id = str(
        (
            await db.warns.insert_one(
                {
                    "user_id": user_id,
                    "chat_id": chat_id,
                    "reason": str(reason),
                    "by": by_id,
                }
            )
        ).inserted_id
    )

    admin = await get_user_link(by_id)
    member = await get_user_link(user_id)
    text = strings["warn"].format(admin=admin, user=member, chat_name=chat_title)

    if reason:
        text += strings["warn_rsn"].format(reason=reason)

    warns_count = await db.warns.count_documents(
        {"chat_id": chat_id, "user_id": user_id}
    )

    buttons = InlineKeyboardMarkup().add(
        InlineKeyboardButton(
            "тЪая╕П Remove warn", callback_data="remove_warn_{}".format(warn_id)
        )
    )

    if await db.rules.find_one({"chat_id": chat_id}):
        buttons.insert(
            InlineKeyboardButton(
                "ЁЯУЭ Rules", url=await get_start_link(f"btn_rules_{chat_id}")
            )
        )

    if warn_limit := await db.warnlimit.find_one({"chat_id": chat_id}):
        max_warn = int(warn_limit["num"])
Example #2
0
def inline_keyboard(*buttons, row_width=2):
    """ Собирает по полученным кнопкам InlineKeyboard """
    keyboard = InlineKeyboardMarkup()
    keyboard.row_width = row_width
    buttons = [b.value if isinstance(b, InlineButtons) else b for b in buttons]
    keyboard.add(*buttons)
    return keyboard
Example #3
0
class ChatStates(StatesGroup):
    class MyState(State):
        def __init__(self, text=None, reply_markup=None):
            self.text = text
            self.reply_markup = reply_markup
            super().__init__()

        async def set(self, message: types.Message = None):
            if self.text is not None and message is not None:
                await message.answer(self.text, reply_markup=self.reply_markup)
            await super().set()

    yes_no_kb = InlineKeyboardMarkup()
    yes_no_kb.add(InlineKeyboardButton('yes', callback_data='yes'),
                  InlineKeyboardButton('no', callback_data='no'))
    similar_different_kb = InlineKeyboardMarkup()
    similar_different_kb.add(
        InlineKeyboardButton('similar', callback_data='similar'))
    similar_different_kb.add(
        InlineKeyboardButton('different', callback_data='different'))

    WaitingForAge = MyState(
        'Hi, I can tell you a joke! How old are you? (Write the number)')
    RandomKind = MyState('Let’s pick a random kind of joke?', yes_no_kb)
    GallowsHumor = MyState('And what about gallows humor?', yes_no_kb)
    RandomJoke = MyState()
    OneMoreJoke = MyState(
        'Do you want one more similar joke or maybe something different?',
        similar_different_kb)
async def new_shedule_1_potok_handler(callback : types.CallbackQuery, state : FSMContext):
    await callback.answer()
    await state.update_data(id_shedule = 1)
    keyboard = InlineKeyboardMarkup()
    keyboard.add(InlineKeyboardButton(text = "Назад", callback_data="new_shedule_back"))
    await callback.message.edit_text("Отправьте новый текст с расписанием", reply_markup=keyboard)
    await AdminStateMainMenu.write_new_shedule.set()
Example #5
0
async def get_start_func(message, strings, edit=False):
    msg = message.message if hasattr(message, "message") else message

    task = msg.edit_text if edit else msg.reply
    buttons = InlineKeyboardMarkup()
    buttons.add(InlineKeyboardButton(strings["btn_help"], callback_data="get_help"))
    buttons.add(
        InlineKeyboardButton(strings["btn_lang"], url="https://t.me/ExploreMoviez"),
        InlineKeyboardButton(
            strings["btn_source"], url="http://www.google.com/"
        ),
    )
    buttons.add(
        InlineKeyboardButton(strings["btn_channel"], url="https://t.me/Mrvasuz"),
        InlineKeyboardButton(
            "My Crush👩‍❤️‍💋‍👨", url="https://t.me/Sasi_kaladhar"
        ),
    )
    buttons.add(
        InlineKeyboardButton(
            "💋Add Meh to your group",
            url=f"https://telegram.me/Explorerobot?startgroup=true",
        )
    )
    # Handle error when user click the button 2 or more times simultaneously
    with suppress(MessageNotModified):
        await task(strings["start_hi"], reply_markup=buttons)
Example #6
0
async def get_start_func(message, strings, edit=False):
    msg = message.message if hasattr(message, "message") else message

    task = msg.edit_text if edit else msg.reply
    buttons = InlineKeyboardMarkup()
    buttons.add(
        InlineKeyboardButton(strings["btn_help"], callback_data="get_help"))
    buttons.add(
        InlineKeyboardButton(strings["btn_lang"], callback_data="lang_btn"),
        InlineKeyboardButton(strings["btn_source"],
                             url="https://t.me/bothousesupport"),
    )
    buttons.add(
        InlineKeyboardButton(strings["btn_channel"],
                             url="https://t.me/doraemonupdate"),
        InlineKeyboardButton("Support Grup",
                             url="https://t.me/doraemonSupport10"),
    )
    buttons.add(
        InlineKeyboardButton(
            "Add DORAEMON to your group",
            url=f"http://t.me/DoraemonxRobot?startgroup=true",
        ))
    # Handle error when user click the button 2 or more times simultaneously
    with suppress(MessageNotModified):
        await task(strings["start_hi"], reply_markup=buttons)
async def admin_whos(callback: types.CallbackQuery):
    await callback.answer()
    user = DataBaseFunc.get_user(callback.from_user.id)
    keyboard = InlineKeyboardMarkup()
    keyboard.add(InlineKeyboardButton(text="Назад", callback_data="admin_in_admin_menu"))
    await callback.message.edit_text(text=AdminHelper.get_whos_admin(user), reply_markup=keyboard)
    await AdminStateMainMenu.whos.set()
Example #8
0
async def get_start_func(message, strings, edit=False):
    msg = message.message if hasattr(message, "message") else message

    task = msg.edit_text if edit else msg.reply
    buttons = InlineKeyboardMarkup()
    buttons.add(
        InlineKeyboardButton(strings["btn_help"], callback_data="get_help"))
    buttons.add(
        InlineKeyboardButton(strings["btn_lang"], callback_data="lang_btn"),
        InlineKeyboardButton(strings["btn_source"],
                             url="https://github.com/TeamDaisyX/"),
    )
    buttons.add(
        InlineKeyboardButton(strings["btn_channel"],
                             url="https://t.me/DaisyXUpdates"),
        InlineKeyboardButton("👥 Support Grup",
                             url="https://t.me/DaisySupport_Official"),
    )
    buttons.add(
        InlineKeyboardButton(
            "👸🏼 Add DaisyX to your group",
            url=f"https://telegram.me/daisyxbot?startgroup=true",
        ))
    # Handle error when user click the button 2 or more times simultaneously
    with suppress(MessageNotModified):
        await task(strings["start_hi"], reply_markup=buttons)
Example #9
0
def get_keyboard_with_music_list(music_list: list) -> InlineKeyboardMarkup:
    keyboard = InlineKeyboardMarkup()

    for music in music_list:
        keyboard.add(InlineKeyboardButton(text=music['title'], callback_data=music['path_to_file']))

    return keyboard
Example #10
0
def remove_wallet_inl(bch, wallet_id):
    keyboard = InlineKeyboardMarkup(row_width=2)

    list_buttons = [
        InlineKeyboardButton(_('Нет'),
                             callback_data='{}_{}_address_info'.format(
                                 bch, wallet_id)),
        InlineKeyboardButton(_('Нет'),
                             callback_data='{}_{}_address_info'.format(
                                 bch, wallet_id)),
        InlineKeyboardButton(_('Нет'),
                             callback_data='{}_{}_address_info'.format(
                                 bch, wallet_id)),
        InlineKeyboardButton(_('Да, удалить'),
                             callback_data='{}_{}_remove_address'.format(
                                 bch, wallet_id))
    ]
    random.shuffle(list_buttons)
    list_buttons.append(
        InlineKeyboardButton(_('Назад'),
                             callback_data='{}_{}_address_info'.format(
                                 bch, wallet_id)))

    for btn in list_buttons:
        keyboard.insert(btn)

    return keyboard
Example #11
0
def select_bch_inl():
    keyboard = InlineKeyboardMarkup(row_width=1)
    keyboard.add(
        InlineKeyboardButton('Ethereum', callback_data='ethereum_view'),
        InlineKeyboardButton('Tron', callback_data='tron_view'),
    )
    return keyboard
Example #12
0
async def change_lang(message, lang, strings, e=False):
    await change_chat_lang(message.chat.id, lang)

    lang_info = LANGUAGES[lang]['language_info']

    text = strings['lang_changed'].format(lang_name=lang_info['flag'] + " " +
                                          lang_info['name'])
    text += strings['help_us_translate']

    markup = InlineKeyboardMarkup()

    if 'translators' in lang_info:
        markup.add(
            InlineKeyboardButton(
                strings['see_translators'],
                callback_data=translators_lang_cb.new(lang=lang)))

    if e:
        await message.edit_text(text,
                                reply_markup=markup,
                                disable_web_page_preview=True)
    else:
        await message.reply(text,
                            reply_markup=markup,
                            disable_web_page_preview=True)
Example #13
0
async def del_filter(message, chat, strings):
    handler = get_args_str(message)
    chat_id = chat["chat_id"]
    filters = await db.filters.find({
        "chat_id": chat_id,
        "handler": handler
    }).to_list(9999)
    if not filters:
        await message.reply(
            strings["no_such_filter"].format(chat_name=chat["chat_title"]))
        return

    # Remove filter in case if we found only 1 filter with same header
    filter = filters[0]
    if len(filters) == 1:
        await db.filters.delete_one({"_id": filter["_id"]})
        await update_handlers_cache(chat_id)
        await message.reply(
            strings["del_filter"].format(handler=filter["handler"]))
        return

    # Build keyboard row for select which exactly filter user want to remove
    buttons = InlineKeyboardMarkup(row_width=1)
    text = strings["select_filter_to_remove"].format(handler=handler)
    for filter in filters:
        action = FILTERS_ACTIONS[filter["action"]]
        buttons.add(
            InlineKeyboardButton(
                # If module's filter support custom del btn names else just show action name
                "" + action["del_btn_name"](message, filter)
                if "del_btn_name" in action else filter["action"],
                callback_data=filter_remove_cp.new(id=str(filter["_id"])),
            ))

    await message.reply(text, reply_markup=buttons)
Example #14
0
def help_markup(modules):
    markup = InlineKeyboardMarkup()
    for module in modules:
        markup.insert(
            InlineKeyboardButton(module,
                                 callback_data=helpmenu_cb.new(mod=module)))
    return markup
Example #15
0
def EditMenuMarkup(chatID: str, chatType: str) -> InlineKeyboardMarkup:
    def RulesMark(role: str, answDict) -> str:
        if answDict['editSettings'] == role:
            return " ✅"
        else:
            return " ❌"

    lang = DBH.GetSetting(chatID, "lang", chatType)
    AllSettings = DBH.GetAllSettings(chatID, chatType)
    dictLang = ButtonTexts[lang]
    EditMenuMU = InlineKeyboardMarkup()
    EditMenuMU.add(
        InlineKeyboardButton(dictLang['creator'] +
                             RulesMark('creator', AllSettings),
                             callback_data="edit_creator"))
    EditMenuMU.add(
        InlineKeyboardButton(dictLang['admins'] +
                             RulesMark('admins', AllSettings),
                             callback_data="edit_admins"))
    EditMenuMU.add(
        InlineKeyboardButton(dictLang['everybody'] +
                             RulesMark('everybody', AllSettings),
                             callback_data="edit_everybody"))
    EditMenuMU.add(
        InlineKeyboardButton(dictLang['back'], callback_data="settings"))
    return EditMenuMU
Example #16
0
async def warn_func(message: Message,
                    chat,
                    user,
                    text,
                    strings,
                    filter_action=False):
    chat_id = chat['chat_id']
    chat_title = chat['chat_title']
    by_id = BOT_ID if filter_action is True else message.from_user.id
    user_id = user['user_id'] if filter_action is False else user

    if user_id == BOT_ID:
        await message.reply(strings['warn_sofi'])
        return

    if not filter_action:
        if user_id == message.from_user.id:
            await message.reply(strings['warn_self'])
            return

    if await is_user_admin(chat_id, user_id):
        if not filter_action:
            await message.reply(strings['warn_admin'])
        return

    reason = text
    warn_id = str((await db.warns.insert_one({
        'user_id': user_id,
        'chat_id': chat_id,
        'reason': str(reason),
        'by': by_id
    })).inserted_id)

    admin = await get_user_link(by_id)
    member = await get_user_link(user_id)
    text = strings['warn'].format(admin=admin,
                                  user=member,
                                  chat_name=chat_title)

    if reason:
        text += strings['warn_rsn'].format(reason=html.escape(reason))

    warns_count = await db.warns.count_documents({
        'chat_id': chat_id,
        'user_id': user_id
    })

    buttons = InlineKeyboardMarkup().add(
        InlineKeyboardButton("тЪая╕П Remove warn",
                             callback_data='remove_warn_{}'.format(warn_id)))

    if await db.rules.find_one({'chat_id': chat_id}):
        buttons.insert(
            InlineKeyboardButton("ЁЯУЭ Rules",
                                 url=await
                                 get_start_link(f'btn_rules_{chat_id}')))

    if warn_limit := await db.warnlimit.find_one({'chat_id': chat_id}):
        max_warn = int(warn_limit['num'])
Example #17
0
def full_wallets_inl():
    keyboard = InlineKeyboardMarkup(row_width=2)
    keyboard.add(
        InlineKeyboardButton(_('Добавить кошелек'),
                             callback_data='add_wallet'),
        InlineKeyboardButton(_('Конвертировать'),
                             callback_data='convert_wallet'))
    return keyboard
Example #18
0
    async def generate_rate_markup():
        markup = InlineKeyboardMarkup()

        markup.row(*[
            InlineKeyboardButton(text=num, callback_data=f"rate_{num}")
            for num in range(MIN_RATE, MAX_RATE + 1)
        ])
        return markup
Example #19
0
def get_help(chat_id):
    text = "Select module to get help"
    counter = 0
    buttons = InlineKeyboardMarkup(row_width=2)
    for module in HELP:
        counter += 1
        btn_name = get_string(module, "btn", chat_id, dir="HELPS")
        buttons.insert(InlineKeyboardButton(btn_name, callback_data=help_page_cp.new(module=module)))
    return text, buttons
Example #20
0
def DeleteMarkup(chatID: str, chatType: str) -> InlineKeyboardMarkup:
    isDeleteButton = DBH.GetSetting(chatID, "deleteButton", chatType)
    DeleteMU = InlineKeyboardMarkup()
    if isDeleteButton:
        lang = DBH.GetSetting(chatID, "lang", chatType)
        dictLang = ButtonTexts[lang]
        DeleteMU.add(
            InlineKeyboardButton(dictLang['delete'], callback_data="delete"))
    return DeleteMU
Example #21
0
async def shedule(callback: types.CallbackQuery):
    await callback.answer()
    user = DataBaseFunc.get_user(callback.from_user)
    ketboard = InlineKeyboardMarkup()
    ketboard.add(InlineKeyboardButton("Назад", callback_data="shedule_back"))
    with open(texts_shedule_filename, 'r', encoding='utf8') as file:
        TEXT_SHEDULE_1 = file.read()

    await callback.message.edit_text(text=TEXT_SHEDULE_1,
                                     reply_markup=ketboard)
Example #22
0
def button_parser(chat_id, texts, pm=False, aio=False, row_width=None):
    buttons = InlineKeyboardMarkup(row_width=row_width) if aio else []
    pattern = r'\[(.+?)\]\((button|btn)(.+?)(:.+?|)(:same|)\)(\n|)'
    raw_buttons = re.findall(pattern, texts)
    text = re.sub(pattern, '', texts)
    for raw_button in raw_buttons:
        name = raw_button[0]
        action = raw_button[2]
        argument = raw_button[3][1:].lower() if raw_button[3] else ''

        if action in BUTTONS:
            cb = BUTTONS[action]
            string = f'{cb}_{argument}_{chat_id}' if argument else f'{cb}_{chat_id}'
            if aio:
                start_btn = InlineKeyboardButton(
                    name, url=f'https://t.me/{BOT_USERNAME}?start=' + string)
                cb_btn = InlineKeyboardButton(name, callback_data=string)
            else:
                start_btn = Button.url(
                    name, f'https://t.me/{BOT_USERNAME}?start=' + string)
                cb_btn = Button.inline(name, string)

            if cb.endswith('sm'):
                btn = cb_btn if pm else start_btn
            elif cb.endswith('cb'):
                btn = cb_btn
            elif cb.endswith('start'):
                btn = start_btn
            elif cb.startswith('url'):
                btn = Button.url(name, argument)
        elif action == 'url':
            if argument[0] == '/' and argument[1] == '/':
                argument = argument[2:]
            btn = InlineKeyboardButton(
                name, url=argument) if aio else Button.url(name, argument)
        else:
            # If btn not registred
            btn = None
            if argument:
                text += f'\n[{name}].(btn{action}:{argument})'
            else:
                text += f'\n[{name}].(btn{action})'
                continue

        if aio:
            buttons.insert(btn) if raw_button[4] else buttons.add(btn)
        else:
            if len(buttons) < 1 and raw_button[4]:
                buttons.add(btn) if aio else buttons.append([btn])
            else:
                buttons[-1].append(btn) if raw_button[4] else buttons.append(
                    [btn])

    if not aio and len(buttons) == 0:
        buttons = None

    if not text or text == ' ':  # TODO: Sometimes we can return text == ' '
        text = None

    return text, buttons
Example #23
0
async def categories_keyboard():
    CURRENT_LEVEL = 0
    markup = InlineKeyboardMarkup(row_width=2)

    categories = await get_categories()
    for category in categories:
        button_text = f'{category.category_name}'
        callback_data = make_callback_data(level=CURRENT_LEVEL + 1, category=category.category_code)
        markup.insert(
            InlineKeyboardButton(text=button_text, callback_data=callback_data)
        )
    return markup
Example #24
0
async def get_start_func(message, strings, edit=False):
    msg = message.message if hasattr(message, 'message') else message
    task = msg.edit_text if edit else msg.reply
    buttons = InlineKeyboardMarkup()
    buttons.add(InlineKeyboardButton(strings['btn_help'], callback_data='get_help'))
    buttons.add (InlineKeyboardButton(strings['btn_lang'], callback_data='lang_btn'),
                 InlineKeyboardButton(strings['btn_source'], url='https://github.com/TeamDaisyX/DaisyX-v2'))
    buttons.add(InlineKeyboardButton(strings['btn_channel'], url='https://t.me/DaisyXUpdates'),
                InlineKeyboardButton('👥 Support Grup', url='https://t.me/DaisyXUpdates'))
    buttons.add(InlineKeyboardButton("👸🏼 Add DaisyX to your group", url=f'https://telegram.me/daisyxbot?startgroup=true'))
    # Handle error when user click the button 2 or more times simultaneously
    with suppress(MessageNotModified):
        await task(strings['start_hi'], reply_markup=buttons)
Example #25
0
def choice_method_add_wallet_inl(bch):
    keyboard = InlineKeyboardMarkup(row_width=1)
    keyboard.add(
        InlineKeyboardButton(_('Добавить адрес кошелька'),
                             callback_data=f'{bch}_add_bch_wallet'),
        InlineKeyboardButton(_('Импортировать приватный ключ'),
                             callback_data=f'{bch}_import_private_key'),
        # InlineKeyboardButton(_('Импортировать seed-фразу'),
        #                 callback_data=f'{bch}_import_seed_phrase'),
        InlineKeyboardButton(_('Сгенерировать новый кошелек'),
                             callback_data=f'{bch}_generate_wallet'),
        InlineKeyboardButton(_('Назад'), callback_data=f'{bch}_view'))
    return keyboard
Example #26
0
async def delall_filters(message: Message, strings: dict):
    if not await is_chat_creator(message, message.chat.id,
                                 message.from_user.id):
        return await message.reply(strings['not_chat_creator'])
    buttons = InlineKeyboardMarkup()
    buttons.add(*[
        InlineKeyboardButton(strings['confirm_yes'],
                             callback_data=filter_delall_yes_cb.new(
                                 chat_id=message.chat.id)),
        InlineKeyboardButton(strings['confirm_no'],
                             callback_data="filter_delall_no_cb")
    ])
    return await message.reply(strings['delall_header'], reply_markup=buttons)
Example #27
0
async def get_start_func(message, strings, edit=False):
    msg = message.message if hasattr(message, "message") else message

    task = msg.edit_text if edit else msg.reply
    buttons = InlineKeyboardMarkup()
    buttons.add(InlineKeyboardButton(strings["btn_help"], callback_data="get_help"))
    buttons.add(
        InlineKeyboardButton(strings["☎️ Contact Admins"], url="https://t.me/shamilhelpbot),
        InlineKeyboardButton(
            strings["🛠️ Support Group"], url="https://t.me/redbullfed"
        ),
    )
    buttons.add(
        InlineKeyboardButton(strings["🔗 Our Channels"], url="https://t.me/mwklinks"),
        InlineKeyboardButton(
            "🎬 Movie Group", url="https://t.me/movieworldkdy"
        ),
    )
    buttons.add(
        InlineKeyboardButton(
            "📞 Contact My Dev 👨‍🔬",
            url=f"https://telegram.me/shamilnelli",
        )
    )
    # Handle error when user click the button 2 or more times simultaneously
    with suppress(MessageNotModified):
        await task(strings["start_hi"], reply_markup=buttons)
Example #28
0
async def select_lang_keyboard(message, strings, edit=False):
    markup = InlineKeyboardMarkup(row_width=2)
    task = message.reply if edit is False else message.edit_text

    lang_info = await get_chat_lang_info(message.chat.id)

    if message.chat.type == "private":
        text = strings["your_lang"].format(lang=lang_info["flag"] + " " +
                                           lang_info["babel"].display_name)
        text += strings["select_pm_lang"]

    # TODO: Connected chat lang info

    else:
        text = strings["chat_lang"].format(lang=lang_info["flag"] + " " +
                                           lang_info["babel"].display_name)
        text += strings["select_chat_lang"]

    for lang in LANGUAGES.values():
        lang_info = lang["language_info"]
        markup.insert(
            InlineKeyboardButton(
                lang_info["flag"] + " " + lang_info["babel"].display_name,
                callback_data=select_lang_cb.new(lang=lang_info["code"],
                                                 back_btn=edit is not False),
            ))

    markup.add(
        InlineKeyboardButton(strings["crowdin_btn"],
                             url="https://t.me/Daisysupport_official"))
    if edit:
        markup.add(
            InlineKeyboardButton(strings["back"], callback_data="go_to_start"))
    with suppress(MessageNotModified):
        await task(text, reply_markup=markup)
Example #29
0
async def select_lang_keyboard(message, strings, edit=False):
    markup = InlineKeyboardMarkup(row_width=2)
    task = message.reply if edit is False else message.edit_text

    lang_info = await get_chat_lang_info(message.chat.id)

    if message.chat.type == 'private':
        text = strings['your_lang'].format(lang=lang_info['flag'] + " " +
                                           lang_info['babel'].display_name)
        text += strings['select_pm_lang']

    # TODO: Connected chat lang info

    else:
        text = strings['chat_lang'].format(lang=lang_info['flag'] + " " +
                                           lang_info['babel'].display_name)
        text += strings['select_chat_lang']

    for lang in LANGUAGES.values():
        lang_info = lang['language_info']
        markup.insert(
            InlineKeyboardButton(
                lang_info['flag'] + " " + lang_info['babel'].display_name,
                callback_data=select_lang_cb.new(lang=lang_info['code'],
                                                 back_btn=edit is not False),
            ))

    markup.add(
        InlineKeyboardButton(strings['crowdin_btn'],
                             url='https://crowdin.com/project/hitsukix'))
    if edit:
        markup.add(
            InlineKeyboardButton(strings['back'], callback_data='go_to_start'))
    with suppress(MessageNotModified):
        await task(text, reply_markup=markup)
Example #30
0
async def release_new_build(message):
    await ReleaseState.sel_build_type.set()

    text = "<b>Releasing new OrangeFox build</b>"
    text += "\nSelect build type:"
    buttons = InlineKeyboardMarkup(row_width=2).add(
        InlineKeyboardButton(
            "Stable", callback_data=build_type_cp.new(build_type='stable')),
        InlineKeyboardButton(
            "Beta/RC", callback_data=build_type_cp.new(build_type='beta')))

    buttons.add(InlineKeyboardButton("Exit", callback_data='cancel'))

    await message.reply(text, reply_markup=buttons)