- Notifications
You must be signed in to change notification settings - Fork5.7k
Transition guide to Version 12.0
- Context based callbacks
- Handler changes
- Filters in handlers
- Persistence
- Return UTC from from_timestamp()
The biggest change in this release is context based callbacks. When running your bot you will probably see a warning like the following:
echobot2.py:62: TelegramDeprecationWarning: Old Handler API is deprecated - see https://git.io/fxJuV for details
This means you're using the old style callbacks and should upgrade to context based callbacks.
The first thing you should do is find where you create yourUpdater
.
updater=Updater('TOKEN')
And adduse_context=True
so it looks like
updater=Updater('TOKEN',use_context=True)
Note that this is only necessary in version 12 ofpython-telegram-bot
. Version 13 will haveuse_context=True
set as default.
If you donot useUpdater
but onlyDispatcher
you should instead setuse_context=True
when you create theDispatcher
.
CallbackContext
is an object that contains all the extra context information regarding anUpdate
, error orJob
. It replaces the old behaviour with having a ton ofpass_something=True
in your handlers. Instead, all this data is available directly on theCallbackContext
- always!So what information is stored on aCallbackContext
? The parameters marked with a star will only be set on specific updates.
- bot
- job_queue
- update_queue
- chat_data*
- user_data*
- job*
- error*
- args*
- matches/match*
Now on to the bulk of the change. You wanna change all your callback functions from the following:
defstart(bot,update,args,job_queue):# Stuff here
to the new style using CallbackContext
defstart(update:Update,context:CallbackContext):# Stuff here# args will be available as context.args# jobqueue will be available as context.jobqueue
On python 2 which doesn't support annotations replaceupdate: Update, context: CallbackContext
with simplyupdate, context
.
Error handler callbacks are the ones added usingDispatcher.add_error_handler
. These have also been changed from the old form:
deferror_callback(bot,update,error):logger.warning('Update "%s" caused error "%s"',update,error)
into
deferror_callback(update,context):logger.warning('Update "%s" caused error "%s"',update,context.error)
Note that the error is now part of theCallbackContext
object.
Job callbacks (the ones that are passed toJobQueue.run_once
and similar) have also changed. Old form:
defjob_callback(bot,job):bot.send_message(SOMEONE,job.context)
New form:
defjob_callback(context):job=context.jobcontext.bot.send_message(SOMEONE,job.context)
Note that both bot, and job have been merged into theCallbackContext
object.
Before version 12, you could both pass_groups and pass_groupdict. InsideCallbackContext
this has been combined into a singleMatch
object. Therefore if your handler looked like this before:
deflike_callback(bot,update,groups,groupdict):# Registered with a RegexHandler with pattern (?i)i (like|dislike) (?P<thing>.*)update.reply_text('You {} {}'.format(groups[1],groupdict['thing'])
It would instead now look something like this:
deflike_callback(update,context):# Registered with a RegexHandler with pattern (?i)i (like|dislike) (?P<thing>.*)update.reply_text('You {} {}'.format(context.match[1],context.match.groupdict()['thing'])
Also seeSpecial note about regex filters.
In version 13 ofpython-telegram-bot
,use_context
will default toTrue
. This means that your old handlers using pass_ will stop working. It also means that after upgrading to version 13, you can removeuse_context=True
from yourUpdater
if you so desire.
This part is only relevant if you've developed custom handlers, that subclasstelegram.ext.Handler
. To support the new context based callbacks, add a method calledcollect_additional_context
to your handler. The method receives aCallbackContext
object and whatever is return bycheck_update()
, and should add whatever extra context is needed (at least everything that could be added viapass_
arguments before). Note thatjob_queue, update_queue, chat_data, user_data
is automatically added by the baseHandler
.
We made some changes to the behaviour of some handlers. Listed below are the changes notable to you and maybe requires some action in your code.
From now onCommandHandler
will only respond tovalid bot commands. It will raiseValueError
when an invalid command is given as thecommand
argument. If you previously used commands not considered valid by @botfather, you can use the newPrefixHandler instead.In additionallow_edited
is deprecated until V13, when it will be removed. The new default behavior is to accept bothmessage
andedited_message
with a valid command. If you would like to exclude edited message from your CommandHandler passfilters=~Filters.update.edited_message
to the constructor.
Newly added is thePrefixHandler
.read the docs for more details on its use and implementation.
MessageHandler
received some upgrades to switch to the filter system. We've removedallow_edited
which has been deprecated for a while. Also we now deprecatedmessage_updates
,channel_post_updates
andedited_updates
in the constructor. The defaults have also changed to acceptingall updates by default. This includes (edited_)channel_posts and (edited_)messages. To tweak the message you receive with MessageHandler, please use theupdate filters.
RegexHandler
is being deprecated. It's basically a MessageHandler with aFilters.regex
, now the CallbackContext contains all match information. For now, we keep it in, but you should switch the use ofRegexHandler
to usingMessageHandler(Filters.regex('pattern'), callback)
.
SeeSpecial note about regex filters andNote about group and groupdict for more details.
The argumentsrun_async_timeout
andtimed_out_behavior
have been removed.The timeout for waiting for a @run_async handler is now always 0. If an update would have waited before, ConversationHandler will now try to use a handler in the new special stateConversationHandler.WAITING
. This allows you to either manually wait in the handler if you want the old functionality, or send a message back to the user like "I am still processing your last request, please wait".
Error handler got a major improvement. Instead of only handling TelegramErrors, every error from every handler will be passed to its callback.
You can use it for example to send yourself notifications if an error happened while your bot is running.
Note: If an error handler callback is successfully executed, the error itself won't be caught by the logger module. If you still want this, reraise the error at the end of your function.
Using a list of filters in a handler like below has been deprecated for a while now. Version 12 removes the ability completely.
MessageHandler([Filters.audio,Filters.video],your_callback)
Instead, you can now combine filters using bitwise operators like below. (The pipe (|
) character means OR, so the below is equivalent to the above example using a list).
# Handle messages that contain EITHER audio or videoMessageHandler(Filters.audio|Filters.video,your_callback)
AND:
# Handle messages that are text AND contain a mentionFilters.text&Filters.entity(MesageEntity.MENTION)
NOT:
# Handle messages that are NOT commands (same as Filters.text in most cases)~Filters.command
More advanced combinations:
# Handle messages that are text and contain a link of some kindFilters.text& (Filters.entity(URL)|Filters.entity(TEXT_LINK))# Handle messages that are text but are not forwardedFilters.text& (~Filters.forwarded)
Regex filters can also be used in advanced combinations like so:
((Filters.regex('(test)')|Filters.command)& (Filters.regex('(it)')|Filters.forwarded))
This would makecontext.matches
equal a list of regex matches, but only if the regex filter actually executed. This means that:
- it will be a list with a single match for
test
if it's a command but not forwarded. - it will be a list with a single match for
it
if it's forwarded but not a command. - it will be a list of two matches. The first one will be
test
and the second oneit
.Note that in the last case, the order is the order that the filters were executed in, and not necessarily left to right.
Also note thatcontext.match
is a shortcut forcontext.matches[0]
. Very useful when you are only interested in the first match.
As ofversion 12.4,Filters.command
checks forMessageEntity.BOT_COMMAND
instead of a leading slash and accordingld,Filters.text
accepts text with a leading slash. UseFilters.text & (~Filters.command)
to filter for text messages that have no commands. For more details, please see thechangelog and the documentation on filters.
In version 12 we introduce persistence to the bot's mechanics. If you want to use this please read thewiki page dedicated to persistence.
from_timestamp() now returns UTC timestamps. The recommended way to work is to run your bot on a machine configured to UTC. This means that from now on.telegram.Message.date
will always be in UTC format.
Wiki ofpython-telegram-bot
© Copyright 2015-2025 – Licensed byCreative Commons
- Architecture Overview
- Builder Pattern for
Application
- Types of Handlers
- Working with Files and Media
- Exceptions, Warnings and Logging
- Concurrency in PTB
- Advanced Filters
- Storing data
- Making your bot persistent
- Adding Defaults
- Job Queue
- Arbitrary
callback_data
- Avoiding flood limits
- Webhooks
- Bot API Forward Compatiblity
- Frequently requested design patterns
- Code snippets
- Performance Optimizations
- Telegram Passport
- Bots built with PTB
- Automated Bot Tests