Bot API v3. Автоматизируем работу в группах
С момента публикации предыдущего урока и по состоянию на момент написания этого, Telegram выпустил одно крупное обновление Bot API (3.0), а также несколько мелких (3.1-3.3). Сразу отмечу, ни отправка видеосообщений, ни платежи (по ним есть отличный пример в репозитории pyTelegramBotAPI), ни работа со стикерами рассмотрены не будут.
Удаляем сообщения
Начнём с того, что научим нашего бота в группе удалять сообщения, в которых есть ссылки. Добавим бота в группу и назначим его администратором с правом удаления и блокировки (пригодится позже).
Выдача прав боту
Дабы избежать неприятных ситуаций, нам необходимо определить две вещи: в какой именно группе он будет удалять сообщения и как отличить сообщения с ссылками от всех остальных? Для начала узнаем и запишем куда-нибудь ID нашей группы. А что делать с ссылками? Неужели нам придётся использовать регулярные выражения, создавая себе ещё одну проблему? Конечно, нет! Все «особые» элементы, будь то ссылки, @юзернеймы, команды ботов и т.д. складываются в массив entities в объекте Message , нам остаётся лишь проверить тип объекта и решить, удалять конкретное сообщение или нет. За последнее отвечает метод delete_message , принимающий на вход два аргумента: ID чата и ID сообщения.
Перейдём непосредственно к коду. Дабы упростить себе жизнь, зададим нужные условия срабатывания (нужный ID чата и непустой массив entities) сразу в хэндлер, это сэкономит нам несколько лишних проверок.
Запустим бота и попробуем отправить сообщение с ссылкой. Если вы всё сделали правильно, оно мгновенно исчезнет и в разделе «Недавние действия» (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 для всех остальных. В реальной жизни, конечно, стоит сделать поддержку большего числа языков.
И подготовим небольшой JSON со строками:
Теперь напишем обработчик, который будет реагировать на набор фраз, выдавать режим Read-Only пользователю на 10 минут и уведомлять его на родном языке. Не забудьте импортировать метод time из одноимённого модуля!
Запустим бота и попросим людей с разными language_code выступить в роли противников мяса:
Бот-полиглот
Заключение
В этом уроке мы кратко ознакомились с новыми фишками третьей версии Telegram Bot API, научились удалять сообщения, если они соответствуют одному из заданных критериев и научились «мягко» ограничивать пользователей, не удаляя их из группы. Помимо restrict_chat_member существует метод promote_chat_member для наделения пользователя определёнными администраторскими правами, он остаётся для самостоятельного изучения.
Редактируем сообщение через Телеграм Бот
Мы все ближе и ближе подходим к реализации интересного проекта. В моих планах написать цикл статей по построению бота по продаже товаров или услуг, своего рода интернет-магазин в Телеграме. У меня уже даже есть настроенная Яндекс.Касса. Но для этого нам нужно понимание процессов, которые будут происходить в работе такого бота. Мы уже многое умеем, и сегодня пополним свои знания в части редактирования и удаления сообщений.
Для того чтобы произвести какие-либо действия с сообщением нам нужно знать его message_id и chat_id . Эти данные мы можем получить в объекте, который будет нам отправлен в ответ на нашу публикацию сообщения от Bot API, далее для удобства можем сохранить их в удобном для нас виде, или можем получить их через объект CallbackQuery при событии через кнопку встроенной клавиатуры.
В своем примере я продемонстрирую работу через встроенную клавиатуру. Заодно еще познакомимся с объектом ForceReply.
Создаем тестовое сообщение
В качестве теста, я создал простое, текстовое сообщение с кнопками "Редактировать" и "Удалить". Приводить весь код скрипта я не буду, он повторяется из предыдущих статей, и в прикрепленном в конце статьи исходном коде он также будет присутствовать.
Редактируем сообщение
Редактирование здесь будет происходить в 2 этапа. Сначала мы предложим пользователю ввести новый текст сообщения, потом произведем действие по замене текста. Хранение данных организовывать не будем, все будем делать на лету. В связи с этим возникает вопрос как передать message_id на втором шаге?
При нажатии на кнопку "Редактировать" нам приходит объект CallbackQuery, в котором содержится message_id нужного нам сообщения, он находится в ['callback_query']['message']['message_id']. Сформируем текстовое сообщение-запрос, зашьем в него полученный message_id, и отправим пользователю. Дополнительно к сообщению прикрепим объект ForceReply.
Пользователь отправит нам в ответ новый текст для редактирования, также под ключом reply_to_message будет наш сформированный текст с message_id нужного нам сообщения. Достаем его и передаем в метод editMessageText.
Удаляем сообщение
Удалять сообщение как ни странно проще некуда. При нажатии на кнопку также передается объект CallbackQuery из которого берем message_id передаем его вместе с chat_id в метод deleteMessage.
Подводим итоги
Теперь мы еще на один шаг стали ближе к большому проекту. Исходный код примеров этой статьи вы можете скачать по этой ссылке.
Комментарии
Авторизуйтесь через Telegram, чтобы оставить комментарий.
Откройте бот @SiteAuthBot, нажмите кнопку Старт/Start. Следуйте инструкциям бота.
Внимание!
Убедитесь, что эта страница открыта в браузере, а не в приложении Telegram. В противном случае авторизация пройдет только в приложении Telegram.
Telegram Bot Удалить сообщение бота
Использую pyTelegramBotAPI Как удалять сообщения бота в чате? Например: бот выдает пользователю несколько кнопок, а при нажатии на одну из них поле с кнопками удаляется.
- Сообщение можно удалить только в том случае, если оно было отправлено менее 48 часов назад.
- Боты могут удалять исходящие сообщения в группах и супергруппах.
- Боты, которым предоставлены права can_post_messages , могут удалять
исходящие сообщения в каналах. - Если бот является администратором группы, он может удалить там любое сообщение.
- Если бот имеет разрешение can_delete_messages в супергруппе или канале, он может удалить там любое сообщение. Возвращает True в случае успеха.
Как правильно удалять и редактировать сообщения в Телеграм-Боте (telebot) на Python?
Ошибка возникает потому, что id сообщений не меняются в зависимости от предыдущего. То есть, id следующего сообщения создаётся рандомно. Если же вы добавите bot.delete_message в одну из команд, то бот удалит сообщение с вашей командой.
Можно попробовать такой способ. Но тогда бот будет удалять каждое новое сообщение, если вы не добавите условия для удаления.
Например, если вы хотите удалять сообщения в зависимости от их контекста, то можно сделать проверку: