Ошибка связанная с Message.delete() в aiogram
Идея кода: при "/start" бота выводится сообщение с инлайн кнопкой, при нажатии, то же сообщение удаляется
from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
from aiogram.types import ReplyKeyboardRemove, ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton, Message
bot = Bot(token='Токен бота')
dp = Dispatcher(bot)
inline_btn_1 = InlineKeyboardButton('Любой текст', callback_data='button1')
func = lambda c: c.data == 'button1'
@dp.callback_query_handler(func)
async def process_callback_button1(callback_query: types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await Message.delete(dlt_msg)
@dp.message_handler(commands = ['start'])
async def start(message : types.Message):
global dlt_msg
dlt_msg = message.reply('Любой текст', reply_markup=inline_kb1)
await dlt_msg
if __name__ == '__main__':
executor.start_polling(dp)
Ошибка, возникающая при попытке нажать на кнопку:
'coroutine' object has no attribute 'bot'
И сразу два вопроса:
- Откуда взялся объект
coroutine? - И почему у него должен быть атрибут
bot?
Если мыслей на счёт первого нет вообще, то вот на счёт второго я пошёл в саму библиотеку aiogram и смотреть что там, да как...
И обнаружил вот такой код в классе message:
async def delete(self) -> base.Boolean:
return await self.bot.delete_message(self.chat.id, self.message_id)
Ииииииии ничего не понял, во-первых почему тот объект, который мы посылаем в метод должен стоять выше по иерархии bot'а? Ведь я хочу удалить сообщение, а оно является частью message, а он частью types, а он уже как раз наравне с bot, разве нет? Во-вторых, по аналогии непонятки с агрументами внутри delete_message
(P.S. в классе chat есть метод delete_message чем он отличается от delete_message в классе bot? И в чем разница их обоих от delete в классе message?)
Ответы (2 шт):
Потому что надо не
await Message.delete(dlt_msg)
А вот так
await callback_query.message.delete()
А вообще, то что вы сделали какой-то ужас. Вы можете убрать кучу лишнего кода.
# пожалуйста забудьте про лямбда функции, используйте их реже, в большинстве случаев можно сделать так, текст это фильтр для той самой колбек даты, а в случае месседж хендлера - для текста сообщения
@dp.callback_query_handler(text="button1")
async def process_callback_button1(callback_query: types.CallbackQuery):
# я думаю это более лаконичный способ
await callback_querry.answer()
# в callback_query.message сейчас то сообщение инлайн клавиатура которого была нажата, поэтому никикие глобальные переменные нам не нужны
await callback_query.message.delete()
@dp.message_handler(commands = ['start'])
async def start(message : types.Message):
await message.reply('Любой текст', reply_markup=inline_kb1)
#Создаем собственно кнопку для удаление сообщения
btn_send_delete = InlineKeyboardButton('Удалить', callback_data='message_delete')
btn_send_markup = InlineKeyboardMarkup().add(btn_send_delete)
#Реагируем на команду /start, при этом выводим сообщение с инлайн кнопкой
@dp.message_handler(commands='start')
async def del_mes(message: types.Message):
await bot.send_message(message.chat.id, 'test', reply_markup=btn_send_markup)
#Если нажимаем на кнопку - удаляется сообщение.
@dp.callback_query_handler(lambda c: c.data == 'message_delete')
async def send_msg_to_user(callback_query: types.CallbackQuery):
await callback_query.answer('Удалено')
await bot.delete_message(callback_query.message.chat.id, callback_query.message.message_id)