Skip to main content
When your bot receives an update from Telegram, grammY wraps it in a context object. Context objects are passed to all middleware and provide convenient shortcuts for working with the Telegram Bot API.

What is a Context?

A context object does two main things:
  1. Holds the update - Access the raw update via ctx.update
  2. Provides API shortcuts - Call Bot API methods with pre-filled parameters

Context Properties

Every context object has these core properties:
Update
The complete update object from Telegram
Api
The Bot API instance for making API calls
UserFromGetMe
Information about your bot
string | RegExpMatchArray | undefined
Populated by methods like hears(), command(), and callbackQuery() with matched content

Update Shortcuts

Instead of accessing ctx.update.message, use convenient shortcuts:

Direct Update Properties

Aggregation Shortcuts

These shortcuts intelligently aggregate data from multiple possible sources:

ctx.msg

Get the message from wherever it appears in the update:

ctx.chat

Get the chat from wherever possible:

ctx.from

Get the user who triggered the update:

Other Aggregations

Chat | undefined
The sender chat from ctx.msg?.sender_chat
number | undefined
Message ID from ctx.msg, ctx.messageReaction, or ctx.messageReactionCount
number | undefined
Chat ID from ctx.chat?.id or ctx.businessConnection?.user_chat_id
string | undefined
Inline message ID from ctx.callbackQuery or ctx.chosenInlineResult
string | undefined
Business connection ID from various business-related updates

API Shortcuts

Context provides convenient methods that are shortcuts to ctx.api.* with pre-filled parameters.

Sending Messages

ctx.reply()

Reply to the current chat:

ctx.replyWithPhoto()

Other Reply Methods

  • ctx.replyWithAudio() - Send audio files
  • ctx.replyWithDocument() - Send documents
  • ctx.replyWithVideo() - Send videos
  • ctx.replyWithAnimation() - Send animations/GIFs
  • ctx.replyWithVoice() - Send voice messages
  • ctx.replyWithVideoNote() - Send video notes
  • ctx.replyWithSticker() - Send stickers
  • ctx.replyWithDice() - Send dice
  • ctx.replyWithPoll() - Send polls
  • ctx.replyWithLocation() - Send locations
  • ctx.replyWithVenue() - Send venues
  • ctx.replyWithContact() - Send contacts
  • ctx.replyWithInvoice() - Send invoices
  • ctx.replyWithGame() - Send games

Forwarding and Copying

ctx.forwardMessage()

ctx.copyMessage()

Message Editing

Callback Query Handling

User and Chat Actions

Helper Methods

ctx.entities()

Extract entities from messages:

ctx.reactions()

Analyze reaction updates:

Context Predicates

Test if a context matches certain conditions:

ctx.has()

Check if context matches a filter query:

Specialized Predicates

Static Predicates

Generate reusable predicate functions:

Custom Context

Extend the context with your own properties:

Custom Context Constructor

Create a custom context class:

Type Narrowing

Filter queries automatically narrow context types:

Context in Action

Here’s a complete example showing various context features:

Best Practices

Use ShortcutsPrefer context shortcuts over direct update access:
Type Safety with Filter QueriesUse filter queries for automatic type narrowing:
Don’t Mutate ContextThe context object should be treated as read-only except for the match property and any custom properties you add.
  • Middleware - How context flows through middleware
  • Filter Queries - Filtering context objects
  • Bot - The Bot class that creates contexts