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 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)
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"])
def kb_schedule_show(schedule_id: int, route_id: int, is_active: bool) -> InlineKeyboardMarkup: """Display keyboard with actions for single schedule.""" bell = Bell.by_state(not is_active) toggle = 'Отключить уведомления' if is_active else 'Включить уведомления' return InlineKeyboardMarkup(inline_keyboard=[ [ InlineKeyboardButton( f'{bell} {toggle}', callback_data=cd_schedules.new( action='toggle', schedule_id=schedule_id, route_id=False, ), ), ], [ InlineKeyboardButton( f'{uchar.WASTEBASKET} Удалить', callback_data=cd_schedules.new( action='delete', schedule_id=schedule_id, route_id=route_id, ), ), ], [ InlineKeyboardButton( f'{uchar.BACK_ARROW} Назад', callback_data=cd_routes.new(action='schedule', route_id=route_id), ), ], ])
async def change_lang(message, lang, e=False, back_btn=False): chat_id = message.chat.id await change_chat_lang(chat_id, lang) strings = await get_strings(chat_id, "language") lang_info = LANGUAGES[lang]["language_info"] text = strings["lang_changed"].format(lang_name=lang_info["flag"] + " " + lang_info["babel"].display_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 back_btn == "True": # Callback_data converts boolean to str markup.add( InlineKeyboardButton(strings["back"], callback_data="go_to_start")) if e: with suppress(MessageNotModified): 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)
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
def kb_schedule_list(schedules: Union[list, None], route_id: int) -> InlineKeyboardMarkup: """Display keyboard with list of all schedules.""" buttons = list() if schedules is not None: for schedule in schedules: cron = json.loads(schedule.cron) readable = cronity.humanize(cron) bell = Bell.by_state(schedule.is_active) buttons.append([ InlineKeyboardButton( f'{bell} {readable}', callback_data=cd_schedules.new('select', schedule.id, False), ), ]) buttons.append([ InlineKeyboardButton( f'{uchar.BACK_ARROW} Назад', callback_data=cd_routes.new(action='select', route_id=route_id), ), InlineKeyboardButton( f'{uchar.NEW} Добавить', callback_data=cd_schedules.new('add', False, route_id=route_id), ), ]) return InlineKeyboardMarkup(inline_keyboard=buttons)
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
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)
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
async def select_lang_keyboard(message, strings): markup = InlineKeyboardMarkup(row_width=2) 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['name'], callback_data=select_lang_cb.new(lang=lang_info['code']))) markup.add( InlineKeyboardButton(strings['crowdin_btn'], url='https://crowdin.com/project/sophiebot')) await message.reply(text, reply_markup=markup)
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
async def change_lang(message, lang, e=False, back_btn=False): chat_id = message.chat.id await change_chat_lang(chat_id, lang) strings = await get_strings(chat_id, 'language') lang_info = LANGUAGES[lang]['language_info'] text = strings['lang_changed'].format(lang_name=lang_info['flag'] + " " + lang_info['babel'].display_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 back_btn == 'True': # Callback_data converts boolean to str markup.add( InlineKeyboardButton(strings['back'], callback_data='go_to_start')) if e: with suppress(MessageNotModified): 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)
async def process_simple_calendar(callback_query: CallbackQuery, callback_data: dict, state: FSMContext): selected, date = await SimpleCalendar().process_selection( callback_query, callback_data) if selected: async with state.proxy() as data: data['time'] = date db_session = callback_query.message.bot.get('db') async with db_session() as session: student = await get_student(session, callback_query.message.chat.id) group = student.grp sql = select(Lesson).where( and_(Lesson.grp == group, Lesson.day == datetime.datetime.weekday(date))) request = await session.execute(sql) lessons = request.scalars() keyboard = ReplyKeyboardMarkup() keyboard.insert(InlineKeyboardButton('Другое')) for lesson in lessons: keyboard.insert(InlineKeyboardButton(str(lesson.name))) keyboard.insert(InlineKeyboardButton('Отмена')) await callback_query.message.answer("Ок. А какая пара?", reply_markup=keyboard) await TaskState.task_name.set()
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'])
def full_wallets_inl(): keyboard = InlineKeyboardMarkup(row_width=2) keyboard.add( InlineKeyboardButton(_('Добавить кошелек'), callback_data='add_wallet'), InlineKeyboardButton(_('Конвертировать'), callback_data='convert_wallet')) return keyboard
async def help_cb(event, strings): button = InlineKeyboardMarkup() button.add( InlineKeyboardButton(strings['click_btn'], url='https://wiki.sophiebot.gq')) button.add( InlineKeyboardButton(strings['back'], callback_data='go_to_start')) with suppress(MessageNotModified): await event.message.edit_text(strings['help_header'], reply_markup=button)
async def enable_all(message, chat, strings): # Ensure that something is disabled if not await db.disabled_v2.find_one({'chat_id': chat['chat_id']}): await message.reply(strings['not_disabled_anything'].format(chat_title=chat['chat_title'])) return text = strings['enable_all_text'].format(chat_name=chat['chat_title']) buttons = InlineKeyboardMarkup() buttons.add(InlineKeyboardButton(strings['enable_all_btn_yes'], callback_data='enable_all_notes_cb')) buttons.add(InlineKeyboardButton(strings['enable_all_btn_no'], callback_data='cancel')) await message.reply(text, reply_markup=buttons)
async def clear_all_notes(message, chat, strings): # Ensure notes count if not await db.notes.find_one({'chat_id': chat['chat_id']}): await message.reply(strings['notelist_no_notes'].format(chat_title=chat['chat_title'])) return text = strings['clear_all_text'].format(chat_name=chat['chat_title']) buttons = InlineKeyboardMarkup() buttons.add(InlineKeyboardButton(strings['clearall_btn_yes'], callback_data='clean_all_notes_cb')) buttons.add(InlineKeyboardButton(strings['clearall_btn_no'], callback_data='cancel')) await message.reply(text, reply_markup=buttons)
async def del_fed_cmd(message, fed, strings): fed_name = html.escape(fed['fed_name'], False) fed_id = fed['fed_id'] fed_owner = fed['creator'] buttons = InlineKeyboardMarkup() buttons.add(InlineKeyboardButton(text=strings['delfed_btn_yes'], callback_data=delfed_cb.new(fed_id=fed_id, creator_id=fed_owner))) buttons.add(InlineKeyboardButton(text=strings['delfed_btn_no'], callback_data=f'cancel_{fed_owner}')) await message.reply(strings['delfed'] % fed_name, reply_markup=buttons)
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'), InlineKeyboardButton(strings['btn_lang'], callback_data='lang_btn')) buttons.add(InlineKeyboardButton(strings['btn_channel'], url='https://t.me/HitsukiNews'), InlineKeyboardButton(strings['btn_source'], url='https://github.com/HitsukiNetwork/HitsukiX')) # 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 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'), InlineKeyboardButton(strings['btn_lang'], callback_data='lang_btn')) buttons.add(InlineKeyboardButton(strings['btn_chat'], url='https://t.me/BotLabTeam'), InlineKeyboardButton(strings['btn_channel'], url='https://t.me/NaoUpdates')) buttons.add(InlineKeyboardButton(strings['btn_add'], url=f'https://telegram.me/NaoTomoriRobot?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 get_missing_katas(cls, user, offset=0): conn = await asyncpg.connect(POSTGRES_URI) records = await conn.fetch( """ SELECT name, slug FROM katas WHERE id in ( SELECT id FROM katas EXCEPT SELECT kata_id FROM solved_katas WHERE user_id = $1 ) LIMIT 10 OFFSET $2; """, user.id, offset) count = await conn.fetchrow( """ SELECT COUNT(*) FROM katas WHERE id in ( SELECT id FROM katas EXCEPT SELECT kata_id FROM solved_katas WHERE user_id = $1 ); """, user.id) await conn.close() markup = InlineKeyboardMarkup() for r in records: btn = InlineKeyboardButton( text=r.get('name'), url=f"{CODEWARS_BASE_KATA_URL}/{r.get('slug')}/") markup.add(btn) buttons = [] if not count.get('count') - offset <= 10: buttons.append( InlineKeyboardButton(text='Далее', callback_data=f'next_{offset + 10}')) if offset > 0: buttons.append( InlineKeyboardButton(text='Назад', callback_data=f'next_{offset - 10}')) if buttons: markup.add(*buttons) return markup, count.get('count')
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
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)
def kb_schedule_days() -> InlineKeyboardMarkup: """Display keyboard with days of week choice.""" return InlineKeyboardMarkup(inline_keyboard=[ [ InlineKeyboardButton( DayOfWeek.EVERY.title, callback_data=cd_schedule_days.new(days=DayOfWeek.EVERY.cron), ) ], [ InlineKeyboardButton( DayOfWeek.WORK.title, callback_data=cd_schedule_days.new(days=DayOfWeek.WORK.cron), ), InlineKeyboardButton( DayOfWeek.END.title, callback_data=cd_schedule_days.new(days=DayOfWeek.END.cron), ), ], [ InlineKeyboardButton( DayOfWeek.MON.short, callback_data=cd_schedule_days.new(days=DayOfWeek.MON.cron), ), InlineKeyboardButton( DayOfWeek.TUE.short, callback_data=cd_schedule_days.new(days=DayOfWeek.TUE.cron), ), InlineKeyboardButton( DayOfWeek.WED.short, callback_data=cd_schedule_days.new(days=DayOfWeek.WED.cron), ), InlineKeyboardButton( DayOfWeek.THU.short, callback_data=cd_schedule_days.new(days=DayOfWeek.THU.cron), ), InlineKeyboardButton( DayOfWeek.FRI.short, callback_data=cd_schedule_days.new(days=DayOfWeek.FRI.cron), ), InlineKeyboardButton( DayOfWeek.SAT.short, callback_data=cd_schedule_days.new(days=DayOfWeek.SAT.cron), ), InlineKeyboardButton( DayOfWeek.SUN.short, callback_data=cd_schedule_days.new(days=DayOfWeek.SUN.cron), ), ], ])
def get_start(chat_id): strings = get_strings(chat_id, module='pm_menu') text = strings["start_hi"] buttons = InlineKeyboardMarkup() buttons.add(InlineKeyboardButton(strings["btn_help"], callback_data='get_help')) buttons.add(InlineKeyboardButton(strings["btn_lang"], callback_data='set_lang')) buttons.add( InlineKeyboardButton(strings["btn_chat"], url='https://t.me/YanaBotGrou'), InlineKeyboardButton(strings["btn_channel"], url='https://t.me/SophieNEWS'), ) return text, buttons
def DonateMarkup(chatID: str, chatType: str) -> InlineKeyboardMarkup: lang = DBH.GetSetting(chatID, "lang", chatType) isDeleteButton = DBH.GetSetting(chatID, "deleteButton", chatType) dictLang = ButtonTexts[lang] DonateMU = InlineKeyboardMarkup() DonateMU.add( InlineKeyboardButton( dictLang['donate'], url="https://secure.wayforpay.com/payment/s3641f64becae", callback_data="donate")) if isDeleteButton: DonateMU.add( InlineKeyboardButton(dictLang['delete'], callback_data="delete")) return DonateMU
def CurrenciesMainMenuMarkup(chatID: str, chatType: str) -> InlineKeyboardMarkup: lang = DBH.GetSetting(chatID, "lang", chatType) dictLang = ButtonTexts[lang] CurrenciesMainMenuMU = InlineKeyboardMarkup() CurrenciesMainMenuMU.add( InlineKeyboardButton(dictLang['cur_menu'], callback_data="cur_curmenu")) CurrenciesMainMenuMU.add( InlineKeyboardButton(dictLang['crypto_menu'], callback_data="cur_cryptomenu")) CurrenciesMainMenuMU.add( InlineKeyboardButton(dictLang['back'], callback_data="settings")) return CurrenciesMainMenuMU
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)