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.
Как удалить сообщение бота с помощью aiogram?
SashaN69, Привет . думаю что с time sleep не получится .от просто задержит отправку . если можно пару строчек кода . мне кажется нужно еще id удаляемого сообщения а вот как его получитъ если сообщение отправляет бот . ? к примеру бот выслал видео юзеру и это видео должно удалится через один час
Ответы на вопрос 1
@dp.callback_query_handler(text=»тут название твоей callback_data»)
async def call_main_menu(call: CallbackQuery):
await bot.delete_message(chat_id=call.from_user.id, message_id=call.message.message_id)
Настроить автоматическое удаления системных сообщений в ТГ чате
Задача удалять автоматически эти сообщения спустя время, например несколько минут (2-5-7-10…)
Цель, чтобы эти сообщения не захламляли чат.
Мгновенное удалением этих сообщений не подходит, так как они создают эффект «массовки» в чате и позитивно влияют на добавление другими участниками группы.
Возможно есть боты, которые можно настроить на удаление этих сообщений спустя время, или разработать такой бот. Если у вас есть опыт в решении подобных задач, будем рады взаимодействию.
Здравствуйте, не могу удалить сообщение пользователя, Aiogram
Вы пытаетесь использовать message.delete() , что удаляет то сообщение, которое пользователь последним отправил, в данном случае это: -sms. Вам нужно использовать bot.delete_message .
@dp.message_handler(commands=['sms'], commands_prefix='-') async def sms(message: types.Message): await bot.delete_message(message.chat.id, message.reply_to_message.message_id) await message.answer("️Удалено")
Отслеживать
ответ дан 6 ноя 2022 в 10:07
Kirill Horn Kirill Horn
274 6 6 бронзовых знаков
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.