Кнопки в inlinekeyboard с длинным текстом
Столкнулся со следующей проблемой. Формирую список продуктов, который записывается БД и в боте можно вызвать inline клавиатуру, где каждый продукт на отдельной кнопке для дальнейшего редактирования/удаления. Но при добавлении длинного текста (в БД он добавляется корректно) и вызове клавиатуры получаю Bad Request: BUTTON_DATA_INVALID. Читал в документации, что callback_data - 1-64 байта, но сталкивался с ботами, где при добавлении подобных текстов все работает.
Пример клавиатуры:
Ниже код для "вычеркивания" продукта из списка:
elif 'edit_product' in call.data:
product = call.data.replace('edit_product ', '')
if '✖ ' in product:
for i in range(len(list_of_products)):
if list_of_products[i] == product:
list_of_products[i] = product.replace('✖ ', '')
db.db_update_call(call, list_of_products)
# show alert
clear_product = product.replace('✖ ', '')
bot.answer_callback_query(callback_query_id=call.id, show_alert=False, text=f'{clear_product} unticked')
else:
cross_product = '✖ ' + product
for i in range(len(list_of_products)):
if list_of_products[i] == product:
list_of_products[i] = cross_product
db.db_update_call(call, list_of_products)
# show alert
bot.answer_callback_query(callback_query_id=call.id, show_alert=False, text=f'{product} ticked')
keyboard = types.InlineKeyboardMarkup(row_width=2)
products = []
for product in list_of_products:
btn = types.InlineKeyboardButton(text=f'{product}', callback_data=f'edit_product {product}')
products.append(btn)
btn1 = types.InlineKeyboardButton(text='⬅', callback_data='back')
btn2 = types.InlineKeyboardButton(text='?', callback_data='delete')
keyboard.add(*products)
keyboard.add(btn1, btn2)
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id,
reply_markup=keyboard)
Ответы (1 шт):
Благодаря советам gil9red реализовал так:
elif 'edit_product' in call.data:
product_id = call.data.replace('edit_product ', '')
if '✖ ' in dict_lop[product_id]:
for i in range(len(list_of_products)):
if list_of_products[i] == dict_lop[product_id]:
list_of_products[i] = dict_lop[product_id].replace('✖ ', '')
dict_lop = {str(product_id): product for product_id, product in
enumerate(list_of_products, 1)}
db.db_update_call(call, list_of_products)
# show alert
clear_product = dict_lop[product_id].replace('✖ ', '')
bot.answer_callback_query(callback_query_id=call.id, show_alert=False, text=f'{clear_product} unticked')
else:
cross_product = '✖ ' + dict_lop[product_id]
for i in range(len(list_of_products)):
if list_of_products[i] == dict_lop[product_id]:
list_of_products[i] = cross_product
dict_lop = {str(product_id): product for product_id, product in
enumerate(list_of_products, 1)}
db.db_update_call(call, list_of_products)
# show alert
bot.answer_callback_query(callback_query_id=call.id, show_alert=False,
text=f'{dict_lop[product_id]} ticked')
keyboard = types.InlineKeyboardMarkup(row_width=2)
products = []
for product_id, product in dict_lop.items():
btn = types.InlineKeyboardButton(text=f'{product}', callback_data=f'edit_product {product_id}')
products.append(btn)
btn1 = types.InlineKeyboardButton(text='⬅', callback_data='back')
btn2 = types.InlineKeyboardButton(text='?', callback_data='delete')
keyboard.add(*products)
keyboard.add(btn1, btn2)
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id,
reply_markup=keyboard)
Первое время просто в самом начале @bot.callback_query_handler формировал словарь dict_lop на основе данных из БД, но получал ошибку Bad Request: message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message". Поэтому решил обновлять словарь после каждого обновления БД. (не знаю на сколько это корректно, но работает), если у вас есть предложения по оптимизации буду рад их прочитать.
