4 Bot API Forward Compatibility
Bibo-Joshi edited this page 2024-02-08 18:47:48 +01:00

The telegram package contains PTBs Python implementation of the classes and methods defined in the Bot API. This implementation is manually updated whenever Telegram releases a new version of the API. Due to the nature of this open-source library, the implementation work usually takes some time, depending on how much changed. However, users of PTB might want to immediately use the new functionality provided by Telegram. PTB therefore provides mechanism that make exactly this possible, i.e. accessing information from the Bot API that has no native PTB implementation yet. Below, we will describe the mechanisms in detail.

Warning

It is important to note that all these mechanism are intended to be used as temporary solutions only. If you use these mechanisms in your code and then upgrade to a PTB version that adds native support for the new Bot API functionality, you'll have to adapt your code to use PTBs native interfaces instead.

Object Attributes

Receiving Objects

Telegram sends data in the form of JSON objects either for updates that your bot receives or as return value of methods. When Telegram adds new attributes ("fields") to these objects that, the corresponding attributes in PTBs classes will be missing. However, any additional data that is not yet covered by the native Python attributes will be gathered in the TelegramObject.api_kwargs attribute (note that TelegramObject is the base class of (almost) all other classes in the telegram package).

For example, imagine that Telegram adds a new field called read_date to the Message class. Then accessing update.message.read_date is possible only after PTB was updated, however accessing update.message.api_kwargs["read_date"] would give the value provided by Telegram.

Important

TelegramObject.api_kwargs will always contain the raw JSON data received from Telegram. For example, a date will be a simple unix timestamp instead of a timezone aware datetime.datetime object. These kinds of conversions are available only once PTB is updated to the new API version.

As another example, imagine that Telegram adds a new filed called user_online_status_updated to the Update class. Then accessing update.user_online_status_updated is again not immediately possible. Moreover, there is not yet a handler in telegram.ext to handle these new kinds of updates. However, in this case you can e.g. use TypeHandler to catch these updates, like this

from telegram import Update
from telegram.ext import TypeHandler

async def callback(update, context):
    if status_updated := update.api_kwargs.get("user_online_status_updated"):
        print(status_updated)

application.add_handler(TypeHandler(Update, callback))

Of course you can also implement your own subclass of BaseHandler that checks for the presence of the key user_online_status_updated in update.api_kwargs. See also this page.

Sending Objects

The Bot API also receives objects from you, namely as input arguments for the different Bot methods. For example, Bot.set_my_command expects an array of BotCommand objects. If Telegram adds new fields to objects that you send as input to Telegram, the corresponding arguments in PTBs classes will be missing. However, any additional data that is not yet covered by the native Python attributes can be passed via the argument api_kwargs of TelegramObject (note that TelegramObject is the base class of (almost) all other classes in the telegram package).

For example, imagine that Telegram adds a new field called emoji to the BotCommand class such that this emoji is shown somewhere in the chat when the command is selected by the user. Then passing the argument via BotCommand("command", "description", emoji="💥") is possible only after PTB was updated. However, you can already do

BotCommand("command", "description", api_kwargs={"emoji": "💥"})

and PTB will pass the data along to Telegram.

Important

The argument api_kwargs of TelegramObject has the same limitations as the argument api_kwargs of Bot.do_api_request - see below.

Using Bot Methods

New Parameters

All bot methods have a number of parameters defined by Telegram. If Telegram adds new parameters to methods that you can specify, the corresponding arguments in PTBs the methods of telegram.Bot (and the corresponding shortcuts) will be missing. However, any additional data that is not yet covered by the native Python arguments can be passed via the argument api_kwargs of the respective method.

For example, imagine that Telegram adds a new parameter called delete_after to the send_message method such that the message is deleted automatically after the specified time. Then passing the argument via await bot.send_message(chat_id=123, text="Hello!", delete_after=42) is possible only after PTB was updated. However, you can already do

await bot.send_message(chat_id=123, text="Hello!", api_kwargs={"delete_after": 42})

and PTB will pass the data along to Telegram.

Important

The argument api_kwargs of bot methods has the same limitations as the argument api_kwargs of Bot.do_api_request - see below.

New Methods

Sometimes, Telegram adds entirely new methods to the API that you can use to trigger novel functionality. If Telegram adds such a new method, the corresponding method of PTBs class telegram.Bot will be missing. However, PTB provides the method Bot.do_api_request that allows you to make any API call to Telegram.

For example, imagine that Telegram adds a new method called get_message allowing your bot to fetch information about a specific method. Then calling that method via await bot.get_message(chat_id=123, message_id=456) is possible only after PTB was updated. However, you can already do

await bot.do_api_request(
    endpoint="get_message",
    api_kwargs={"message_id": 456, "chat_id": 123},
    return_type=Message
)

and PTB will call the corresponding Bot API method with the given parameters and return the result as a Message object.

Important

The argument api_kwargs will always accept a dictionary with string keys. Note that the type of the values should in general be either

  • JSON serializable (e.g. str, int, list/tuple or dict is str keys) or
  • a object of type TelegramObject (or a subclass) or
  • a datetime.datetime object or
  • an InputFile object

Otherwise, PTB will not be able to correctly pass api_kwargs along to Telegram, or Telegram by not be able to parse the input. For more details on the limitations of api_kwargs, see here.