Сообщить об ошибке.

Все о фильтрации сообщений в python-telegram-bot

Внимание! Пакеты python-telegram-bot версии 13.x будут придерживаться многопоточной парадигмы программирования (*на данный момент актуальна версия 13.15). Пакеты версий 20.x и новее предоставляют чистый асинхронный Python интерфейс для Telegram Bot API. Дополнительно смотрите основные изменения в пакете python-telegram-bot версии 20.x.

В этом материале рассмотрены встроенные фильтры в пакет python-telegram-bot версии 13.x, а так же описаны расширенные варианты использования фильтров, которые используют обработчики MessageHandler, а также с CommandHandler и PrefixHandler модуля расширения telegram.ext.

ВНИМАНИЕ Для python-telegram-bot версии 20.x, модуль telegram.ext.filters был переписан практически с нуля и использует новую политику пространства имен.

Изменения примерно такие:

  • telegram.ext.Filters больше не существует. Вместо него нужно использовать модуль telegram.ext.filters. Например, Filters.text нужно заменить на filter.TEXT.
  • Встроенные фильтры, которым не нужны аргументы, теперь пишутся в стиле SCREAMING_SNAKE_CASE, например filter.TEXT. Классы фильтров, которым нужны аргументы, теперь пишутся в стиле CamelCase, например filters.User.
  • Для тесно связанных фильтров теперь используется класс пространства имен, чтобы сгруппировать их. Например, filter.Document нельзя использовать в MessageHandler. Чтобы отфильтровать сообщения с вложенным документом, нужно использовать filter.Document.ALL.

Кроме того, фильтры больше нельзя вызывать. Чтобы проверить, принимает ли фильтр обновление, используйте новый синтаксис my_filter.check_update(update).

Содержание:


Встроенные фильтры telegram.ext.filters.

Встроенные фильтры используются в обработчике MessageHandler(filters, callback) в качестве аргумента filters.

Импорт модуля производится следующим образом:

from telegram.ext import Filters

# пример для фильтрации всех видео-сообщений.
MessageHandler(Filters.video, callback_method)
# пример для фильтрации всех контактов
MessageHandler(Filters.contact, callback_method)

# пример для версии 20.x
from telegram.ext import filters

# пример для фильтрации всех видео-сообщений.
MessageHandler(filters.VIDEO, callback_method)
# пример для фильтрации всех контактов
MessageHandler(filters.CONTACT, callback_method)

Filters.animation:

Фильтр Filters.animation определяет сообщения, содержащие объект telegram.Animation, который представляет собой файл анимации (видео в формате GIF или H.264/MPEG-4 AVC без звука).

Filters.audio:

Фильтр Filters.audio определяет сообщения, содержащие объект telegram.Audio - аудиофайл, который клиенты Telegram будут рассматривать как музыку.

Filters.caption(capt):

Фильтр Filters.caption определяет сообщения с подписью. Если передается список строк, он фильтрует сообщения, чьи заголовки capt появляются в данном списке.

Необязательный аргумент capt - это список или кортеж строк, определяющий, какие подписи необходимо разрешать. Допускаются только точные совпадения. Если не указано, то будет разрешать любые сообщения, имеющие подпись.

Пример: MessageHandler(Filters.caption, callback_method)

Filters.caption_entity(entity_type):

Фильтр Filters.caption_entity() определяет только сообщения, подпись которых имеет особую сущность telegram.MessageEntity, где её тип совпадает с entity_type. Объект telegram.MessageEntity представляет собой хэштеги, имена пользователей, URL-адреса и т. д.

Аргумент entity_type это тип объекта заголовка для проверки. Все типы можно найти как константы в telegram.constants.MESSAGEENTITY_ALL_TYPES.

>>> import telegram
>>> telegram.constants.MESSAGEENTITY_ALL_TYPES
# ['mention', 'hashtag', 'cashtag', 'phone_number', 
# 'bot_command', 'url', 'email', 'bold', 'italic', 'code', 
# 'pre', 'text_link', 'text_mention', 'underline', 'strikethrough']

Пример: MessageHandler(Filters.caption_entity("hashtag"), callback_method)

Filters.caption_regex(pattern):

Фильтр Filters.caption_regex() определяет сообщения путем поиска вхождения шаблона pattern в подписи к сообщению.

Этот фильтр работает аналогично Filters.regex, за исключением того, что он применяется к заголовку сообщения, а не к тексту.

Фильтр Filters.caption_regex() не будет работать с простыми текстовыми сообщениями, а только с медиафайлами с подписями.

Пример: MessageHandler(Filters.photo & Filters.caption_regex(r'help'), callback) для захвата всех фотографий с подписью, содержащей слово "help".

Filters.chat(chat_id=None, username=None, allow_empty=False):

Фильтр Filters.chat(), определяет сообщения, c указанными идентификаторами чата chat_id или username чата.

  • Аргумент chat_id - какой идентификатор(ы) чата разрешить (принимает целое число или список целых чисел).
  • Аргумент username какое имя пользователя(ей) разрешить. Ведущий символ '@' в именах пользователей будут отброшены (принимает строку или список строк).
  • Аргумент allow_empty - следует ли обрабатывать сообщения, если в chat_id и именах пользователей не указан чат. По умолчанию установлено значение False

Если одновременно присутствуют и chat_id и username, то возникает исключение RuntimeError.

Пример: MessageHandler(Filters.chat(-1234), callback_method)

Фильтр Filters.chat() имеет следующие атрибуты и методы:

  • chat_ids - set(int), какие идентификаторы чата разрешить.
  • usernames - set(str), какие имена пользователей (без символа @) разрешить.
  • allow_empty - bool, следует ли обрабатывать сообщения, если в chat_ids и usernames не указан чат.
  • add_chat_ids(chat_id) - добавляет один или несколько чатов chat_id к разрешенным идентификаторам чатов.
  • add_usernames(username) - добавляет один или несколько пользователей username к разрешенным именам пользователей.
  • remove_chat_ids(chat_id) - удаляет один или несколько чатов chat_id из разрешенных идентификаторов чатов.
  • remove_usernames(username) - удаляет один или несколько пользователей username из разрешенных имен пользователей.

Filters.chat_type:

Фильтр Filters.chat_type является подмножеством для фильтрации типа чата.

Filters.chat_type имеет следующие атрибуты:

  • channel - сообщения из канала.
  • group - сообщения из группы.
  • supergroup - сообщения от супергруппы.
  • groups - сообщения из группы или супергруппы.
  • private - сообщения, отправлены в приватном чате.

Filters.command(update=True):

Фильтр Filters.command() определяет сообщения, начинающиеся с команды бота.

По умолчанию разрешены только сообщения, начинающиеся с команды бота. Передайте необязательному аргументу update значение False, чтобы также разрешить сообщения, содержащие команду бота в любом месте текста.

Пример:

# команда в начале сообщения
MessageHandler(Filters.command, command_at_start_callback)
# команда встречается в тексте сообщения
MessageHandler(Filters.command(False), command_anywhere_callback)

Обратите внимание, что фильтр Filters.text также принимает сообщения, содержащие команду.

Filters.contact:

Фильтр Filters.contact определяет сообщения с объектом telegram.Contact - переданным телефонным контактом.

Filters.dice(n):

Фильтр Filters.dice() определяет сообщения игрального кубика/кости. Если передается целое число n или список целых чисел, он фильтрует сообщения, чье значение кубика появляется в данном списке.

Примеры:

# Чтобы разрешить любое сообщение `dice`, просто используйте
MessageHandler(Filters.dice, callback_method)
# Чтобы разрешить только кости со значением 6, используйте
MessageHandler(Filters.dice(6), callback_method).
# Чтобы разрешить только кости со значением 5 или 6, используйте
MessageHandler(Filters.dice([5, 6]), callback_method).

Фильтр Filters.dice в сообщениях не поддерживает текст. Если необходимо фильтровать текстовые сообщения или сообщения в виде игрального кубика/кости, то нужно использовать комбинацию фильтров Filters.text | Filters.dice.

Filters.document:

Фильтр Filters.document представляет собой подмножество сообщений, содержащих документ/файл.

Используйте такие фильтры, как: Filters.document.mp3, Filters.document.mime_type("text/plain") и т. д. Или используйте только Filters.document для всех сообщений, которые содержат какой либо документ/файл.

Фильтр Filters.document имеет следующие атрибуты:

  • category - фильтрует документы по их категории в атрибуте mime-type.
  • application - то же самое, что Filters.document.category("application").
  • audio - то же самое, что Filters.document.category("audio").
  • image - то же самое, что Filters.document.category("image").
  • video - то же самое, что Filters.document.category("video").
  • text - то же самое, что Filters.document.category("text").
  • mime_type - фильтрует документы по их атрибуту mime-type. Пример: Filters.document.mime_type('audio/mpeg') - фильтрует все аудио в формате mp3.
  • apk - то же самое, что Filters.document.mime_type("application/vnd.android.package-archive").
  • doc - то же самое, что Filters.document.mime_type("application/msword").
  • docx - то же самое, что Filters.document.mime_type("application/vnd.openxmlformats-officedocument.wordprocessingml.document").
  • exe - то же самое, что Filters.document.mime_type("application/x-ms-dos-executable").
  • gif - то же самое, что Filters.document.mime_type("video/mp4"").
  • jpg - то же самое, что Filters.document.mime_type("image/jpeg").
  • mp3 - то же самое, что Filters.document.mime_type("audio/mpeg").
  • pdf - то же самое, что Filters.document.mime_type("application/pdf").
  • py - то же самое, что Filters.document.mime_type("text/x-python").
  • svg - то же самое, что Filters.document.mime_type("image/svg+xml").
  • txt - то же самое, что Filters.document.mime_type("text/plain").
  • targz - то же самое, что Filters.document.mime_type("application/x-compressed-tar").
  • wav - то же самое, что Filters.document.mime_type("audio/x-wav").
  • xml - то же самое, что Filters.document.mime_type("application/xml").
  • zip - то же самое, что Filters.document.mime_type("application/zip").
  • file_extension - этот фильтр определяет документы по окончанию/расширению файла.

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

    1. По умолчанию регистр не учитывается, такое поведение можно изменить это с помощью флага case_sensitive=True.
    2. Расширение следует передавать без начальной точки, если оно не является частью расширения.
    3. Передайте None, чтобы фильтровать файлы без расширения, то есть без точки в имени файла.

    Примеры

    # фильтрует файлы с расширением ".jpg".
    Filters.document.file_extension("jpg") 
    # фильтрует файлы с расширением "..jpg".
    Filters.document.file_extension(".jpg") 
    # фильтрует файлы с расширением `.Dockerfile` учитывая регистр символов.
    Filters.document.file_extension("Dockerfile", case_sensitive=True)
    # фильтрует файлы без расширения
    Filters.document.file_extension(None) filters files withou
    

Filters.entity(entity_type):

Фильтр Filters.entity() определяет сообщения, текст которых имеет особую сущность telegram.MessageEntity, где её тип совпадает с entity_type. Объект telegram.MessageEntity представляет собой хэштеги, имена пользователей, URL-адреса и т. д.

Аргумент entity_type - тип сущности объекта Telegram для проверки. Сущности, встроенные в Telegramm:

import telegram
telegram.MessageEntity.ALL_TYPES
# ['mention', 'hashtag', 'cashtag', 'phone_number', 
# 'bot_command', 'url', 'email', 'bold', 'italic', 'code', 
# 'pre', 'text_link', 'text_mention', 'underline', 'strikethrough']

Пример: MessageHandler(Filters.entity("hashtag"), callback_method)

Filters.forwarded:

Фильтр Filters.forwarded определяет только пересылаемые сообщения.

Filters.game:

Фильтр Filters.game определяет сообщения, содержащие объект, представляющий собой игру telegram.Game.

Используйте @BotFather для создания и редактирования игр, их короткие названия будут выступать в качестве уникальных идентификаторов.

Filters.invoice:

Фильтр Filters.invoice определяет сообщения, с объектом, содержащим основную информацию о счете telegram.Invoice.

Filters.language(lang):

Фильтр Filters.language() определяет только сообщения от пользователей с определенным языковым кодом.

Согласно официальной документации Telegram API, не у каждого пользователя есть атрибут language_code. Не рассчитывайте, что этот фильтр сработает для всех пользователей.

Аргумент lang - строка с языковым кодом. Фильтр использует метод str.startswith(), это означает, что строка 'en' будет соответствовать как en_US, так и en_GB.

Пример: MessageHandler(Filters.language("en"), callback_method)

Filters.location:

Фильтр Filters.location определяет сообщения, c объектом, представляющим собой точку на карте telegram.Location.

Filters.passport_data:

Фильтр Filters.passport_data определяет сообщения c объектом, cодержим информацию о данных telegram.PassportData, которыми пользователь поделился с ботом.

Чтобы расшифровать этот объект, необходимо передать свой private_key в telegram.Updater или telegram.Bot. Расшифрованные данные находятся в decrypted_data, а полезная нагрузка decrypted_credentials - в атрибуте telegram.Credentials.payload .

Filters.photo:

Фильтр Filters.photo определяет сообщения c объектом, представляющим собой фотографию со сторонами одного размера или миниатюру файла/стикера telegram.PhotoSize.

Filters.poll:

Фильтр Filters.poll определяет сообщения c объектом, содержащим информацию об опросе telegram.Poll.

Filters.regex(pattern):

Фильтр Filters.regex() определяет сообщения, путем поиска вхождения шаблона регулярного выражения pattern в тексте сообщения. При поиске вхождения шаблона используется функция re.search().

# для захвата всех сообщений, содержащих слово 'help'
MessageHandler(Filters.regex(r'help'), callback)
# шаблон нечувствителен к регистру
MessageHandler(Filters.regex(re.compile(r'help', re.IGNORECASE)), callback)`.

Комбинация фильтров Filters.regex использует ту же логику замыкания, что и операторы and, or и not. Например, комбинация фильтров Filters.regex(r'(a?x)') | Filters.regex(r'(b?x)') с message.text='х', будет возвращать только совпадения для первого фильтра, так как второй никогда не оценивается.

Filters.reply:

Фильтр Filters.reply определяет сообщения, являющиеся ответом на другое сообщение.

Filters.sender_chat(chat_id=None, username=None, allow_empty=False):

Фильтр Filters.sender_chat определяет сообщения, отправителем которого является чат с chat_id или username чата.

  • Аргумент chat_id: разрешенный чат отправителя. Может быть целое число или список целых чисел.
  • Аргумент username: разрешенное имя пользователя отправителя чата. Символ '@' в начале имени пользователя будет удален. Может быть строка или список строк.
  • Аргумент allow_empty: следует ли обрабатывать обновления, если чат отправителя не указан в chat_ids или usernames. По умолчанию False.

Если присутствуют и chat_id, и username одновременно, то возникает исключение RuntimeError.

# Для фильтрации сообщений, пересылаемых в  
# группу из канала с идентификатором -1234
MessageHandler(Filters.sender_chat(-1234), callback_method).

# Для фильтрации сообщений анонимных администраторов
# в супергруппе с именем пользователя `@anonymous`
MessageHandler(Filters.sender_chat(username='anonymous'), callback_method).

# Для фильтрации сообщений, пересылаемых
# в группу с любого канала 
MessageHandler(Filters.sender_chat.channel, callback_method).

# Для фильтрации сообщений анонимных 
# администраторов в любой супергруппе
MessageHandler(Filters.sender_chat.super_group, callback_method).

Помните, что атрибут фильтра sender_chat также устанавливается для сообщений в канале как сам канал, поэтому, когда бот является администратором канала и связанной группы обсуждения, то сообщение придет дважды (один раз изнутри канала, один раз внутри группы обсуждения).

Чтобы добавить/удалить чат, необходимо использовать методы фильтра .add_usernames(), .add_chat_ids(), .remove_usernames() и .remove_chat_ids(). Обновляйте все множество только с помощью атрибутов экземпляра фильтра filter.chat_ids/.usernames=new_set, если полностью уверены, что это не вызывает состояния гонки в потоках, так как произойдет замена текущего множества разрешенных чатов.

Атрибуты и методы фильтра Filters.sender_chat:

  • chat_ids (множество целых чисел set(int)) - какой идентификатор(ы) чата отправителя должен быть разрешен.
  • usernames (множество строк set(str)) - какие имена пользователей чата отправителя (без символа @) должен быть разрешены.
  • allow_empty - следует ли обрабатывать сообщения, если чат отправителя не указан в chat_ids или usernames.
  • super_group - сообщения, отправителем которых является чат супергруппы. Например, Filters.sender_chat.supergroup.
  • channel - сообщения, чей чат отправителя является каналом. Например, Filters.sender_chat.channel.
  • add_chat_ids(chat_id) - добавляет один или несколько чатов отправителя к разрешенным идентификаторам чата. chat_id - то же самое, что аргумент фильтра.
  • add_usernames(username) - добавляет один или несколько чатов отправителя к разрешенным именам пользователей. username. - то же самое, что аргумент фильтра.
  • get_chat_or_user(message)remove_chat_ids(chat_id) удаляет один или несколько чатов отправителя из разрешенных идентификаторов чата. chat_id - то же самое, что аргумент фильтра.remove_usernames(username) удаляет один или несколько чатов отправителя из разрешенных имен пользователей. username. - то же самое, что аргумент фильтра.

Filters.status_update:

Фильтр Filters.status_update определяет подмножество сообщений, содержащих обновление статуса.

# для всех сообщений с обновлением статуса
Filters.status_update
# для всех сообщений с информацией о новых участниках чата 
Filters.status_update.new_chat_members

Фильтр Filters.status_update имеет следующие атрибуты:

  • chat_created - обновления, содержащие
    • telegram.Message.group_chat_created (группа создана),
    • telegram.Message.supergroup_chat_created (супергруппа создана),
    • telegram.Message.channel_chat_created (канал создан).
  • connected_website - обновления, содержащие telegram.Message.connected_website (доменное имя сайта, с которого пользователь вошел в систему).
  • delete_chat_photo - обновления, содержащие telegram.Message.delete_chat_photo (фото чата была удалена).
  • left_chat_member - обновления, содержащие telegram.Message.left_chat_member (информация о пользователе, покинувшем группу. Этим участником может быть сам бот).
  • migrate - обновления, содержащие:
    • telegram.Message.migrate_to_chat_id (группа была перенесена в супергруппу с указанным идентификатором),
    • telegram.Message.migrate_from_chat_id (супергруппа была перенесена из группы с указанным идентификатором).
  • new_chat_members - обновления, содержащие telegram.Message.new_chat_members (информация о новых участниках чата. Сам бот может быть одним из этих членов).
  • new_chat_photo - обновления, содержащие telegram.Message.new_chat_photo (фотография чата была изменена на это значение).
  • new_chat_title - обновления, содержащие telegram.Message.new_chat_title (название чата было изменено на это значение).
  • message_auto_delete_timer_changed - обновления, содержащие telegram.Message.message_auto_delete_timer_changed (служебное сообщение: в чате изменены настройки таймера автоудаления).
  • pinned_message - обновления, содержащие telegram.Message.pinned_message (указанное сообщение было закреплено.).
  • proximity_alert_triggered - обновления, содержащие telegram.Message.proximity_alert_triggered (служебное сообщение: пользователь в чате вызвал оповещение о близости другого пользователя во время обмена живым местоположением).
  • voice_chat_started - обновления, содержащие telegram.Message.voice_chat_started (служебное сообщение: пользователь начат голосовой чат).
  • voice_chat_ended - обновления, содержащие telegram.Message.voice_chat_ended (служебное сообщение: пользователь закончил голосовой чат).
  • voice_chat_participants_invited - обновления, содержащие telegram.Message.voice_chat_participants_invited (служебное сообщение: новые участники приглашены в голосовой чат).

Filters.sticker:

Фильтр Filters.sticker определяет сообщения, содержащие объект, представляющий собой стикер.

Filters.successful_payment:

Фильтр Filters.successful_payment определяет сообщения, содержащие объект, представляющий основную информацию об успешном платеже.

Filters.text(str):

Фильтр Filters.text определяет текстовые сообщения.

Если в update передается список строк, он фильтрует сообщения, текст которых появляется в str. Допускаются только точные совпадения. Если не указано, разрешит любое текстовое сообщение.

# любое текстовое сообщение,
MessageHandler(Filters.text, callback_method).

Простой вариант использования для передачи списка: разрешить только те сообщения, которые были отправлены пользователем при помощи кнопок, определенных telegram.ReplyKeyboardMarkup.

buttons = ['Start', 'Settings', 'Back']
markup = ReplyKeyboardMarkup.from_column(buttons)
...
MessageHandler(Filters.text(buttons), callback_method)

Примечания:

  • Сообщения Filters.dice](#Filters.dice) не содержат текста. Если необходимо отфильтровать текстовые сообщения или сообщения dice, используйте комбинацию Filters.text | Filters.dice.
  • Сообщения, содержащие команду, принимаются этим фильтром. Используйте комбинацию фильтров Filters.text & (~Filters.command), если надо фильтровать только текстовые сообщения без команд.

Filters.update:

Фильтр Filters.update представляет собой подмножество для фильтрации типа обновления.

# новое входящее сообщение
Filters.update.message
# новый входящий пост на канале
# или для всех типов сообщений 
Filters.update

Фильтр Filters.update содержит следующие атрибуты:

  • message - сообщение, содержащее новое входящее сообщение telegram.Update.message,
  • edited_message - сообщение, содержащее новую версию сообщения (сообщение отредактировано) telegram.Update.edited_message,
  • messages - сообщение, с любым из:
    • новое входящее сообщение telegram.Update.message,
    • сообщение отредактировано telegram.Update.edited_message,
  • channel_post - сообщение, содержащее новый входящий пост на канале telegram.Update.channel_post,
  • edited_channel_post - сообщение, содержащее новую версию сообщения на канале telegram.Update.edited_channel_post,
  • channel_posts - сообщение, с любым из:
    • новый входящий пост на канале telegram.Update.channel_post,
    • отредактированный пост на канале telegram.Update.edited_channel_post.

Filters.user(user_id=None, username=None, allow_empty=False):

Фильтр Filters.user() определяет сообщения, которые получены от указанного(ых) user_id или username пользователя(ей).

Например: MessageHandler(Filters.user(1234), callback_method)

  • Аргумент user_id: разрешенный индификатор пользователя отправителя. Может быть целое число или список целых чисел.
  • Аргумент username: разрешенное имя пользователя отправителя. Символ '@' в начале имени пользователя будет удален. Может быть строка или список строк.
  • Аргумент allow_empty: следует ли обрабатывать сообщения, если отправитель не указан в user_id или usernames. По умолчанию False.

Если присутствуют и user_id, и username, то возникает исключение RuntimeError.

Чтобы добавить/удалить пользователя, необходимо использовать методы экземпляра фильтра .add_usernames(), .add_user_ids(), .remove_usernames() и .remove_user_ids(). Обновляйте весь набор только с помощью filter.user_ids/.usernames = new_set, если только уверены, что это не вызывает состояния гонки в потоках, так как это заменит текущий набор разрешенных пользователей.

Фильтр Filters.user() определяет следующие методы и атрибуты:

  • user_ids (множество целых чисел set(int)) - разрешенные идентификаторы пользователей
  • usernames (множество строк set(str)) - разрешенные имена пользователей (без символа @).
  • allow_empty - следует ли обрабатывать сообщения, если отправитель не указан в user_ids или usernames.
  • add_user_ids(user_id) - добавляет одного или нескольких пользователей к разрешенным идентификаторам пользователей. user_id - то же самое, что аргумент фильтра.
  • add_usernames(username) - добавляет одного или нескольких пользователей к разрешенным именам пользователей. username - то же самое, что аргумент фильтра.
  • get_chat_or_user(message)
  • remove_user_ids(user_id) - удаляет одного или нескольких пользователей из разрешенных идентификаторов пользователей. user_id - то же самое, что аргумент фильтра.
  • remove_usernames(username) - удаляет одного или нескольких пользователей из разрешенных имён. username - то же самое, что аргумент фильтра.

Filters.via_bot(bot_id=None, username=None, allow_empty=False):

Фильтр Filters.via_bot определяет сообщения, которые получены от указанных идентификаторов bot_id или username.

Например: MessageHandler(Filters.via_bot(1234), callback_method)

  • Аргумент bot_id: разрешенный индификатор бота. Может быть целое число или список целых чисел.
  • Аргумент username: разрешенное имя пользователя. Символ '@' в начале имени пользователя будет удален. Может быть строка или список строк.
  • Аргумент allow_empty: следует ли обрабатывать сообщения, если не указан в bot_id или usernames. По умолчанию False.

Чтобы добавить/удалить бота, необходимо использовать методы экземпляра фильтра .add_usernames(), .add_bot_ids(), .remove_usernames() и .remove_bot_ids(). Обновляйте весё множество только с помощью filter.bot_ids/.usernames = new_set, если только уверены, что это не вызывает условий гонки в потоках, так как произойдет замена текущего множества разрешенных ботов.

Фильтр Filters.via_bot() определяет следующие методы и атрибуты:

  • bot_id (множество целых чисел set(int)) - разрешенные идентификаторы бота(ов).
  • usernames (множество строк set(str)) - разрешенные имена пользователей (без символа @).
  • allow_empty - следует ли обрабатывать сообщения, если не указан в bot_id или usernames.
  • add_bot_ids(user_id) - добавляет одного или нескольких ботов к разрешенным идентификаторам. bot_id - то же самое, что аргумент этого фильтра.
  • add_usernames(username) - добавляет одного или нескольких пользователей к разрешенным именам пользователей. username - то же самое, что аргумент фильтра.
  • get_chat_or_user(message)
  • remove_bot_ids(bot_id) - удаляет одного или нескольких ботов из разрешенных идентификаторов. bot_id - то же самое, что аргумент фильтра.
  • remove_usernames(username) - удаляет одного или нескольких пользователей из разрешенных имён. username - то же самое, что аргумент фильтра.

Filters.venue:

Фильтр Filters.venue определяет сообщения с объектом, представляющим собой место проведения.

Filters.video:

Фильтр Filters.video определяет сообщения с объектом, представляющим собой telegram.Video

Filters.video_note:

Фильтр Filters.video_note определяет сообщения с объектом, представляющим собой telegram.VideoNote

Filters.voice:

Фильтр Filters.video_note определяет сообщения с объектом, представляющим собой telegram.Voice


Комбинирование фильтров.

При использовании MessageHandler иногда бывает полезно иметь более одного фильтра. Это можно сделать с помощью так называемых побитовых операторов. В Python такими операторами являются &, | и ~, которые означают И, ИЛИ и НЕ соответственно. Начиная с версии 13.1 фильтры поддерживают ^ для операции XOR.

Пример определения сообщения, которое является либо видео, либо фото, либо документом.

# для версии 13.x
from telegram.ext import MessageHandler, Filters
handler = MessageHandler(Filters.video | Filters.photo | Filters.document, 
                         callback)

# для версии 20.x
from telegram.ext import MessageHandler, filters
handler = MessageHandler(filters.VIDEO | filters.PHOTO | filters.Document.ALL, 
                         callback
)

Вычисляем сообщение, которое является пересылаемой фотографией.

# для версии 13.x
from telegram.ext import MessageHandler, Filters
handler = MessageHandler(Filters.forwarded & Filters.photo, callback)

# для версии 20.x
from telegram.ext import MessageHandler, filters
handler = MessageHandler(filters.FORWARDED & filters.PHOTO, callback)

Определение сообщения, которое является текстовым и содержит ссылку.

# для версии 13.x
from telegram import MessageEntity
from telegram.ext import MessageHandler, Filters
handler = MessageHandler(
   Filters.text & (
      Filters.entity(MessageEntity.URL) |
      Filters.entity(MessageEntity.TEXT_LINK)
   ),
   callback
)

# для версии 20.x
from telegram import MessageEntity
from telegram.ext import MessageHandler, Filters
handler = MessageHandler(
   filters.TEXT & (
      filters.Entity(MessageEntity.URL) |
      filters.Entity(MessageEntity.TEXT_LINK)
   ),
   callback
)

Определение сообщения, которое является фотографией и не пересылается.

# для версии 13.x
from telegram.ext import MessageHandler, Filters
handler = MessageHandler(Filters.photo & (~ Filters.forwarded), callback)

# для версии 20.x
handler = MessageHandler(filters.PHOTO & (~ filters.FORWARDED), callback)

Создание и использование пользовательских фильтров.

Также возможно написать собственные фильтры. По сути, фильтр - это просто функция, которая получает либо экземпляр сообщения, либо экземпляр обновления и возвращает либо True, либо False. Эта функция должна быть реализована в новом классе, который наследуется от MessageFilter или UpdateFilter, что позволяет комбинировать его с другими фильтрами. Если комбинация всех фильтров оценивается как True, то сообщение будет передано в соответствующую функцию-обработчик callback.

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

Например, для определенного обработчика необходимо разрешить только те сообщения, которые содержат текст "python-telegram-bot", в этом случае можно написать собственный фильтр следующим образом:

from telegram.ext import MessageFilter

class FilterAwesome(MessageFilter):
    def filter(self, message):
        return 'python-telegram-bot' in message.text

# Инициализируем класс.
my_filter = FilterAwesome()

Класс можно назвать как угодно, но необходимо придерживаться следующего:

  • Класс должен быть унаследован от MessageFilter или UpdateFilter.
  • Он должен реализовать метод .filter().
  • Перед использованием необходимо создать экземпляр класса.

Затем фильтр можно использовать так:

my_handler = MessageHandler(my_filter, callback)

Фильтры и класс CallbackContext.

При использовании Filters.regex атрибуты context.matches и context.match устанавливаются на соответствующие совпадения. Чтобы добиться чего-то подобного для пользовательского настраиваемого фильтра, можно сделать следующее:

  • Установите self.data_filter=True для своего фильтра.Если обновление должно быть обработано, верните словарь в форме {attribute_name: value}. Этот словарь dict будет объединен с внутренним словарем аргумента context, делая значение доступным как context.attribute_name. В настоящее время это работает с MessageHandler, CommandHandler и PrefixHandler, которые являются единственными обработчиками, которые принимают фильтры.

Если необходимо, чтобы это работало с пользовательским обработчиком, то необходимо убедится, что YourHandler.collect_additional_context делает что-то вроде:

if isinstance(check_result, dict):
    context.update(check_result)