Перейти к содержимому

Aiogram как удалить сообщение бота

  • автор:

Bot API v3. Автоматизируем работу в группах

⁠⁠ С момента публикации предыдущего урока и по состоянию на момент написания этого, Telegram выпустил одно крупное обновление Bot API (3.0), а также несколько мелких (3.1-3.3). Сразу отмечу, ни отправка видеосообщений, ни платежи (по ним есть отличный пример в репозитории pyTelegramBotAPI), ни работа со стикерами рассмотрены не будут.

Удаляем сообщения

Начнём с того, что научим нашего бота в группе удалять сообщения, в которых есть ссылки. Добавим бота в группу и назначим его администратором с правом удаления и блокировки (пригодится позже).

Выдача прав боту

Дабы избежать неприятных ситуаций, нам необходимо определить две вещи: в какой именно группе он будет удалять сообщения и как отличить сообщения с ссылками от всех остальных? Для начала узнаем и запишем куда-нибудь ID нашей группы. А что делать с ссылками? Неужели нам придётся использовать регулярные выражения, создавая себе ещё одну проблему? Конечно, нет! Все «особые» элементы, будь то ссылки, @юзернеймы, команды ботов и т.д. складываются в массив entities в объекте Message , нам остаётся лишь проверить тип объекта и решить, удалять конкретное сообщение или нет. За последнее отвечает метод delete_message , принимающий на вход два аргумента: ID чата и ID сообщения.

Перейдём непосредственно к коду. Дабы упростить себе жизнь, зададим нужные условия срабатывания (нужный ID чата и непустой массив entities) сразу в хэндлер, это сэкономит нам несколько лишних проверок.

GROUP_ID = -10012345 # Ваш ID группы @bot.message_handler(func=lambda message: message.entities is not None and message.chat.id == GROUP_ID) def delete_links(message): for entity in message.entities: # Пройдёмся по всем entities в поисках ссылок # url - обычная ссылка, text_link - ссылка, скрытая под текстом if entity.type in ["url", "text_link"]: # Мы можем не проверять chat.id, он проверяется ещё в хэндлере bot.delete_message(message.chat.id, message.message_id) else: return 

Запустим бота и попробуем отправить сообщение с ссылкой. Если вы всё сделали правильно, оно мгновенно исчезнет и в разделе «Недавние действия» (Recent Actions) появится запись об удалённом сообщении.

Сообщение удалено

Точно так же можно сделать удаление чего угодно: стикеров, репостов из неугодных каналов, матерных сообщений и т.д. Возможности (почти) безграничны!

Read-Only и прочие «мягкие» наказания

Представьте, что у вас есть группа, например, “Международный клуб любителей мяса”, в котором люди на разных языках делятся своими впечатлениями от поедания свинины, говядины, баранины и т.д.
Конечно, время от времени в чатик будут приходить вегетарианцы и высказывать недовольство, но так как мы терпеливые люди, не будем банить веганов, а просто запретим им писать сообщения некоторое время, дабы они успокоились и вели дискуссию в рамках тематики чата. Усложним себе задачу и будем оповещать пользователей о временном ограничении прав, исходя из их языковой принадлежности.

Начиная с Telegram 4.1, у администраторов групп появилась возможность точечно настраивать права и ограничения пользователей. В Bot API за операцию ограничения ответственен метод restrict_chat_member , принимающий на вход ID чата, ID юзера, список ограничений, а также параметр until_date со значением времени (Unix Time), до которого эти ограничения действуют, причём если указать время с разницей меньше 30 секунд или больше 366 дней от текущего, Telegram воспринимает это, как «навсегда». В нашем случае Read-Only режим будет выдаваться на 10 минут, т.е. 600 секунд.

Давайте теперь разберёмся, на каком языке отвечать пользователю. В объекте User есть поле language_code , содержащее языковую метку пользователя. Не всё так просто, ведь в зависимости от настроек системы и местоположения пользователя, его языковая метка может быть ru , en-GB , en-US или вообще какой-нибудь nan-Hant-TW . Подробно о строении таких меток можно прочесть здесь. В нашем случае задача немного упрощается, т.к. нам нужен только первый элемент (сам язык), независимо от региона (будем считать, к примеру, что «английский» английский и американский английский для нас одинаковы). Напишем наипростейшую определялку языка, которая будет возвращать ru для русского языка и en для всех остальных. В реальной жизни, конечно, стоит сделать поддержку большего числа языков.

def get_language(lang_code): # Иногда language_code может быть None if not lang_code: return "en" if "-" in lang_code: lang_code = lang_code.split("-")[0] if lang_code == "ru": return "ru" else: return "en" 

И подготовим небольшой JSON со строками:

strings = < "ru": < "ro_msg": "Вам запрещено отправлять сюда сообщения в течение 10 минут." >, "en": < "ro_msg": "You're not allowed to send messages here for 10 minutes." > 

Теперь напишем обработчик, который будет реагировать на набор фраз, выдавать режим Read-Only пользователю на 10 минут и уведомлять его на родном языке. Не забудьте импортировать метод time из одноимённого модуля!

restricted_messages = ["я веган", "i am vegan"] # Выдаём Read-only за определённые фразы @bot.message_handler(func=lambda message: message.text and message.text.lower() in restricted_messages and message.chat.id == GROUP_ID) def set_ro(message): bot.restrict_chat_member(message.chat.id, message.from_user.id, until_date=time()+600) bot.send_message(message.chat.id, strings.get(get_language(message.from_user.language_code)).get("ro_msg"), reply_to_message_id=message.message_id) 

Запустим бота и попросим людей с разными language_code выступить в роли противников мяса:

Бот-полиглот

Заключение

В этом уроке мы кратко ознакомились с новыми фишками третьей версии Telegram Bot API, научились удалять сообщения, если они соответствуют одному из заданных критериев и научились «мягко» ограничивать пользователей, не удаляя их из группы. Помимо restrict_chat_member существует метод promote_chat_member для наделения пользователя определёнными администраторскими правами, он остаётся для самостоятельного изучения.

Исходный код бота этого урока, как обычно, расположен на Github.

Обновление и удаление сообщений, отправленных ботом

Примеры кода в этом разделе основаны на версии 4.6 и более поздних версиях пакета SDK Bot Framework. Если вы ищете документацию по более ранним версиям, см. раздел пакет SDK для ботов версии 3 в папке Устаревшие пакеты SDK документации.

Бот может динамически обновлять сообщения после их отправки, а не сохранять их в виде статических снимков данных. Сообщения также можно удалить с помощью метода DeleteActivity Bot Framework.

Обновление сообщений

Вы можете использовать динамические обновления сообщений для таких сценариев, как обновления опроса, изменение действий, доступных после нажатия кнопки, или любое другое асинхронное изменение состояния.

Новое сообщение не обязательно должно совпадать по типу с исходным. Например, если исходное сообщение содержит вложение, новое сообщение может быть простым текстовым сообщением.

  • C#
  • TypeScript
  • Python
  • REST API
  • Справочные материалы для SDK
  • Пример справочника по коду

Чтобы обновить существующее сообщение, передайте новый объект Activity с существующим идентификатором действия в метод UpdateActivityAsync класса TurnContext .

// Send initial message var response = await turnContext.SendActivityAsync(MessageFactory.Attachment(card.ToAttachment()), cancellationToken); var activityId = response.Id; // Fetch activity id. // MessageFactory.Text(): Specifies the type of text data in a message attachment. var newActivity = MessageFactory.Text("The new text for the activity"); newActivity.Id = activityId; // UpdateActivityAsync(): A method that can participate in update activity events for the current turn. await turnContext.UpdateActivityAsync(newActivity, cancellationToken); 
  • Справочные материалы для SDK
  • Пример справочника по коду

Чтобы обновить существующее сообщение, передайте новый объект Activity с существующим идентификатором действия в метод updateActivity объекта TurnContext .

// Send initial message var message = await context.sendActivity(""); var activityId = message.id; // Fetch activity id. // MessageFactory.Text(): Specifies the type of text data in a message attachment. const newActivity = MessageFactory.text('The new text for the activity'); newActivity.id = activityId; // A method that can participate in update activity events for the current turn. await turnContext.updateActivity(newActivity); 
  • Справочные материалы для SDK
  • Пример справочника по коду

Чтобы обновить существующее сообщение, передайте новый объект Activity с существующим идентификатором действия в метод update_activity класса TurnContext .

# Send initial message message = await turn_context.send_activity("") activityId = message.id # Fetch activity id. # MessageFactory.Text(): Specifies the type of text data in a message attachment. new_activity = MessageFactory.text("The new text for the activity") new_activity.id = activity_id # A method that can participate in update activity events for the current turn. update_result = await context.update_activity(new_activity) 

Вы можете разрабатывать приложения Teams с помощью любой технологии веб-программирования и напрямую вызывать REST API службы соединителя ботов. Для этого вам необходимо реализовать процедуры безопасности Проверки подлинности безопасности с вашими запросами API.

Чтобы обновить существующее действие в беседе, включите conversationId и activityId в конечную точку запроса. Чтобы выполнить этот сценарий, вы должны кэшировать идентификатор действия, возвращенный исходным почтовым вызовом.

PUT /v3/conversations//activities/
Запрос Отклик
Объект Действия. Объект ResourceResponse.

Теперь, когда вы обновили сообщения, обновите существующую карточку при выборе кнопки для входящих действий.

Обновить карточки

Чтобы обновить существующую карточку при выборе кнопки, вы можете использовать ReplyToId входящую активность.

  • C#
  • TypeScript
  • Python
  • REST API
  • Справочные материалы для SDK
  • Пример справочника по коду

Чтобы обновить существующую карточку при выборе кнопки, передайте новый объект Activity с обновленной карточкой и ReplyToId как идентификатор действия для метода UpdateActivityAsync класса TurnContext .

// Returns a message activity that contains an attachment. var activity = MessageFactory.Attachment(card.ToAttachment()); activity.Id = turnContext.Activity.ReplyToId; // A method that can participate in update activity events for the current turn. await turnContext.UpdateActivityAsync(activity, cancellationToken); 
  • Справочные материалы для SDK
  • Пример справочника по коду

Чтобы обновить существующую карточку при выборе кнопки, передайте новый объект Activity с обновленной карточкой и replyToId как идентификатор действия для метода updateActivity объекта TurnContext

// MessageFactory.attachment(): Returns a message activity that contains an attachment. const message = MessageFactory.attachment(card); message.id = context.activity.replyToId; // updateActivity(): A method that can participate in update activity events for the current turn. await context.updateActivity(message); 
  • Справочные материалы для SDK
  • Пример справочника по коду

Чтобы обновить существующую карточку при нажатии кнопки, передайте новый объект Activity с обновленной карточкой и reply_to_id как идентификатор действия для метода update_activity класса TurnContext .

# MessageFactory.attachment(): Returns a message activity that contains an attachment. updated_activity = MessageFactory.attachment(CardFactory.hero_card(card)) updated_activity.id = turn_context.activity.reply_to_id # update_activity(): A method that can participate in update activity events for the current turn. await turn_context.update_activity(updated_activity) 

Вы можете разрабатывать приложения Teams с помощью любой технологии веб-программирования и напрямую вызывать REST API службы соединителя ботов. Для этого вам необходимо реализовать процедуры безопасности Проверки подлинности безопасности с вашими запросами API.

Чтобы обновить существующее действие в беседе, включите conversationId и activityId в конечную точку запроса. Чтобы выполнить этот сценарий, вы должны кэшировать идентификатор действия, возвращенный исходным почтовым вызовом.

PUT /v3/conversations//activities/
Запрос Отклик
Объект Действия. Объект ResourceResponse.

Теперь, когда у вас есть обновленные карточки, вы можете удалять сообщения с помощью Bot Framework.

Удаление сообщений

В Bot Framework каждое сообщение имеет уникальный идентификатор действия. Сообщения можно удалить с помощью метода DeleteActivity Bot Framework.

  • C#
  • TypeScript
  • Python
  • REST API
  • Справочные материалы для SDK
  • Пример справочника по коду

Чтобы удалить сообщение, передайте идентификатор этого действия методу DeleteActivityAsync класса TurnContext .

foreach (var activityId in _list) < // When overridden in a derived class, deletes an existing activity in the conversation. await turnContext.DeleteActivityAsync(activityId, cancellationToken); >
  • Справочные материалы для SDK
  • Пример справочника по коду

Чтобы удалить сообщение, передайте идентификатор этого действия методу deleteActivity объекта TurnContext .

for (let i = 0; i < activityIds.length; i++) < // deleteActivity(): deletes an existing activity in the conversation. await turnContext.deleteActivity(activityIds[i]); >
  • Справочные материалы для SDK
  • Пример справочника по коду

Чтобы удалить это сообщение, передайте идентификатор этого действия методу delete_activity объекта TurnContext .

for each activity_id in _list: # delete_activity(): deletes an existing activity in the conversation. await TurnContext.delete_activity(activity_id) 

Чтобы удалить существующее действие в беседе, включите conversationId и activityId в конечную точку запроса.

DELETE /v3/conversations//activities/
Запрос и отклик Описание
Недоступно Код состояния HTTP, указывающий результат операции. В тексте отклика ничего не указано.

Пример кода

В следующем образце кода демонстрируются основы бесед.

Название примера Описание .NET Node.js Python Манифест
Основы бесед в Teams В этом примере показано, как использовать различные события бесед бота, доступные в bot framework версии 4 для личных и командных область. Просмотр Просмотр Просмотр Просмотр

Следующий этап

См. также

  • Создание ботов для Teams
  • Основы разговора
  • Карточки

Как удалить предыдущее сообщение Aiogram

При нажатии отправляется ссылка на статью в telegraph. При нажатии еще раз на кнопку (ту же или другую) нужно удалять предыдущее сообщение со ссылкой.

# Отправление ссылок на аддоны @dp.callback_query(F.data.in_(telegraphLinks)) async def send_addon1(callback: types.CallbackQuery): await callback.message.answer(telegraphLinks[callback.data]) 

Забор ссылок и колбэков идет через словарь

telegraphLinks: dict[str, str] = 

Отслеживать

3,149 2 2 золотых знака 11 11 серебряных знаков 36 36 бронзовых знаков

задан 12 сен 2023 в 12:06

Timofei Dimitriev Timofei Dimitriev

Управление сообщениями в боте телеграм

Отправка сообщений с помощью бота

Класс types.Message является основным классом в библиотеке aiogram для представления сообщений в Telegram. Он содержит различные методы и атрибуты для работы с сообщениями.

Некоторые из наиболее часто используемых атрибутов и методов класса `types.Message`:

  1. message_id : Уникальный идентификатор сообщения.
  2. from_user : Объект types.User , представляющий отправителя сообщения.
  3. date : Дата и время отправки сообщения.
  4. chat : Объект `types.Chat`, представляющий чат, в котором было отправлено сообщение.
  5. forward_from : Объект types.User , представляющий отправителя оригинального сообщения, если оно было переслано.
  6. forward_from_chat : Объект types.Chat , представляющий чат, из которого было переслано оригинальное сообщение, если оно было переслано из группы или канала.
  7. forward_from_message_id : Идентификатор оригинального сообщения, если оно было переслано.
  8. text : Текст сообщения.
  9. entities : Список объектов types.MessageEntity , представляющих различные сущности в тексте сообщения, такие как упоминания пользователей, хэштеги и т.д.
  10. reply_to_message : Объект types.Message , представляющий сообщение, на которое данное сообщение является ответом.
  11. reply_markup : Объект `types.InlineKeyboardMarkup` или `types.ReplyKeyboardMarkup`, представляющий клавиатуру, привязанную к сообщению.
  12. delete() : Метод для удаления сообщения.
  13. edit_text() : Метод для редактирования текста сообщения.
  14. reply() : Метод для отправки ответного сообщения.

Примеры, приведенные в этой статье работают на версии aiogram 2x

Методы, которые позволяют отправлять сообщения

Для отправки текстового сообщения в библиотеке aiogram можно использовать несколько методов. Некоторые из них:

  • bot.send_message(chat_id, text) : Этот метод позволяет отправить текстовое сообщение в указанный чат. Необходимо указать идентификатор чата ( chat_id ) и текст сообщения ( text ).
await bot.send_message(chat_id, "Привет, мир!")
  • message.answer(text) , который позволяет отправить ответное сообщение на текущее сообщение. Этот метод является альтернативой методу message.reply(text) .
await message.answer("Спасибо за ваше сообщение!")

Метод message.answer() автоматически определяет идентификатор чата и идентификатор сообщения, на которое нужно ответить, поэтому вам не нужно указывать их явно.

  • message.reply(text) : Этот метод позволяет отправить ответное сообщение на текущее сообщение. Необходимо указать текст ответного сообщения ( text ).
await message.reply("Спасибо за ваше сообщение!")
  • message.edit_text(text) : Этот метод позволяет отредактировать текст текущего сообщения. Необходимо указать новый текст сообщения ( text ).
await message.edit_text("Новый текст сообщения")
  • bot.send_message(chat_id, text, reply_to_message_id) : Этот метод позволяет отправить текстовое сообщение в указанный чат в качестве ответа на другое сообщение. Необходимо указать идентификатор чата ( chat_id ), текст сообщения ( text ) и идентификатор сообщения, на которое данное сообщение будет ответом ( reply_to_message_id ).
await bot.send_message(chat_id, "Ответ на ваше сообщение", reply_to_message_id=message_id)

Различия между send_message, answer и reply

Метод bot.send_message отправляет сообщение в произвольный чат, который указывается в параметре chat_id . Метод answer() , позволяет отправить сообщение в ответ на предыдущее сообщение в текущем чате. При этом, сообщение, на которое дается ответ не пересылается. Метод reply() , позволяет отправить сообщение в ответ на предыдущее сообщение в текущем чате. Cообщение, на которое дается ответ также отправляется.

Результат работы функций anwer и reply

Пример готового бота, который умеет отправлять сообщения

from aiogram import Bot, Dispatcher, types from aiogram.contrib.fsm_storage.memory import MemoryStorage # Установите токен вашего бота BOT_TOKEN = 'YOUR_BOT_TOKEN' bot = Bot(token=BOT_TOKEN) dp = Dispatcher(bot, storage=MemoryStorage()) @dp.message_handler(commands=['start']) async def handle_start(message: types.Message): # Отправляем приветственное сообщение await message.reply('Привет! Я бот. Как дела?') @dp.message_handler(commands=['help']) async def handle_help(message: types.Message): # Отправляем сообщение с инструкциями по использованию бота help_message = """ Привет! Я бот. Вот некоторые доступные команды: - /start: Начать взаимодействие с ботом - /help: Получить справку о командах бота """ await message.reply(help_message) @dp.message_handler() async def handle_message(message: types.Message): # Отправляем эхо-ответ на полученное сообщение await message.reply(f'Вы отправили сообщение: ') if __name__ == '__main__': from aiogram import executor executor.start_polling(dp, skip_updates=True) 

В этом примере бот будет отвечать на команды /start и /help , а также на любые другие текстовые сообщения, отправленные пользователем. При получении команды /start он отправит приветственное сообщение, а при получении команды /help отправит справку о командах бота. Для всех остальных сообщений бот отправит эхо-ответ с содержимым полученного сообщения.

Просто замените ‘YOUR_BOT_TOKEN’ на фактический токен вашего бота, запустите скрипт, и ваш бот будет готов к работе. Вы можете добавить дополнительные команды и функциональность, чтобы адаптировать его под свои потребности.

Отправка других типов контента с помощью бота

В библиотеке aiogram вы можете отправлять различные типы контента помимо простого текста. Вот некоторые из наиболее распространенных типов контента, которые вы можете отправлять с помощью aiogram:

1. Фотографии: Метод send_photo используется для отправки фотографий. Вы можете указать путь к файлу фотографии на вашем сервере или использовать URL-адрес изображения в Интернете. Пример использования:

await bot.send_photo(chat_id, photo=open('photo.jpg', 'rb'), caption='Красивая фотография')

2. Аудио: Метод send_audio используется для отправки аудиофайлов. Вы можете указать путь к файлу аудио или использовать URL-адрес аудиофайла в Интернете. Пример использования:

await bot.send_audio(chat_id, audio=open('audio.mp3', 'rb'), caption='Музыкальный трек')

3. Документы: Метод `send_document` используется для отправки документов. Вы можете указать путь к файлу документа на вашем сервере или использовать URL-адрес документа в Интернете. Пример использования:

await bot.send_document(chat_id, document=open('document.pdf', 'rb'), caption='PDF-документ')

4. Видео: Метод send_video используется для отправки видеофайлов. Вы можете указать путь к файлу видео или использовать URL-адрес видеофайла в Интернете. Пример использования:

await bot.send_video(chat_id, video=open('video.mp4', 'rb'), caption='Видео-ролик')

5. Голосовые сообщения: Метод send_voice используется для отправки голосовых сообщений. Вы можете указать путь к файлу голосового сообщения на вашем сервере или использовать URL-адрес голосового сообщения в Интернете. Пример использования:

await bot.send_voice(chat_id, voice=open('voice.ogg', 'rb'), caption='Голосовое сообщение')

Пример реализации бота с возможностью отправки разного типа контента

from aiogram import Bot, Dispatcher, types from aiogram.contrib.fsm_storage.memory import MemoryStorage # Установите токен вашего бота BOT_TOKEN = 'YOUR_BOT_TOKEN' bot = Bot(token=BOT_TOKEN) dp = Dispatcher(bot, storage=MemoryStorage()) @dp.message_handler(commands=['start']) async def handle_start(message: types.Message): # Отправляем приветственное сообщение await message.reply('Привет! Я бот. Как дела?') @dp.message_handler(commands=['text']) async def handle_text(message: types.Message): # Отправляем текстовое сообщение await message.reply('Пример текстового сообщения') @dp.message_handler(commands=['video']) async def handle_video(message: types.Message): # Отправляем видеофайл await bot.send_video(message.chat.id, video=open('video.mp4', 'rb')) @dp.message_handler(commands=['audio']) async def handle_audio(message: types.Message): # Отправляем аудиофайл await bot.send_audio(message.chat.id, audio=open('audio.mp3', 'rb')) @dp.message_handler(commands=['document']) async def handle_document(message: types.Message): # Отправляем документ await bot.send_document(message.chat.id, document=open('document.pdf', 'rb')) @dp.message_handler(commands=['photo']) async def handle_photo(message: types.Message): # Отправляем фотографию await bot.send_photo(message.chat.id, photo=open('photo.jpg', 'rb')) @dp.message_handler(commands=['voice']) async def handle_voice(message: types.Message): # Отправляем голосовое сообщение await bot.send_voice(message.chat.id, voice=open('voice.ogg', 'rb')) if __name__ == '__main__': from aiogram import executor executor.start_polling(dp, skip_updates=True) 

В этом примере бот реагирует на различные команды ( /start , /text , /video , /audio , /document , /photo , /voice ). Когда пользователь отправляет одну из этих команд, бот отправляет соответствующий контент в ответ.

Просто замените ‘YOUR_BOT_TOKEN’ на фактический токен вашего бота, а также укажите пути к файлам видео, аудио, документа, фотографии и голосового сообщения. После этого запустите скрипт, и ваш бот будет готов к работе. Вы можете добавить дополнительные команды и функциональность, чтобы адаптировать его под свои потребности.

Примеры ботов, работающих с сообщениями

Бот — фильтр ненормативной лексики

from aiogram import Bot, Dispatcher, types from aiogram.contrib.fsm_storage.memory import MemoryStorage # Установите токен вашего бота BOT_TOKEN = 'YOUR_BOT_TOKEN' bot = Bot(token=BOT_TOKEN) dp = Dispatcher(bot, storage=MemoryStorage()) # Список запрещенных слов forbidden_words = ['ругаться', 'оскорблять', 'ненормативная_лексика'] @dp.message_handler() async def handle_message(message: types.Message): text = message.text.lower() # Проверяем наличие запрещенных слов в сообщении if any(word in text for word in forbidden_words): # Отправляем предупреждение await message.reply('В чате нельзя ругаться!') if __name__ == '__main__': from aiogram import executor executor.start_polling(dp, skip_updates=True) 

В этом примере бот реагирует на все сообщения в чате и проверяет наличие запрещенных слов из списка forbidden_words в тексте сообщения. Если хотя бы одно из запрещенных слов обнаружено, бот отправляет предупреждение о недопустимости ругательства.

Просто замените ‘YOUR_BOT_TOKEN’ на фактический токен вашего бота и расширьте список forbidden_words в соответствии с вашими требованиями. Запустите скрипт, и ваш бот будет готов к мониторингу сообщений и отправке предупреждений о ненормативной лексике.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *