Есть код с помощью которого бот отправляет фото пользователю вместе с подписью и Inline клавиатурой, после необходимо изменить в ранее отправленном сообщении Inline клавиатуру и подпись, как это можно сделать?
Код с помощью которого отправляю фото пользователям:
x = await bot.send_photo( chat_id=userId, photo=image, caption=message_text, reply_markup=keyboard, parse_mode=’MarkdownV2′ )
Код с помощью которого пытаюсь изменить подпись и клавиатуру ранее отправленного сообщения:
x = await bot.edit_message_media( media=image, chat_id=call.message.chat.id, message_id=lastBotWordMessageId, caption=answerCheckMessage, reply_markup=answerCheckKeyboard )
Также хотел бы, чтобы вы отправили пример кода по изменению простого сообщения без фото, но с подписью и Inline клавиатурой.
Ответы (2 шт):
Чтобы отредактировать подпись и Inline клавиатуру под фото:
x = await bot.edit_message_caption( chat_id=call.message.chat.id, message_id=lastBotWordMessageId, caption=answerCheckMessage, reply_markup=answerCheckKeyboard )
Для изменения caption Вы можете передать в Ваш InputMedia объект параметр caption . Вот Вам небольшой пример:
ПЕРЕСЛАТЬ СООБЩЕНИЕ В КАНАЛ ► AIOGram в телеграм канал
Сообщение при вызове команды:
Сообщение при нажатии на кнопку:
Источник: husl.ru
Как отредактировать сообщение с помощью aiogram?
Выдает ошибку aiogram.utils.exceptions.MessageCantBeEdited: Message can’t be edited
Что значит не может быть изменено.
Я понимаю если бы сообщению было больше 48 часов, но оно существует 30 секунд всего.
Причем точно такой же кусок у меня исправно работает в другом боте.
В интернетах ответа нет, в документации про это ничего не говорится. Помогите решить)
- Вопрос задан более двух лет назад
- 14516 просмотров
Комментировать
Решения вопроса 0
Ответы на вопрос 2
Редактировать можно всегда сообщения, надо чтобы правильно подходили айди чата и сообщения, в аиограме для этого есть специальные методы, которые упрощают жизнь, но можно и по старинке.
В телеграме никогда не было ограничений на редактирования только сообщения с кнопками.
Ниже пример с редактированием сообщения через 3 минуты
Please note, that it is currently only possible to edit messages without reply_markup or with inline keyboards.
Источник: qna.habr.com
Сообщения Aiogram
Рассылка сообщений через Телеграм Бота | Python — Aiogram
В этой главе мы разберёмся, как применять различные типы форматирования к сообщениям и работать с медиафайлами.
Текст
Обработка текстовых сообщений — это, пожалуй, одно из важнейших действий у большинства ботов. Текстом можно выразить практически что угодно и при этом подавать информацию хочется красиво. В распоряжении у разработчика имеется три способа разметки текста: HTML, Markdown и MarkdownV2. Наиболее продвинутыми из них считаются HTML и MarkdownV2, «классический» Markdown поддерживает меньше возможностей и более не используется в aiogram.
Прежде, чем мы рассмотрим способы работы с текстом в aiogram, необходимо упомянуть важное отличие aiogram 3.x от 2.x: в «двойке» по умолчанию обрабатывались только текстовые сообщения, а в «тройке» — любого типа. Если точнее, вот как теперь надо принимать исключительно текстовые сообщения:
Форматированный вывод
За выбор форматирования при отправке сообщений отвечает аргумент parse_mode , например:
Если в боте повсеместно используется определённое форматирование, то каждый раз указывать аргумент parse_mode довольно накладно. К счастью, в aiogram можно передать необходимый тип прямо в объект Bot, а если в каком-то конкретном случае нужно обойтись без этих ваших разметок, то просто укажите parse_mode=None :
bot = Bot(token=»123:abcxyz», parse_mode=»HTML») # где-то в функции. await message.answer(«Сообщение с HTML-разметкой») await message.answer(«Сообщение без какой-либо разметки», parse_mode=None)
Нередко бывают ситуации, когда окончательный текст сообщения бота заранее неизвестен и формируется исходя из каких-то внешних данных: имя пользователя, его ввод и т.д. Напишем хэндлер на команду /name , который будет отвечать пользователю текстом, указанным после команды, например, /name Иван Иванов :
Почему мы не воспользовались просто message.text ? В противном случае бот бы ответил: “Привет, /name Иван Иванов”, а нам нужен только текст после команды. Если вы используете встроенный фильтр Command (или его алиас commands, как в примере выше), то можно добавить в хэндлер аргумент command с типом CommandObject , и достать оттуда текст после команды, который aiogram уже распарсил за вас. Если после команды ничего не указано, то command.args будет иметь значение None .
И, вроде бы, всё хорошо, но тут приходит хитрый юзер и пишет /name . В этом случае бот не ответит, а в консоли появится ошибка:
aiogram.exceptions.TelegramBadRequest: Bad Request: can’t parse entities: Unsupported start tag «славик777» at byte offset 17
Что же делать? К счастью, проблема решается просто: экранированием. Для этого в модуле html (в markdown аналогично) есть метод quote() для экранирования, а также различные методы для форматирования: bold() , italic() , link() и т.д.
Исправим код, чтобы всё заработало:
# новый импорт! from aiogram import html # В функции cmd_name await message.answer(f»Привет, «, parse_mode=»HTML»)
Сохранение форматирования
Представим, что бот должен получить форматированный текст от пользователя и добавить туда что-то своё, например, отметку времени. Напишем простой код:
Мда, что-то пошло не так, почему сбилось форматирование исходного сообщения? Это происходит из-за того, что message.text возвращает просто текст, без каких-либо оформлений. Чтобы получить текст в нужном форматировании, воспользуемся альтернативными свойствами: message.html_text или message.md_text . Сейчас нам нужен первый вариант. Заменяем в примере выше message.text на message.html_text и получаем корректный результат:
Работа с entities
Telegram, на самом деле, очень много обработки делает вместо пользователя, сильно упрощая жизнь. Например, некоторые сущности, типа e-mail, номера телефона, юзернейма и др. можно не доставать регулярными выражениями, а извлечь напрямую из объекта Message и поля entities , содержащего массив объектов типа MessageEntity. В качестве примера напишем хэндлер, который извлекает ссылку, e-mail и моноширинный текст из сообщения (по одной штуке).
Здесь кроется важный подвох. Telegram возвращает не сами значения, а их начало в тексте и длину. Более того, текст считается в символах UTF-8, а entities работают с UTF-16, из-за этого, если просто взять позицию и длину, то при наличии UTF-16 символов (например, эмодзи) ваш обработанный текст просто съедет.
Лучше всего это демонстрирует пример ниже. На скриншоте первый ответ бота есть результат парсинга «в лоб», а второй — результат применения аиограмного метода extract() над entity. На вход ему передаётся весь исходный текст:
Медиафайлы
Помимо обычных текстовых сообщений Telegram позволяет обмениваться медиафайлами различных типов: фото, видео, гифки, геолокации, стикеры и т.д. У большинства медиафайлов есть свойства file_id и file_unique_id . Первый можно использовать для повторной отправки одного и того же файла много раз, причём отправка будет мгновенной, т.к. сам файл уже лежит на серверах Telegram. Это самый предпочтительный способ.
К примеру, следующий код заставит бота моментально ответить пользователю той же гифкой, что была прислана:
В отличие от file_id , идентификатор file_unique_id нельзя использовать для повторной отправки или скачивания медиафайла, но зато он одинаковый у всех ботов для конкретного медиа. Нужен file_unique_id обычно тогда, когда нескольким ботам требуется знать, что их собственные file_id односятся к одному и тому же файлу.
Помимо переиспользования для отправки, бот может скачать медиа к себе на компьютер/сервер. Для этого у объекта типа Bot есть метод download() . В примерах ниже файлы скачиваются сразу в файловую систему, но никто не мешает вместо этого сохранить в объект BytesIO в памяти, чтобы передать в какое-то приложение дальше (например, pillow).
В случае с изображениями мы использовали не message.photo , а message.photo[-1] , почему? Фотографии в Telegram в сообщении приходят сразу в нескольких экземплярах; это одно и то же изображение с разным размером. Соответственно, если мы берём последний элемент (индекс -1), то работаем с максимально доступным размером фото.
Сервисные (служебные) сообщения
Сообщения в Telegram делятся на текстовые, медиафайлы и служебные (они же — сервисные). Настало время поговорить о последних.
Несмотря на то, что они выглядят необычно и взаимодействие с ними ограничено, это всё ещё сообщения, у которых есть свои айдишники и даже владелец. Стоит отметить, что спектр применения сервисных сообщений с годами менялся и сейчас, скорее всего, ваш бот с ними работать не будет, либо только удалять.
Не будем сильно углубляться в детали и рассмотрим один конкретный пример: отправка приветственного сообщения вошедшему участнику. У такого служебного сообщения будет content_type равный “new_chat_members”, но вообще это объект Message, у которого заполнено одноимённое поле.
Важно помнить, что message.new_chat_members является списком, потому что один пользователь может добавить сразу нескольких участников. Также не надо путать поля message.from_user и message.new_chat_members . Первое — это субъект, т.е. тот, кто совершил действие. Второе — это объекты действия. Т.е. если вы видите сообщение вида «Анна добавила Бориса и Виктора», то message.from_user — это информация об Анне, а список message.new_chat_members содержит информацию о Борисе с Виктором.
Бонус: прячем ссылку в тексте
Бывают ситуации, когда хочется отправить длинное сообщение с картинкой, но лимит на подписи к медиафайлам составляет всего 1024 символа против 4096 у обычного текстового, а вставлять внизу ссылку на медиа — выглядит некрасиво. Более того, когда Telegram делает предпросмотр ссылок, он берёт первую из них и считывает метатеги, в результате сообщение может отправиться не с тем превью, которое хочется увидеть.
Для решения этой проблемы ещё много лет назад придумали подход со «скрытыми ссылками» в HTML-разметке. Суть в том, что можно поместить ссылку в пробел нулевой ширины и вставить всю эту конструкцию в начало сообщения. Для наблюдателя в сообщении никаких ссылок нет, а сервер Telegram всё видит и честно добавляет предпросмотр.
Разработчики aiogram для этого даже сделали специальный вспомогательный метод hide_link() :
Источник: aiogram.ru