Skip to main content
Filter queries are a concise syntax for specifying which updates your middleware should handle. They let you write bot.on('message:text') instead of checking if (ctx.message?.text).

What are Filter Queries?

A filter query is a string that describes which updates to match. Filter queries work with bot.on() and automatically narrow the TypeScript types.

Filter Query Syntax

Filter queries have three levels:
  • L1: Update type (message, callback_query, etc.)
  • L2: Property on the update type (text, photo, etc.)
  • L3: Nested property (entities, specific entity types, etc.)

Level 1 - Update Types

Available L1 filters:
  • message - New messages
  • edited_message - Edited messages
  • channel_post - New channel posts
  • edited_channel_post - Edited channel posts
  • business_connection - Business connection updates
  • business_message - Business account messages
  • edited_business_message - Edited business messages
  • deleted_business_messages - Deleted business messages
  • inline_query - Inline queries
  • chosen_inline_result - Chosen inline results
  • callback_query - Callback queries
  • shipping_query - Shipping queries
  • pre_checkout_query - Pre-checkout queries
  • poll - Poll updates
  • poll_answer - Poll answers
  • my_chat_member - Bot’s chat member status changed
  • chat_member - Chat member status changed
  • chat_join_request - Join requests
  • message_reaction - Message reactions
  • message_reaction_count - Reaction counts
  • chat_boost - Chat boosts
  • removed_chat_boost - Removed boosts
  • purchased_paid_media - Paid media purchases

Level 2 - Message Properties

Common L2 filters:
  • :text - Text messages
  • :photo - Photos
  • :video - Videos
  • :audio - Audio files
  • :document - Documents
  • :animation - Animations/GIFs
  • :voice - Voice messages
  • :video_note - Video notes
  • :sticker - Stickers
  • :location - Locations
  • :contact - Contacts
  • :poll - Polls
  • :dice - Dice
  • :game - Games
  • :invoice - Invoices

Level 3 - Nested Properties

Entity types (L3 for :entities or :caption_entities):
  • :mention - @username mentions
  • :hashtag - #hashtag
  • :cashtag - $USD
  • :bot_command - /command
  • :url - https://example.com
  • :email - email@example.com
  • :phone_number - Phone numbers
  • :bold - Bold text
  • :italic - Italic text
  • :underline - Underlined text
  • :strikethrough - Strikethrough text
  • :spoiler - Spoiler text
  • :code - Inline code
  • :pre - Code blocks
  • :text_link - Text links
  • :text_mention - Text mentions
  • :custom_emoji - Custom emoji

Shortcuts

Filter queries support powerful shortcuts:

Empty L1 - Messages and Channel Posts

: matches both message and channel_post:
Equivalent to:

msg - All Message Types

msg: matches all message-like updates:

edit - Edited Messages

edit: matches edited messages and channel posts:

Double Colon - Entity Shortcuts

:: expands to both :entities: and :caption_entities::

media - Photo or Video

file - Any File Type

Combining Filters

OR Logic - Array of Filters

Pass an array to match any of the filters:

AND Logic - Chaining

Chain .on() calls for AND logic:

Advanced Examples

Forwarded Messages

Service Messages

Bot-Specific Filters

The special me filter matches your bot:

Business Updates

Reactions

Stickers

Using Filter Functions

Create reusable filter predicates:
Drop updates that match:

Type Safety

Filter queries provide automatic type narrowing:
Multiple filters create union types:

Performance

Filter queries are compiled to efficient predicate functions:
The compilation happens once, so there’s no performance penalty for using filter queries.

Common Patterns

Ignore Bot Messages

Admin-Only Commands

Private Chat Only

Group Features

Debugging Filter Queries

If a filter query isn’t working as expected:

Best Practices

Use Specific FiltersBe as specific as possible:
Combine Filters for Precision
Use Shortcuts for Readability