CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-telegram-bot

A pure Python, asynchronous interface for the Telegram Bot API with comprehensive wrapper and high-level framework for building sophisticated Telegram bots

Pending
Overview
Eval results
Files

filters.mddocs/

Filters System

Powerful filtering system for precisely targeting which updates handlers should process, with extensive built-in filters and support for custom filter creation.

Capabilities

Basic Filters

Core filters for common update types and content.

class filters:
    ALL: UpdateFilter
    TEXT: MessageFilter
    COMMAND: MessageFilter  
    PHOTO: MessageFilter
    VIDEO: MessageFilter
    VIDEO_NOTE: MessageFilter
    VOICE: MessageFilter
    AUDIO: MessageFilter
    DOCUMENT: MessageFilter
    ANIMATION: MessageFilter
    STICKER: MessageFilter
    LOCATION: MessageFilter
    CONTACT: MessageFilter
    VENUE: MessageFilter
    POLL: MessageFilter
    DICE: MessageFilter
    GAME: MessageFilter
    FORWARDED: MessageFilter
    REPLY: MessageFilter

Usage examples:

from telegram.ext import MessageHandler, filters

# Text messages only (excluding commands)
text_handler = MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)

# Photo messages
photo_handler = MessageHandler(filters.PHOTO, handle_photo)

# Video or video note messages
video_handler = MessageHandler(filters.VIDEO | filters.VIDEO_NOTE, handle_video)

# Documents that aren't photos/videos/audio
doc_handler = MessageHandler(
    filters.DOCUMENT & ~(filters.PHOTO | filters.VIDEO | filters.AUDIO),
    handle_document
)

# Forwarded messages
forward_handler = MessageHandler(filters.FORWARDED, handle_forwarded)

# Replies to other messages
reply_handler = MessageHandler(filters.REPLY, handle_reply)

Chat Type Filters

Filter messages based on chat type.

class filters:
    class ChatType:
        PRIVATE: MessageFilter
        GROUP: MessageFilter
        SUPERGROUP: MessageFilter
        CHANNEL: MessageFilter
        GROUPS: MessageFilter  # GROUP | SUPERGROUP

Usage examples:

# Private messages only
private_handler = MessageHandler(
    filters.ChatType.PRIVATE & filters.TEXT,
    handle_private_message
)

# Group messages (both regular and supergroups)
group_handler = MessageHandler(
    filters.ChatType.GROUPS & filters.COMMAND,
    handle_group_command
)

# Channel posts
channel_handler = MessageHandler(
    filters.ChatType.CHANNEL,
    handle_channel_post
)

User and Chat Filters

Filter by specific users, chats, or user properties.

class filters:
    class User:
        @staticmethod
        def user_id(user_id: int | list[int]) -> MessageFilter: ...
        
        @staticmethod 
        def username(username: str | list[str]) -> MessageFilter: ...
    
    class Chat:
        @staticmethod
        def chat_id(chat_id: int | list[int]) -> MessageFilter: ...
        
        @staticmethod
        def username(username: str | list[str]) -> MessageFilter: ...
        
        @staticmethod
        def title(title: str | list[str]) -> MessageFilter: ...
    
    IS_BOT: MessageFilter
    IS_PREMIUM: MessageFilter

Usage examples:

# Messages from specific user
user_filter = filters.User.user_id(123456789)
user_handler = MessageHandler(user_filter, handle_specific_user)

# Messages from multiple users
admin_users = [123456789, 987654321, 555666777]
admin_filter = filters.User.user_id(admin_users)
admin_handler = MessageHandler(admin_filter & filters.COMMAND, handle_admin_command)

# Messages from specific username
username_filter = filters.User.username("john_doe")
username_handler = MessageHandler(username_filter, handle_john)

# Messages in specific chat
chat_filter = filters.Chat.chat_id(-1001234567890)
chat_handler = MessageHandler(chat_filter, handle_specific_chat)

# Messages from bots
bot_filter = filters.IS_BOT
bot_handler = MessageHandler(bot_filter, handle_bot_message)

# Messages from premium users
premium_filter = filters.IS_PREMIUM
premium_handler = MessageHandler(premium_filter, handle_premium_user)

Content Filters

Filter based on message content and properties.

class filters:
    class Text:
        @staticmethod
        def startswith(prefix: str | list[str], ignore_case: bool = False) -> MessageFilter: ...
        
        @staticmethod
        def endswith(suffix: str | list[str], ignore_case: bool = False) -> MessageFilter: ...
        
        @staticmethod
        def contains(substring: str | list[str], ignore_case: bool = False) -> MessageFilter: ...
    
    class Regex:
        @staticmethod
        def create(pattern: str | Pattern, flags: int = 0) -> MessageFilter: ...
    
    class Language:
        @staticmethod
        def language_code(lang_code: str | list[str]) -> MessageFilter: ...
    
    HAS_MEDIA_SPOILER: MessageFilter
    HAS_PROTECTED_CONTENT: MessageFilter
    IS_AUTOMATIC_FORWARD: MessageFilter
    IS_TOPIC_MESSAGE: MessageFilter

Usage examples:

import re

# Messages starting with specific text
hello_filter = filters.Text.startswith("hello", ignore_case=True)
hello_handler = MessageHandler(hello_filter, handle_greeting)

# Messages containing keywords
keyword_filter = filters.Text.contains(["help", "support", "assistance"])
help_handler = MessageHandler(keyword_filter, handle_help_request)

# Regex pattern matching
email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
email_filter = filters.Regex.create(email_pattern, re.IGNORECASE)
email_handler = MessageHandler(email_filter, handle_email)

# Messages from users with specific language
spanish_filter = filters.Language.language_code("es")
spanish_handler = MessageHandler(spanish_filter & filters.TEXT, handle_spanish)

# Messages with spoiler media
spoiler_filter = filters.HAS_MEDIA_SPOILER
spoiler_handler = MessageHandler(spoiler_filter, handle_spoiler_media)

Entity Filters

Filter messages containing specific entity types.

class filters:
    class Entity:
        MENTION: MessageFilter        # @username
        HASHTAG: MessageFilter        # #hashtag  
        CASHTAG: MessageFilter        # $CASHTAG
        BOT_COMMAND: MessageFilter    # /command
        URL: MessageFilter            # http://example.com
        EMAIL: MessageFilter          # user@example.com
        PHONE_NUMBER: MessageFilter   # +1234567890
        BOLD: MessageFilter           # **bold**
        ITALIC: MessageFilter         # *italic*
        CODE: MessageFilter           # `code`
        PRE: MessageFilter            # ```pre```
        TEXT_LINK: MessageFilter      # [text](url)
        TEXT_MENTION: MessageFilter   # @user (no username)

Usage examples:

# Messages with mentions
mention_handler = MessageHandler(filters.Entity.MENTION, handle_mention)

# Messages with hashtags
hashtag_handler = MessageHandler(filters.Entity.HASHTAG, handle_hashtag)

# Messages with URLs
url_handler = MessageHandler(filters.Entity.URL, handle_url)

# Messages with email addresses
email_handler = MessageHandler(filters.Entity.EMAIL, handle_email)

# Messages with phone numbers
phone_handler = MessageHandler(filters.Entity.PHONE_NUMBER, handle_phone)

# Messages with code blocks
code_handler = MessageHandler(filters.Entity.CODE | filters.Entity.PRE, handle_code)

Status Update Filters

Filter special message types and status updates.

class filters:
    class StatusUpdate:
        NEW_CHAT_MEMBERS: MessageFilter
        LEFT_CHAT_MEMBER: MessageFilter
        NEW_CHAT_TITLE: MessageFilter
        NEW_CHAT_PHOTO: MessageFilter
        DELETE_CHAT_PHOTO: MessageFilter
        GROUP_CHAT_CREATED: MessageFilter
        SUPERGROUP_CHAT_CREATED: MessageFilter
        CHANNEL_CHAT_CREATED: MessageFilter
        MIGRATE_TO_CHAT_ID: MessageFilter
        MIGRATE_FROM_CHAT_ID: MessageFilter
        PINNED_MESSAGE: MessageFilter
        INVOICE: MessageFilter
        SUCCESSFUL_PAYMENT: MessageFilter
        USERS_SHARED: MessageFilter
        CHAT_SHARED: MessageFilter
        CONNECTED_WEBSITE: MessageFilter
        WRITE_ACCESS_ALLOWED: MessageFilter
        PASSPORT_DATA: MessageFilter
        PROXIMITY_ALERT_TRIGGERED: MessageFilter
        VIDEO_CHAT_SCHEDULED: MessageFilter
        VIDEO_CHAT_STARTED: MessageFilter
        VIDEO_CHAT_ENDED: MessageFilter
        VIDEO_CHAT_PARTICIPANTS_INVITED: MessageFilter
        WEB_APP_DATA: MessageFilter
        FORUM_TOPIC_CREATED: MessageFilter
        FORUM_TOPIC_CLOSED: MessageFilter
        FORUM_TOPIC_REOPENED: MessageFilter
        FORUM_TOPIC_EDITED: MessageFilter
        GENERAL_FORUM_TOPIC_HIDDEN: MessageFilter
        GENERAL_FORUM_TOPIC_UNHIDDEN: MessageFilter
        GIVEAWAY_CREATED: MessageFilter
        GIVEAWAY: MessageFilter
        GIVEAWAY_WINNERS: MessageFilter
        GIVEAWAY_COMPLETED: MessageFilter
        CHAT_BACKGROUND_SET: MessageFilter
        BOOST_ADDED: MessageFilter

Usage examples:

# New members joining
welcome_handler = MessageHandler(
    filters.StatusUpdate.NEW_CHAT_MEMBERS,
    handle_new_members
)

# Members leaving
goodbye_handler = MessageHandler(
    filters.StatusUpdate.LEFT_CHAT_MEMBER,
    handle_member_left
)

# Chat title changes
title_handler = MessageHandler(
    filters.StatusUpdate.NEW_CHAT_TITLE,
    handle_title_change
)

# Successful payments
payment_handler = MessageHandler(
    filters.StatusUpdate.SUCCESSFUL_PAYMENT,
    handle_payment_success
)

# Video chat events
video_chat_handler = MessageHandler(
    filters.StatusUpdate.VIDEO_CHAT_STARTED | filters.StatusUpdate.VIDEO_CHAT_ENDED,
    handle_video_chat_event
)

Update Type Filters

Filter different types of updates beyond messages.

class filters:
    class UpdateType:
        MESSAGE: UpdateFilter
        EDITED_MESSAGE: UpdateFilter
        CHANNEL_POST: UpdateFilter
        EDITED_CHANNEL_POST: UpdateFilter
        INLINE_QUERY: UpdateFilter
        CHOSEN_INLINE_RESULT: UpdateFilter
        CALLBACK_QUERY: UpdateFilter
        SHIPPING_QUERY: UpdateFilter
        PRE_CHECKOUT_QUERY: UpdateFilter
        POLL: UpdateFilter
        POLL_ANSWER: UpdateFilter
        MY_CHAT_MEMBER: UpdateFilter
        CHAT_MEMBER: UpdateFilter
        CHAT_JOIN_REQUEST: UpdateFilter
        CHAT_BOOST: UpdateFilter
        REMOVED_CHAT_BOOST: UpdateFilter
        BUSINESS_CONNECTION: UpdateFilter
        BUSINESS_MESSAGE: UpdateFilter
        EDITED_BUSINESS_MESSAGE: UpdateFilter
        DELETED_BUSINESS_MESSAGES: UpdateFilter
        MESSAGE_REACTION: UpdateFilter
        MESSAGE_REACTION_COUNT: UpdateFilter
        PURCHASED_PAID_MEDIA: UpdateFilter

Custom Filters

Create custom filters for specific use cases.

class BaseFilter:
    def __init__(self, name: str = None, data_filter: bool = False): ...
    
    def filter(self, message: Message) -> bool | dict: ...
    
    def __and__(self, other: BaseFilter) -> BaseFilter: ...
    def __or__(self, other: BaseFilter) -> BaseFilter: ...
    def __invert__(self) -> BaseFilter: ...
    def __xor__(self, other: BaseFilter) -> BaseFilter: ...

class MessageFilter(BaseFilter):
    pass

class UpdateFilter(BaseFilter):
    pass

Usage examples:

from telegram.ext.filters import BaseFilter

# Custom filter for long messages
class LongMessageFilter(BaseFilter):
    def __init__(self, min_length=100):
        self.min_length = min_length
        super().__init__(name=f"LongMessage({min_length})")
    
    def filter(self, message):
        return message.text and len(message.text) >= self.min_length

long_msg_filter = LongMessageFilter(200)
long_handler = MessageHandler(long_msg_filter, handle_long_message)

# Filter for specific file extensions
class FileExtensionFilter(BaseFilter):
    def __init__(self, extensions):
        self.extensions = [ext.lower() for ext in extensions]
        super().__init__(name=f"FileExtension({extensions})")
    
    def filter(self, message):
        if not message.document or not message.document.file_name:
            return False
        
        filename = message.document.file_name.lower()
        return any(filename.endswith(f".{ext}") for ext in self.extensions)

pdf_filter = FileExtensionFilter(["pdf"])
pdf_handler = MessageHandler(pdf_filter, handle_pdf)

# Filter with data extraction
class UrlExtractorFilter(BaseFilter):
    def __init__(self):
        super().__init__(name="URLExtractor", data_filter=True)
    
    def filter(self, message):
        if not message.entities:
            return False
        
        urls = []
        for entity in message.entities:
            if entity.type == "url":
                url = message.text[entity.offset:entity.offset + entity.length]
                urls.append(url)
        
        return {"urls": urls} if urls else False

url_filter = UrlExtractorFilter()

async def handle_urls(update, context):
    urls = context.match["urls"]  # Access extracted data
    await update.message.reply_text(f"Found URLs: {', '.join(urls)}")

url_handler = MessageHandler(url_filter, handle_urls)

# Admin filter
class AdminFilter(BaseFilter):
    def __init__(self):
        super().__init__(name="Admin")
    
    def filter(self, message):
        # Check if user is admin in the chat
        return message.from_user.id in get_admin_list(message.chat.id)

admin_filter = AdminFilter()
admin_handler = MessageHandler(admin_filter & filters.COMMAND, handle_admin_command)

Filter Combinations

Combine filters using logical operators.

# AND operation - both conditions must be true
text_and_private = filters.TEXT & filters.ChatType.PRIVATE

# OR operation - either condition can be true  
media_filter = filters.PHOTO | filters.VIDEO | filters.ANIMATION

# NOT operation - condition must be false
non_command_text = filters.TEXT & ~filters.COMMAND

# XOR operation - exactly one condition must be true
either_photo_or_video = filters.PHOTO ^ filters.VIDEO

# Complex combinations
admin_media_filter = (
    filters.User.user_id(admin_user_ids) &
    (filters.PHOTO | filters.VIDEO | filters.DOCUMENT) &
    ~filters.HAS_MEDIA_SPOILER
)

# Grouped conditions
content_filter = (
    (filters.TEXT & filters.Text.contains(["urgent", "important"])) |
    (filters.PHOTO & filters.Entity.HASHTAG) |
    (filters.DOCUMENT & filters.Text.contains("report"))
)

Performance Considerations

# Order filters by specificity (most specific first)
# Good - specific user check first
efficient_filter = filters.User.user_id(admin_id) & filters.TEXT & filters.COMMAND

# Less efficient - broad check first
less_efficient = filters.TEXT & filters.COMMAND & filters.User.user_id(admin_id)

# Use built-in filters when possible (they're optimized)
# Good
builtin_filter = filters.PHOTO

# Less efficient custom equivalent
class PhotoFilter(BaseFilter):
    def filter(self, message):
        return message.photo is not None

# Cache expensive operations in custom filters
class ExpensiveFilter(BaseFilter):
    def __init__(self):
        self._cache = {}
        super().__init__()
    
    def filter(self, message):
        user_id = message.from_user.id
        if user_id not in self._cache:
            self._cache[user_id] = expensive_check(user_id)
        return self._cache[user_id]

Types

from typing import Union, List, Pattern
import re

FilterType = Union[BaseFilter, MessageFilter, UpdateFilter]
PatternType = Union[str, Pattern]

Install with Tessl CLI

npx tessl i tessl/pypi-python-telegram-bot

docs

advanced-features.md

application-framework.md

bot-api.md

files.md

filters.md

handlers.md

index.md

keyboards.md

telegram-types.md

tile.json