Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Arbitrary callback_data

NeonBlader edited this pageFeb 2, 2025 ·19 revisions

Arbitrary objects asInlineKeyboardButton.callback_data

The Telegrams Bot API only accepts strings with length up to 64 bytes ascallback_data forInlineKeyboardButtons, which sometimes is quite a limitation.

With PTB, you are able to passany object ascallback_data. This is achieved by storing the object in a cache and passing a unique identifier for that object to Telegram. When aCallbackQuery is received, the id in thecallback_data is replaced with the stored object. To use this feature, setApplication.arbitrary_callback_data toTrue. The cache that holds the stored data has limited size (more details on memory usage below). If the cache is full and objects from a newInlineKeyboardMarkup need to be stored, it will discard the data for the least recently used keyboard.

This means three things for you:

  1. If you don't usepersistence, buttons won't work after restarting your bot, as the stored updates are lost. More precisely, thecallback_data you will receive is an instance oftelegram.ext.InvalidCallbackData. If you don't need persistence otherwise, you can setstore_callback_data toTrue and all the others toFalse.

  2. If you have a number of keyboards that need to stay valid for a very long time, you might need to do some tweaking manually (see below)

  3. When using theCallbackQueryHandler, thepattern argument can now be either

    • a regex expression, which will be used, if thecallback_data is in fact a string
    • a callable accepting thecallback_data as only argument. You can perform any kinds of tests on thecallback_data and returnTrue orFalse accordingly
    • a type. In that case theCallbackQuery will be handled, if thecallback_data is an instance of that type. Btw: This allows you to inform users, when a buttons' data has been dropped from cache. WithCallbackQueryHandler(callback, pattern=InvalidCallbackData) you can e.g., callawait update.callback_query.answer(text='Button is no longer valid', show_alert=True) to inform the user.

Note

You can of course also manually implement the idea of storing the object in a cache and passing a unique identifier for that object to Telegram, e.g. with the help of PTBstoring data functionality. PTBs built-in "Arbitrarycallback_data" provides this mechanism in a way that requires minimal additional implementation effort on your end and that ties in well with the overall PTB framework.

Memory Usage

PTB stores the callback data objects in memory. Additionally, to that, it stores a mapping ofCallbackQuery.id to the corresponding UUID. By default, both storages contain a maximum number of 1024 items. You can change the size by passing an integer to thearbitrary_callback_data argument ofApplicationBuilder/ExtBot.

As PTB can't know when the stored data is no longer needed, it uses an LRU (Least Recently Used) cache. This means that when the cache is full, it will drop the keyboard that has been not used for the longest time. However, if you want to keep memory usage low, you haveadditional options to drop data:

  • on receiving aCallbackQuery, you can callcontext.drop_callback_data(callback_query). This will delete the data associated with the keyboard attached to the message that originated theCallbackQuery. Callingcontext.drop_callback_data is safe in any case where you change the keyboard, i.e.callback_query.edit_message_text/reply_markup/…Note: If the user clicks a button more than one time fast enough, but you callcontext.drop_callback_data for the first resultingCallbackQuery, the second one will haveInvalidCallbackData ascallback_data. However, this is usually not a problem, because one only wants one button click anyway.
  • To drop more data from memory, you can callbot.callback_data_cache.clear_callback_queries() orbot.callback_data_cache.clear_callback_data(), which will drop the mapping ofCallbackQuery ids to the associated UUID and the mapping of UUIDs to data, respectively.clear_callback_data also accepts atime_cutoff, allowing you to delete only entries older than a specified time.

Security of InlineKeyboardButtons

Callback updates are not sent by Telegram, but by the client. This means that they can be manipulated by a user. (While Telegram unofficially does try to prevent this, they don't want Bot devs to rely on them doing the security checks).

Most of the time, this is not really a problem, sincecallback_data often just isYes,No, etc. However, if the callback data is something likedelete message_id 123, the malicious user could delete any message sent by the bot.

When usingarbitrary_callback_data as described above, PTB replaces the outgoingcallback_data with aUUID, i.e., a random unique identifier. This makes thecallback_data safe: If a malicious client alters the sentCallbackQuery, the invalid UUID can't be resolved. In this caseCallbackQuery.data will be an instance oftelegram.ext.InvalidCallbackData. Note that this is also the case, when the UUIDwas valid, but the data has already been dropped from cache - PTB can't distinguish between the two cases.

Manually handling updates

You may be manually building your updates from JSON-data, e.g., in case you are using a custom webhooks setup. In this case you'll have to make sure that the cached data is inserted back into the buttons yourself, like this:

update=Update.de_json(data,bot)ifbot.arbitrary_callback_data:bot.insert_callback_data(update)

Special note about channel posts

Inline buttons are not only sent, your bot also receives them. In the return value of your bot message, when receiving messages that are replies to messages with an inline keyboard, havemessage.pinned_message or wheremessage.via_bot is your bot (i.e., messages sent via your bot in inline mode). PTB tries very hard to insert the corresponding data back into all those keyboards, where appropriate - i.e., where the keyboard was sent byyour bot and not by another bot. There is however one case, where there is no way to tell that: channel posts have nofrom_user. So unless they have thevia_bot attribute, there is no way to tell, if they were sent by your bot or another one. This means:

If your bot receives a channel post, which asreply_to_message orpinned_message and the latter has a keyboard, but wasnot sent by your bot, allcallback_data will containInvalidCallbackData instances. This is of course unfortunate, but we do have a feeling that the cases where this would complicate things are so rare that it doesn't really matter 😉

Wiki ofpython-telegram-bot © Copyright 2015-2025 – Licensed byCreative Commons

Must read

  1. Introduction to the API
  2. Tutorial: Your first bot
  3. FAQ
  4. How to ask good questions
  5. How to write an MWE

Concepts & Important Elements

  1. Architecture Overview
  2. Builder Pattern forApplication
  3. Types of Handlers
  4. Working with Files and Media
  5. Exceptions, Warnings and Logging
  6. Concurrency in PTB

Notable Features

  1. Advanced Filters
  2. Storing data
  3. Making your bot persistent
  4. Adding Defaults
  5. Job Queue
  6. Arbitrarycallback_data
  7. Avoiding flood limits
  8. Webhooks
  9. Bot API Forward Compatiblity

Code Resources

  1. Frequently requested design patterns
  2. Code snippets
  3. Performance Optimizations
  4. Telegram Passport
  5. Bots built with PTB
  6. Automated Bot Tests

Examples explained

  1. InlineKeyboard Example

Networking

  1. Working Behind a Proxy
  2. Handling network errors

Other resources

  1. Where to host Telegram Bots
  2. How to host your bot
  3. Local API Server
  4. Type Checking with PTB
  5. Press
  6. Notes on GAE
  7. Related Projects
  8. Emoji

Transition Guides

Administration

Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp