Вопрос:
Привет я new в stackoverflow также на python… Я хочу сделать клавиатуру (replykeyboardmarkup), которая считывает данные из базы данных и каждую кнопку на каждой строке клавиатуры, чтобы показать.
Я хочу создать пользовательскую клавиатуру в telegram.bot Например: у нас есть массив строк, которые получают из базы данных. Как мы можем передавать данные из массива в InlineKeyboardMarkup? динамичная, отзывчивая кнопка.
Что я могу сделать? thankss
Ответ №1
В API Telegram Bot они не упоминали о том, как работать с динамическим InlineKeyboardButton. Но есть способ сделать это с помощью CallbackQuery. В следующем примере предполагается, что переменная stringList будет содержать результаты запроса к базе данных, для этого я использую stringList в качестве словаря Pyton с Python 3.7 и pyTelegramBotAPI, который реализован для Telegram Bot API.
stringList = {«Name»: «John», «Language»: «Python», «API»: «pyTelegramBotAPI»}
Позвольте создавать кнопки в соответствии со списком строк, импортируя типы из telebot. Здесь callback_data выполняет List, который помогает нам передавать данные от кнопки обработчикам запросов. Существует ограничение, если ваши callback_data больше 64 байт. Telegram Bot API сгенерирует ответ BUTTON_DATA_INVALID. Пожалуйста, обратитесь к разделу Ошибки разметки, чтобы избежать подобных исключений.
markup = types.InlineKeyboardMarkup() for key, value in stringList.items(): markup.add(types.InlineKeyboardButton(text=value, callback_data=»[‘value’, ‘» + value + «‘, ‘» + key + «‘]»), types.InlineKeyboardButton(text=crossIcon, callback_data=»[‘key’, ‘» + key + «‘]»))
Ниже изображение является результатом кода выше.
Я использую этот крестик, чтобы показать вам, как удалить динамическую кнопку и как отредактировать InlineKeyboardButton, удалив эту динамическую кнопку. Как вы можете видеть (код выше), есть два CallbackQuery, которые обрабатывают первую кнопку и перекрестную кнопку.
Вы можете захватить первую кнопку callback_data в следующих строках кода.
if (call.data.startswith(«[‘value'»)): print(f»call.data : {call.data} , type : {type(call.data)}») print(f»ast.literal_eval(call.data) : {ast.literal_eval(call.data)} , type : {type(ast.literal_eval(call.data))}») valueFromCallBack = ast.literal_eval(call.data)[1] keyFromCallBack = ast.literal_eval(call.data)[2] bot.answer_callback_query(callback_query_id=call.id, show_alert=True, text=»You Clicked » + valueFromCallBack + » and key is » + keyFromCallBack)
Есть два оператора печати, чтобы точно определить, какой тип данных мы будем обрабатывать. Первый оператор print показывает нам строковый тип List, когда мы нажимаем первую кнопку John.
call.data : [‘value’, ‘John’, ‘Name’] , type : <class ‘str’>
Мы почти ближе к решению, но со строковым типом List. Я нашел решение преобразовать строковый тип List в обычный List, сославшись на ответы на этот вопрос. Python ast (Абстрактные синтаксические деревья) – это модуль, представляющий абстрактную синтаксическую структуру исходного кода. Используя ast.literal_eval(), мы можем получить следующий вывод из второго оператора print.
ast.literal_eval(call.data) : [‘value’, ‘John’, ‘Name’] , type : <class ‘list’>
Тем временем выведите это предупреждение также из-за answerCallbackQuery, который мы используем в приведенном выше коде.
Мы можем получить вывод, как это, потому что мы заполняем кнопку со списком значений. Аналогично, вы можете передать список в callback_data и обработать этот список в callback_query_handler. Давайте посмотрим, что произойдет, если щелкнуть значок крестика.
if (call.data.startswith(«[‘key'»)): keyFromCallBack = ast.literal_eval(call.data)[1] del stringList[keyFromCallBack] bot.edit_message_text(chat_id=call.message.chat.id, text=»Here are the values of stringList», message_id=call.message.message_id, reply_markup=makeKeyboard(), parse_mode=’HTML’)
Он перейдет к answerCallbackQuery, который начинается с “‘[key’”, и удалит словарь Pyton, используя заданный ключ (del stringList[keyFromCallBack]). Пусть кликнет первый крестик, посмотрим, что будет
Первая кнопка исчезнет, потому что editMessageText регенерирует с доступными деталями словаря. Вместо удаления Pyton Dictionary вы можете вызвать запрос к базе данных.
Вот полный код приведенных выше примеров.
import telebot import ast import time from telebot import types bot = telebot.TeleBot(«YOUR_BOT_API_KEY_HERE») stringList = {«Name»: «John», «Language»: «Python», «API»: «pyTelegramBotAPI»} crossIcon = u»u274C» def makeKeyboard(): markup = types.InlineKeyboardMarkup() for key, value in stringList.items(): markup.add(types.InlineKeyboardButton(text=value, callback_data=»[‘value’, ‘» + value + «‘, ‘» + key + «‘]»), types.InlineKeyboardButton(text=crossIcon, callback_data=»[‘key’, ‘» + key + «‘]»)) return markup @bot.message_handler(commands=[‘test’]) def handle_command_adminwindow(message): bot.send_message(chat_id=message.chat.id, text=»Here are the values of stringList», reply_markup=makeKeyboard(), parse_mode=’HTML’) @bot.callback_query_handler(func=lambda call: True) def handle_query(call): if (call.data.startswith(«[‘value'»)): print(f»call.data : {call.data} , type : {type(call.data)}») print(f»ast.literal_eval(call.data) : {ast.literal_eval(call.data)} , type : {type(ast.literal_eval(call.data))}») valueFromCallBack = ast.literal_eval(call.data)[1] keyFromCallBack = ast.literal_eval(call.data)[2] bot.answer_callback_query(callback_query_id=call.id, show_alert=True, text=»You Clicked » + valueFromCallBack + » and key is » + keyFromCallBack) if (call.data.startswith(«[‘key'»)): keyFromCallBack = ast.literal_eval(call.data)[1] del stringList[keyFromCallBack] bot.edit_message_text(chat_id=call.message.chat.id, text=»Here are the values of stringList», message_id=call.message.message_id, reply_markup=makeKeyboard(), parse_mode=’HTML’) while True: try: bot.polling(none_stop=True, interval=0, timeout=0) except: time.sleep(10)
Чтобы проверить этот код, введите/протестируйте команду в окне вашего бота.
Ответ №2
Если вы используете библиотеку python-telegram-bot в качестве библиотеки, вы можете посмотреть ее документацию здесь
Кроме того, если вы не используете эту библиотеку, вы можете адаптировать эту функцию к своему коду
Ответ №3
Если вы используете python-telegram-bot, в соответствии с этими фрагментами, это должно быть что-то вроде этого
>>> custom_keyboard = [[‘top-left’, ‘top-right’], … [‘bottom-left’, ‘bottom-right’]] >>> reply_markup = telegram.ReplyKeyboardMarkup(custom_keyboard) >>> bot.send_message(chat_id=chat_id, … text=»Custom Keyboard Test», … reply_markup=reply_markup)
Обратите внимание, что я не проверял код. Позвольте мне знать, если вы хотите.
Ответ №4
использовать python telegram bot
dict = {«Name»: «John», «Language»: «Python», «API»: «pyTelegramBotAPI»} buttons = [] for key, value in dice.items(): buttons.append( [InlineKeyboardButton(text = key, url = ‘google.com’)] ) keyboard = InlineKeyboardMarkup(buttons) bot.sendMessage(chat_id,text = ‘f’, reply_markup = keyboard) Ответ №5
Это использует python-telegram-bot:
Если у вас есть список городов, и вы хотите отобразить так:
def city(update,context): list_of_cities = [‘Erode’,’Coimbatore’,’London’, ‘Thunder Bay’, ‘California’] button_list = [] for each in list_of_cities: button_list.append(InlineKeyboardButton(each, callback_data = each)) reply_markup=InlineKeyboardMarkup(build_menu(button_list,n_cols=1)) #n_cols = 1 is for single column and mutliple rows bot.send_message(chat_id=update.message.chat_id, text=’Choose from the following’,reply_markup=reply_markup) def build_menu(buttons,n_cols,header_buttons=None,footer_buttons=None): menu = [buttons[i:i + n_cols] for i in range(0, len(buttons), n_cols)] if header_buttons: menu.insert(0, header_buttons) if footer_buttons: menu.append(footer_buttons) return menu
Если вам нужны пояснительные комментарии ниже!