Динамические Inline кнопки

Пишу бота с помощью библиотеки aiogram для коммунального предприятия.

Какие есть варианты обращаться к callback_data inline кнопки, если она строится динамически? То есть название кнопки и callback берутся из БД, которая так же строится динамически. В дальнейшем действием этих кнопок будет удалением из БД.

def genmarkup(data): # передаём в функцию data


    markup = InlineKeyboardMarkup() # создаём клавиатуру
    markup.row_width = 1 # кол-во кнопок в строке
    for i in data: # цикл для создания кнопок
        
        markup.add(InlineKeyboardButton(f'Номер договора {i[0]}', callback_data=i[0])) #Создаём кнопки, i[1] - название, i[2] - callback_data
    return markup #возвращаем клавиатуру

Хендлер, где используется data

@dp.message_handler(state=new_rah.new_acc)
async def add_acc_2(message: types.Message, state: FSMContext):
    async with state.proxy() as data_fsm:
        data_fsm["new_acc"] = int(message.text)
         data =  cur.execute("select lsid from egn_cards where tg_id = (?) ", (b[0],)).fetchall()
        print(data)
        db.commit()

        await bot.send_message(
            message.from_user.id, "text", reply_markup=genmarkup(data)

Ответы (1 шт):

Автор решения: misha plotnikov

В кнопке можно передовать какие-то аргументы, как это делается: callback_data="fun_first:second". Это втсавляеться при создании кнопки, прижелании аргументов можно добавить или убавить. Эти аргументы можно вытаскивать в функции.

@dp.callback_query_handler(lambda call: call.data.startswith('fun_'))
async def fun(call: types.CallbackQuery):
    First, second = call.data.replace('fun_', '', 1).split(':') 

К чему это я. Мы можем создать одну функцию, допустим с названием func_ .

callback_data = f"func_{i[0]}

Это нужно записать в кнопку, там где вы создаёте клавиатуру

Дальше всё просто! Вытащим аргумент, который мы передали

@dp.callback_query_handler(lambda call: call.data.startswith('func_'))
async def fun(call: types.CallbackQuery):
    Fun_name = call.data.replace('func_', '', 1).split(':')[0]

В Fun_name я записал то назывние, через котоое вы хотели обращаться к функции(и записывали это в бд). Дальше просто нужно сделать условие. Как пример приведу ниже

@dp.callback_query_handler(lambda call: call.data.startswith('func_'))
async def fun(call: types.CallbackQuery):
    Fun_name = call.data.replace('func_', '', 1).split(':')[0]
    Bd_key1 = 'k1'
    Bd_key2 = 'k2'  
    if Fun_name == Bd_key1:
        print('действие один')
    elif Fun_name == Bd_key2:
        print('действие 2')

В переменные Bd_key1 и Bd_key2 я записал названия(представим, что из вашей бд), дальше через условаия я уже определяю какой действие мне нужно выполнить.

UPD: когда мы вытаскиваем значение, мы его получаем в Str формате. Тоесть Fun_name это у нас String.

Если остались вопросы, с удовольствием отвечу в коментариях

→ Ссылка