cómo hacer que Telegram bot boton teclado dynamic en python cada botón en una fila

Hola, soy nuevo en stackoverflow también en python … Quiero hacer un botón de teclado (replykeyboardmarkup) que lea los datos de la base de datos y cada botón en cada fila del teclado para mostrar.

Quiero crear un teclado personalizado en telegram.bot Por ejemplo: tenemos una matriz de cadenas que se obtiene de la base de datos … ¿cómo podemos enviar datos de una matriz a InlineKeyboardMarkup? Botón dynamic, sensible.

que puedo hacer? gracias

En la API de Telegram Bot no mencionaron cómo tratar con InlineKeyboardButton dynamic. Pero hay una manera de hacer este tipo de cosas usando CallbackQuery . En el siguiente ejemplo, supongamos que la variable stringList retendrá los resultados de la consulta de la base de datos, para ello estoy usando stringList como un diccionario Pyton con Python 3.7 y pyTelegramBotAPI que se implementa para la API Telegram Bot .

stringList = {"Name": "John", "Language": "Python", "API": "pyTelegramBotAPI"} 

Vamos a crear botones de acuerdo a stringList importando tipos desde telebot. Aquí, callback_data cumple con una lista que nos ayuda a pasar los datos del botón a los manejadores de consultas. Hay una limitación, si su callback_data tiene más de 64 bytes, la API de Telegram Bot generará la respuesta BUTTON_DATA_INVALID . Consulte más acerca de los errores de marcado para evitar ese tipo de excepciones.

 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 + "']")) 

La imagen de abajo es el resultado del código de arriba.

Resultado del InlineKeyboardButton

Estoy usando este icono de cruz para mostrarle cómo eliminar el botón dynamic y cómo editar el botón InlineKeyboard con la eliminación de ese botón dynamic. Como puede ver (arriba del código) hay dos CallbackQuery que manejan el primer botón y el botón de cruz.

Puede capturar el callback_data del primer botón en las siguientes líneas de código.

 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) 

Hay dos declaraciones de impresión para ver exactamente qué tipo de datos vamos a manejar. La primera statement impresa nos muestra la lista de tipos de cadena cuando hacemos clic en el primer botón de John .

 call.data : ['value', 'John', 'Name'] , type :  

Estamos casi más cerca de la solución, pero con el tipo de cadena Lista. Encontré una solución para convertir la Lista de tipo de cadena en la Lista normal haciendo referencia a las respuestas de esta pregunta . Python ast (Abstract Syntax Trees) es el módulo que representa la estructura sintáctica abstracta del código fuente. Usando ast.literal_eval () podemos obtener el siguiente resultado de la segunda statement de impresión.

 ast.literal_eval(call.data) : ['value', 'John', 'Name'] , type :  

Mientras tanto, muestre esta alerta también debido a answerCallbackQuery que estamos usando en el código anterior.

Resultado de la respuestaCallbackQuery

Podemos obtener una salida como esta porque llenamos el botón con Lista de valores. Del mismo modo, puede pasar la Lista dentro de callback_data y manejar esa Lista en callback_query_handler . Echemos un vistazo a lo que sucederá cuando haga clic en el icono de la cruz.

 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') 

Irá a answerCallbackQuery que comienza con “‘[key'” y eliminará el diccionario Pyton usando la clave dada ( del stringList[keyFromCallBack] ). Hagamos clic en el icono de la primera cruz para ver qué pasará.

Regenerar botones dinámicos según la lista.

El primer botón desaparecerá porque editMessageText se regenera con los detalles del Diccionario disponibles. En lugar de eliminar el diccionario Pyton , puede llamar a alguna consulta de base de datos.

Aquí está el código completo de los ejemplos anteriores.

 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) 

Para probar este tipo de código / comando de prueba en la ventana de tu bot.

Si está utilizando python-telegram-bot como biblioteca, puede consultar la documentación aquí.

Además, si no está utilizando esa biblioteca, podría adaptar esa función en su código

Si está usando python-telegram-bot , de acuerdo con estos fragmentos , debería ser algo como esto

 >>> 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) 

Tenga en cuenta que no he comprobado el código. Déjame saber si es lo que quieres.