Задать вопрос
@Arniss472

Как в aiogram получить доступ к тому сообщению, к которому привязана inline кнопка?

В общем пишу бота с использованием библиотеки aiogram, изначально реализовал все функции при помощи команд, теперь решил некоторые из функций реализовать при помощи inlaine кнопок.

Возможно важно отметить, что регистрирую хэндлеры я отдельно.

Здесь код обработчика команды 'list', которая парсит БД и выводит записи, у каждой записи есть свой id, по которому производятся те или иные операции с ними и к каждой записи я прикрутил эти самые inline кнопки.
spoiler

from aiogram import Dispatcher, types
from ..base import get_list_tasks, del_task


def get_keyboard():
    buttons: list = [
        types.InlineKeyboardButton(text='Редактировать', callback_data='edit'),
        types.InlineKeyboardButton(text='Удалить', callback_data='del')
    ]
    keyboard = types.InlineKeyboardMarkup(row_width=2)
    keyboard.add(*buttons)
    return keyboard


async def list_tasks(message: types.Message):
    keyboard = get_keyboard()
    user_id: int = message.from_user.id
    lt: list = get_list_tasks(user_id)
    if len(lt) == 0:
        await message.answer('Ни одного таска ещё не создано.')
    else:
        for task in lt:
            await message.answer(f'{task[0]}\n\n{task[1]}\n\nid: {task[-1]}', reply_markup=keyboard)


async def inline_del_handler(call: types.CallbackQuery, message: types.Message):
    # метод заглушка
    pass 


def register_handlers_list_task(dp: Dispatcher, admin_id: int):
    dp.register_message_handler(list_tasks, commands=['list'])



Вот код изначальной команды edit:
spoiler

from aiogram import Dispatcher, types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from Tasker_bot.app.base import edit_task


class StateEdit(StatesGroup):
    edit_id = State()
    edit_title = State()
    edit_body = State()


async def editing_start(message: types.Message):
    await message.answer('Введите id редактируемого таска:')
    await StateEdit.edit_id.set()


async def editing_title(message: types.Message, state: FSMContext):
    await state.update_data(id=message.text)
    await StateEdit.next()
    await message.answer('Введите новый заголовок:')


async def editing_body(message: types.Message, state: FSMContext):
    await state.update_data(title=message.text)
    await StateEdit.next()
    await message.answer('Введите новый текст:')


async def editing_task(message: types.Message, state: FSMContext):
    await state.update_data(body=message.text)
    task_edit: dict = await state.get_data()
    try:
        edit_id: int = int(task_edit['id'])
        title: str = task_edit['title']
        body: str = task_edit['body']
        edit_task(edit_id, title, body)
        await message.answer('Запись успешно отредактирована.')

    except ValueError:
        await message.answer('id может содержать только цифры.')

    finally:
        await state.finish()


def register_handler_edit_task(dp: Dispatcher):
    dp.register_message_handler(editing_start, commands='edit', state='*')
    dp.register_message_handler(editing_title, state=StateEdit.edit_id)
    dp.register_message_handler(editing_body, state=StateEdit.edit_title)
    dp.register_message_handler(editing_task, state=StateEdit.edit_body)



В общем вопрос:
1. Как вытащить id той записи, с которой сработала кнопка?
2. Как передать этот id другому хэндлеру?

Спасибо.
  • Вопрос задан
  • 1583 просмотра
Подписаться 1 Простой 3 комментария
Решения вопроса 1
@twistfire92
Python backend developer
Когда зарегистрируешь метод, который будет запускать цепочку действий для редактирования поста, в этот метод будешь передавать параметр call с типом CallbackQuery. Этот параметр содержит данные, которые ты поместил в кнопку (call.data), а также объект самого сообщения (call.message).

Но насколько я понял, тебе не особо то и нужно это сообщение. Ты можешь немного видоизменить функцию get_keyboard()

def get_keyboard(id: str):
    buttons: list = [
        types.InlineKeyboardButton(text='Редактировать', callback_data=f'edit|{id}'),
        types.InlineKeyboardButton(text='Удалить', callback_data=f'del|{id}')
    ]
    keyboard = types.InlineKeyboardMarkup(row_width=2)
    keyboard.add(*buttons)
    return keyboard

.....

async def list_tasks(message: types.Message):
    user_id: int = message.from_user.id
    lt: list = get_list_tasks(user_id)
    if len(lt) == 0:
        await message.answer('Ни одного таска ещё не создано.')
    else:
        for task in lt:
            id = task[-1] # Ну или под каким индексом тут должен скрываться ID записи? Скорректируешь
            await message.answer(f'{task[0]}\n\n{task[1]}\n\nid: {task[-1]}', reply_markup=get_keyboard(id))


теперь туда передается ID нужной записи и при нажатии на кнопку вы просто парсите команду и ID записи в БД:
command, id = call.data.split('|')

а дальше уже думаю понятно
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы