Update documentation links to be version independent

Hinrich Mahler 2022-05-06 19:27:38 +02:00
parent a1e84cfc14
commit 0ef1016501
20 changed files with 62 additions and 62 deletions

@ -1,5 +1,5 @@
## Introduction
As of version 12.4, PTB supports passing default values for arguments such as `parse_mode` to reduce the need for repetition. For this purpose, the [Defaults](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.defaults.html) class was introduced. This makes it possible to set defaults for often used arguments. These are set at the creation of the bot and are _immutable_.
As of version 12.4, PTB supports passing default values for arguments such as `parse_mode` to reduce the need for repetition. For this purpose, the [Defaults](https://python-telegram-bot.readthedocs.io/telegram.ext.defaults.html) class was introduced. This makes it possible to set defaults for often used arguments. These are set at the creation of the bot and are _immutable_.
## What can be set to a default
* `parse_mode`

@ -62,7 +62,7 @@ application = Application.builder().token(token).context_types(context_types).re
And that's already it!
The docs of [`ApplicationBuilder`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.applicationbuilder.html) have all the info about which "ingredients" it can handle, i.e. which methods it has. Each method will tell you
The docs of [`ApplicationBuilder`](https://python-telegram-bot.readthedocs.io/telegram.ext.applicationbuilder.html) have all the info about which "ingredients" it can handle, i.e. which methods it has. Each method will tell you
* how the parameters will be used (e.g. the token passed to `ApplicationBuilder.token` will be used for the `Bot` available as `Application.bot`)
* What happens if you don't call this method. For most things, PTB will use reasonable defaults.

@ -128,9 +128,9 @@ To catch the incoming message with the location/contact, use `MessageHandler` wi
---
### Message Formatting (bold, italic, code, ...)
Telegram supports some formatting options for text. All the details about what is supported can be found [here](https://core.telegram.org/bots/api#formatting-options). Please keep in mind that you will have to escape the special characters as detailed in the documentation. PTB also offers a [helper function](https://python-telegram-bot.readthedocs.io/en/stable/telegram.utils.helpers.html#telegram.utils.helpers.escape_markdown) for escaping of Markdown text. For escaping of HTML text, you can use [`html.escape`](https://docs.python.org/3/library/html.html?#html.escape) from the standard library.
Telegram supports some formatting options for text. All the details about what is supported can be found [here](https://core.telegram.org/bots/api#formatting-options). Please keep in mind that you will have to escape the special characters as detailed in the documentation. PTB also offers a [helper function](https://python-telegram-bot.readthedocs.io/telegram.utils.helpers.html#telegram.utils.helpers.escape_markdown) for escaping of Markdown text. For escaping of HTML text, you can use [`html.escape`](https://docs.python.org/3/library/html.html?#html.escape) from the standard library.
You can format text with every API method/type that has a `parse_mode` parameter. In addition to editing your text as described in the link above, pass one of the parse modes available through [`telegram.constants.ParseMode`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.constants.html#telegram.constants.ParseMode) to the `parse_mode` parameter. Since the `5.0` update of the Bot API (version `13.1+` of PTB), you can alternatively pass a list of [`telegram.MessageEntities`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.messageentity.html) to the `entities` parameter.
You can format text with every API method/type that has a `parse_mode` parameter. In addition to editing your text as described in the link above, pass one of the parse modes available through [`telegram.constants.ParseMode`](https://python-telegram-bot.readthedocs.io/telegram.constants.html#telegram.constants.ParseMode) to the `parse_mode` parameter. Since the `5.0` update of the Bot API (version `13.1+` of PTB), you can alternatively pass a list of [`telegram.MessageEntities`](https://python-telegram-bot.readthedocs.io/telegram.messageentity.html) to the `entities` parameter.
*Note:* In the API 4.5 update, Telegram introduced MarkdownV2, which supports nested entities and needs other escaping than v1. Markdown V1 is referred as legacy mode by the official API docs, and you should prefer MarkdownV2. Make sure to also use `reply_markdown_v2` instead of `reply_markdown` etc.
@ -156,7 +156,7 @@ await bot.send_message(chat_id=chat_id,
---
#### Message entities
[ᵀᴱᴸᴱᴳᴿᴬᴹ](https://core.telegram.org/bots/api#messageentity)
To use `MessageEntity`, extract the entities and their respective text from a `Message` object using [`parse_entities`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.message.html#telegram.Message.parse_entities).
To use `MessageEntity`, extract the entities and their respective text from a `Message` object using [`parse_entities`](https://python-telegram-bot.readthedocs.io/telegram.message.html#telegram.Message.parse_entities).
**Note:** This method should always be used instead of the ``entities`` attribute, since it calculates the correct substring from the message text based on UTF-16 codepoints - that is, it extracts the correct string even on when working with weird characters such as Emojis.
@ -298,7 +298,7 @@ media_1 = InputMediaDocument(media='https://python-telegram-bot.org/static/testf
media_1 = InputMediaDocument(media=file_id, ...)
```
Please check out the documentation of [`InputMediaAudio`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.inputmediaaudio.html), [`InputMediaDocument`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.inputmediadocument.html), [`InputMediaPhoto`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.inputmediaphoto.html#telegram.InputMediaPhoto) and [`InputMediaVideo`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.inputmediavideo.html#telegram.InputMediaVideo) for the details on required and optional arguments.
Please check out the documentation of [`InputMediaAudio`](https://python-telegram-bot.readthedocs.io/telegram.inputmediaaudio.html), [`InputMediaDocument`](https://python-telegram-bot.readthedocs.io/telegram.inputmediadocument.html), [`InputMediaPhoto`](https://python-telegram-bot.readthedocs.io/telegram.inputmediaphoto.html#telegram.InputMediaPhoto) and [`InputMediaVideo`](https://python-telegram-bot.readthedocs.io/telegram.inputmediavideo.html#telegram.InputMediaVideo) for the details on required and optional arguments.
---
#### Sending files via inline mode

@ -2,7 +2,7 @@ While you program your bot and while the bot is running there can be several thi
# Exceptions
In `python-telegram-bot`, all Telegram-related errors are encapsulated in the `TelegramError` exception class and its subclasses, located in [`telegram.error`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.error.html) module.
In `python-telegram-bot`, all Telegram-related errors are encapsulated in the `TelegramError` exception class and its subclasses, located in [`telegram.error`](https://python-telegram-bot.readthedocs.io/telegram.error.html) module.
Any error, including `TelegramError`, that is raised in one of your handler or job callbacks (or while calling `get_updates` in the `Updater`), is forwarded to all registered error handlers, so you can react to them. You can register an error handler by calling `Application.add_error_handler(callback)`, where `callback` is a coroutine function that takes the `update` and `context`. `update` will be the update that caused the error (or `None` if the error wasn't caused by an update, e.g. for [[Jobs|Extensions--JobQueue]]) and `context.error` the error that was raised.
@ -41,7 +41,7 @@ aps_logger.setLevel(logging.WARNING)
# Warnings
In contrast to exceptions, warnings usually don't indicate that something already did go wrong, but rather that something *could* go wrong or at least could be improved.
Warnings issued by `python-telegram-bot` are encapsulated in `PTBUserWarnang` or one of the subclasses, located in the [`telegram.warnings` module](https://python-telegram-bot.readthedocs.io/en/stable/telegram.warnings.html).
Warnings issued by `python-telegram-bot` are encapsulated in `PTBUserWarnang` or one of the subclasses, located in the [`telegram.warnings` module](https://python-telegram-bot.readthedocs.io/telegram.warnings.html).
This allows you to easily handle the warnings using Pythons [`warnings` library](https://docs.python.org/3/library/warnings.html).
For example, if you don't want to miss any deprecation warning during development, you can tell Python to turn every such warning issued by PTB into an exception via

@ -70,7 +70,7 @@ application.add_handler(awesome_handler)
## `Filters` and `CallbackContext`
You may have noticed that when using [`filters.Regex`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.filters.html#telegram.ext.filters.Regex), the attributes [`context.matches`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.callbackcontext.html#telegram.ext.CallbackContext.matches) and [`context.match`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.callbackcontext.html#telegram.ext.CallbackContext.match) are set to the corresponding matches. To achieve something like this for your custom filter, you can do the following:
You may have noticed that when using [`filters.Regex`](https://python-telegram-bot.readthedocs.io/telegram.ext.filters.html#telegram.ext.filters.Regex), the attributes [`context.matches`](https://python-telegram-bot.readthedocs.io/telegram.ext.callbackcontext.html#telegram.ext.CallbackContext.matches) and [`context.match`](https://python-telegram-bot.readthedocs.io/telegram.ext.callbackcontext.html#telegram.ext.CallbackContext.match) are set to the corresponding matches. To achieve something like this for your custom filter, you can do the following:
1. Set `self.data_filter=True` for your filter.
2. If the update should be handled, return a dictionary of the form `{attribute_name: [values]}`. This dict will be merged with the internal dict of the `context` argument making `value` available as `context.attribute_name`. This currently works with `MessageHandler`, `CommandHandler` and `PrefixHandler`, which are the only handlers that accept filters.

@ -26,7 +26,7 @@ job_queue = application.job_queue
Just know that unless you have a good reason to do so, you should not instantiate `JobQueue` yourself.
Tasks in the job queue are encapsulated by the [`Job`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.job.html#telegram-ext-job) class. It takes a [callback function as a parameter](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.job.html#telegram.ext.Job.params.callback), which will be executed when the time comes. This callback function always takes exactly one parameter: `context`, a [`telegram.ext.CallbackContext`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.callbackcontext.html). Like in the case of handler callbacks used by the `Application`, through this object you can access
Tasks in the job queue are encapsulated by the [`Job`](https://python-telegram-bot.readthedocs.io/telegram.ext.job.html#telegram-ext-job) class. It takes a [callback function as a parameter](https://python-telegram-bot.readthedocs.io/telegram.ext.job.html#telegram.ext.Job.params.callback), which will be executed when the time comes. This callback function always takes exactly one parameter: `context`, a [`telegram.ext.CallbackContext`](https://python-telegram-bot.readthedocs.io/telegram.ext.callbackcontext.html). Like in the case of handler callbacks used by the `Application`, through this object you can access
* `context.bot`, the `Application`'s `telegram.Bot` instance
* `context.job_queue`, the same object as `application.job_queue` above
* and for this particular case you can also access `context.job`, which is the `Job` instance of the task that triggered the callback (more on that later).
@ -51,7 +51,7 @@ job_minute = job_queue.run_repeating(callback_minute, interval=60, first=10)
application.run_polling()
```
The `callback_minute` function will be executed every `60.0` seconds, the first time being after 10 seconds (because of `first=10`). The `interval` and `first` parameters are in seconds if they are `int` or `float`. They can also be `datetime` objects. See the [docs](http://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.jobqueue.html) for detailed explanation.
The `callback_minute` function will be executed every `60.0` seconds, the first time being after 10 seconds (because of `first=10`). The `interval` and `first` parameters are in seconds if they are `int` or `float`. They can also be `datetime` objects. See the [docs](http://python-telegram-bot.readthedocs.io/telegram.ext.jobqueue.html) for detailed explanation.
The return value of these functions are the `Job` objects being created. You don't need to store the result of `run_repeating` (which is the newly instantiated `Job`) if you don't need it; we will make use of it later in this tutorial.
You can also add a job that will be executed only once, with a delay:
@ -79,9 +79,9 @@ job_minute.enabled = False # Temporarily disable this job
job_minute.schedule_removal() # Remove this job completely
```
**Note:** [`schedule_removal`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.job.html#telegram.ext.Job.schedule_removal) does not immediately remove the job from the queue. Instead, it is marked for removal and will be removed as soon as its current interval is over (it will not run again after being marked for removal).
**Note:** [`schedule_removal`](https://python-telegram-bot.readthedocs.io/telegram.ext.job.html#telegram.ext.Job.schedule_removal) does not immediately remove the job from the queue. Instead, it is marked for removal and will be removed as soon as its current interval is over (it will not run again after being marked for removal).
You might want to add jobs in response to certain user input, and there is a convenient way to do that. The `context` argument of your `Handler` callbacks has the `JobQueue` attached as `context.job_queue` ready to be used. Another feature you can use here are the [`context`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.job.html#telegram.ext.Job.params.context) and [`chat_id`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.job.html#telegram.ext.Job.params.chat_id) keyword arguments of `Job`. You can pass any object as a `context` parameter when you launch a `Job` and retrieve it at a later stage as long as the `Job` exists. The `chat_id` parameter allows for an easy way to let the `Job` know which chat we're talking about. This way, we can access `context.chat_data` in the job's `callback`. Let's see how it looks in code:
You might want to add jobs in response to certain user input, and there is a convenient way to do that. The `context` argument of your `Handler` callbacks has the `JobQueue` attached as `context.job_queue` ready to be used. Another feature you can use here are the [`context`](https://python-telegram-bot.readthedocs.io/telegram.ext.job.html#telegram.ext.Job.params.context) and [`chat_id`](https://python-telegram-bot.readthedocs.io/telegram.ext.job.html#telegram.ext.Job.params.chat_id) keyword arguments of `Job`. You can pass any object as a `context` parameter when you launch a `Job` and retrieve it at a later stage as long as the `Job` exists. The `chat_id` parameter allows for an easy way to let the `Job` know which chat we're talking about. This way, we can access `context.chat_data` in the job's `callback`. Let's see how it looks in code:
```python
from telegram import Update

@ -118,7 +118,7 @@ if __name__ == '__main__':
application.run_polling()
```
**Related docs:** [`telegram.ext.MessageHandler`](http://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.messagehandler.html), [`telegram.ext.filters`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.filters.html)
**Related docs:** [`telegram.ext.MessageHandler`](http://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.messagehandler.html), [`telegram.ext.filters`](https://python-telegram-bot.readthedocs.io/telegram.ext.filters.html)
From now on, your bot should echo all non-command messages it receives.

@ -92,7 +92,7 @@ How exactly you get them sadly is beyond the scope of PTB, as that depends on th
If you have a setup for getting the updates, you can put them in your bots update queue via `await application.update_queue.put(your_update)`. The `update_queue` is also available as `context.update_queue`.
Note that `your_update` does *not* need to be an instance of `telegram.Update` - on the contrary! You can e.g. write your own custom class to represent an update from your external service.
To actually do something with the update, you can register a [`TypeHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.typehandler.html). [`StringCommandHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.stringcommandhandler.html) and [`StringRegexHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.stringregexhandler.html) might also be interesting for some use cases.
To actually do something with the update, you can register a [`TypeHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.typehandler.html). [`StringCommandHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.stringcommandhandler.html) and [`StringRegexHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.stringregexhandler.html) might also be interesting for some use cases.
### Why am I getting `ImportError: cannot import name 'XY' from 'telegram'`?

@ -39,13 +39,13 @@ The following sections will give you an idea how to tackle this problem, based o
### Type Handler and Groups
PTB comes with a powerful handler known as [TypeHandler](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.typehandler.html).
PTB comes with a powerful handler known as [TypeHandler](https://python-telegram-bot.readthedocs.io/telegram.ext.typehandler.html).
You can understand it as a generic handler. You can use it to handle any class put through the Updater.
For example, Type Handlers are used in bots to handle "updates" from Github or other external services.
To add any handler, we use [Application.add_handler](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.application.html#telegram.ext.Application.add_handler). Apart from the handler itself, it takes an optional argument called `group`. We can understand groups as numbers which indicate the priority of handlers. A lower group means a higher priority. An update can be processed by (at most) one handler in each group.
To add any handler, we use [Application.add_handler](https://python-telegram-bot.readthedocs.io/telegram.ext.application.html#telegram.ext.Application.add_handler). Apart from the handler itself, it takes an optional argument called `group`. We can understand groups as numbers which indicate the priority of handlers. A lower group means a higher priority. An update can be processed by (at most) one handler in each group.
Stopping handlers in higher groups from processing an update is achieved using [ApplicationHandlerStop](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.ApplicationHandlerStop.html#telegram.ext.ApplicationHandlerStop). When raising this exception, the Application is asked to stop sending the updates to handlers in higher groups. Depending on your use case, you may not need to raise it. But it is useful if you want to enable flood handling or limit who can use the bot.
Stopping handlers in higher groups from processing an update is achieved using [ApplicationHandlerStop](https://python-telegram-bot.readthedocs.io/telegram.ext.ApplicationHandlerStop.html#telegram.ext.ApplicationHandlerStop). When raising this exception, the Application is asked to stop sending the updates to handlers in higher groups. Depending on your use case, you may not need to raise it. But it is useful if you want to enable flood handling or limit who can use the bot.
That's it. With these three knowledge nuggets, we can solve the question given in the introduction.
@ -102,7 +102,7 @@ async def callback(update: Update, context: CallbackContext):
raise ApplicationHandlerStop
```
Here, it should be noted that this approach blocks your bot entirely for a set of users. If all you need is to block a specific functionality, like a special command or privilege, then it will be wise to use [filters.Chat](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.filters.html#telegram.ext.filters.Chat), [filters.User](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.filters.html#telegram.ext.filters.user).
Here, it should be noted that this approach blocks your bot entirely for a set of users. If all you need is to block a specific functionality, like a special command or privilege, then it will be wise to use [filters.Chat](https://python-telegram-bot.readthedocs.io/telegram.ext.filters.html#telegram.ext.filters.Chat), [filters.User](https://python-telegram-bot.readthedocs.io/telegram.ext.filters.html#telegram.ext.filters.user).
Don't forget that you can also use [decorators](https://github.com/python-telegram-bot/python-telegram-bot/wiki/Code-snippets#restrict-access-to-a-handler-decorator) or a simple `if-else` check.
If you want a more streamlined style of managing permissions (like superuser, admin, users) then [ptbcontrib/roles](https://github.com/python-telegram-bot/ptbcontrib/tree/main/ptbcontrib/roles) is worth checking out.
@ -146,7 +146,7 @@ If you feel like this approach is too much of trouble, you can use Python's inbu
## How do I enforce users joining a specific channel before using my bot?
After sending an (invite) link to the channel to the user, you can use [`Bot.get_chat_member`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot.get_chat_member) to check if the user is an that channel.
After sending an (invite) link to the channel to the user, you can use [`Bot.get_chat_member`](https://python-telegram-bot.readthedocs.io/telegram.bot.html#telegram.Bot.get_chat_member) to check if the user is an that channel.
Note that:
- the bot needs to be admin in that channel
@ -155,11 +155,11 @@ Note that:
Otherwise depending on whether the user in the channel, has joined and left again, has been banned, ... (there are multiple situations possible), the method may
- raise an exception and in this case the error message will probably be helpful
- return a [`ChatMember`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.chatmember.html#telegram.ChatMember) instance. In that case make sure to check the [`ChatMember.status`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.chatmember.html#telegram.ChatMember.status) attribute
- return a [`ChatMember`](https://python-telegram-bot.readthedocs.io/telegram.chatmember.html#telegram.ChatMember) instance. In that case make sure to check the [`ChatMember.status`](https://python-telegram-bot.readthedocs.io/telegram.chatmember.html#telegram.ChatMember.status) attribute
Since API 5.1 (PTB v13.4+) you can alternatively use the [`ChatMember`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.chatmemberupdated.html) updates to keep track of users in channels. See [`chatmemberbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/tree/master/examples#chatmemberbotpy) for an example.
Since API 5.1 (PTB v13.4+) you can alternatively use the [`ChatMember`](https://python-telegram-bot.readthedocs.io/telegram.chatmemberupdated.html) updates to keep track of users in channels. See [`chatmemberbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/tree/master/examples#chatmemberbotpy) for an example.
If the user has not yet joined the channel, you can ignore incoming updates from that user or reply to them with a corresponding warning. A convenient way to do that is by using [TypeHandler](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.typehandler.html). Read this [section](#how-do-i-limit-who-can-use-my-bot) to learn how to do it.
If the user has not yet joined the channel, you can ignore incoming updates from that user or reply to them with a corresponding warning. A convenient way to do that is by using [TypeHandler](https://python-telegram-bot.readthedocs.io/telegram.ext.typehandler.html). Read this [section](#how-do-i-limit-who-can-use-my-bot) to learn how to do it.
## How do I send a message to all users of the bot?
@ -167,17 +167,17 @@ Let's first point out an easy alternative solution: Instead of sending the messa
If that doesn't work for you, here we go:
To send a message to all users, you of course need the IDs of all the users. You'll have to keep track of those yourself. The most reliable way for that are the [`my_chat_member`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.chatmemberupdated.html) updates. See [`chatmemberbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/tree/master/examples#chatmemberbotpy) for an example on how to use them.
To send a message to all users, you of course need the IDs of all the users. You'll have to keep track of those yourself. The most reliable way for that are the [`my_chat_member`](https://python-telegram-bot.readthedocs.io/telegram.chatmemberupdated.html) updates. See [`chatmemberbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/tree/master/examples#chatmemberbotpy) for an example on how to use them.
If you didn't keep track of your users from the beginning, you may have a chance to get the IDs anyway, if you're using persistence. Please have a look at [this issue](https://github.com/python-telegram-bot/python-telegram-bot/issues/1836) in that case.
Even if you have all the IDs, you can't know if a user has blocked your bot in the meantime. Therefore, you should make sure to wrap your send request in a `try-except` clause checking for [`telegram.error.Unauthorized`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.error.html#telegram.error.Unauthorized) errors.
Even if you have all the IDs, you can't know if a user has blocked your bot in the meantime. Therefore, you should make sure to wrap your send request in a `try-except` clause checking for [`telegram.error.Unauthorized`](https://python-telegram-bot.readthedocs.io/telegram.error.html#telegram.error.Unauthorized) errors.
Finally, note that Telegram imposes some limits that restrict you to send ~30 Messages per second. If you have a huge user base and try to notify them all at once, you will get flooding errors. To prevent that, try spreading the messages over a long time range. A simple way to achieve that is to leverage the [`JobQueue`](Extensions--JobQueue).
## How do I deal with a media group?
The basic problem behind this question is simple. For the end user, it looks like one message, consisting of several medias, are sent to the receiver. For the bot API/bot developer, this is not the case however: Every media is send as one unique message, only linked via the unique [Message.media_group_id](https://python-telegram-bot.readthedocs.io/en/stable/telegram.message.html#telegram.Message.media_group_id) attribute. So you need some way of determining when to start and to end collecting the media messages.
The basic problem behind this question is simple. For the end user, it looks like one message, consisting of several medias, are sent to the receiver. For the bot API/bot developer, this is not the case however: Every media is send as one unique message, only linked via the unique [Message.media_group_id](https://python-telegram-bot.readthedocs.io/telegram.message.html#telegram.Message.media_group_id) attribute. So you need some way of determining when to start and to end collecting the media messages.
This basic problem has two basic approaches for handling it, without requiring a more elaborate setup involving databases.

@ -84,7 +84,7 @@ A contribution in this direction would be greatly appreciated.
## Stabilizing your app
When a network error occurs, be prepared to catch the [raised exception](https://python-telegram-bot.readthedocs.io/en/stable/telegram.error.html) and handle it according to your policy (do you want to retry? ignore? other?) or use PTBs built-in mechanism for [[exception handling|Exception-Handling]].
When a network error occurs, be prepared to catch the [raised exception](https://python-telegram-bot.readthedocs.io/telegram.error.html) and handle it according to your policy (do you want to retry? ignore? other?) or use PTBs built-in mechanism for [[exception handling|Exception-Handling]].
## PTB
If you think of another way to improve stability from within ptb, please contact us (the maintainers).

@ -16,16 +16,16 @@ if __name__ == '__main__':
```python
updater = Updater("TOKEN")
```
[The first line](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L54) in the main function, it creates an updater instance from the [Updater class](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.updater.html). The "TOKEN" part is where you put the bot token.
[The first line](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L54) in the main function, it creates an updater instance from the [Updater class](https://python-telegram-bot.readthedocs.io/telegram.ext.updater.html). The "TOKEN" part is where you put the bot token.
```python
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CallbackQueryHandler(button))
updater.dispatcher.add_handler(CommandHandler('help', help_command))
```
[Line 56 to 58](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L56-L58) registers our three handlers. The first handler is a [CommandHandler](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.commandhandler.html). Whenever an user sends a /start command to the bot, the function `start` is called. Same situation with the third handler: Whenever an user sends the /help command, `help_command` gets called.
[Line 56 to 58](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L56-L58) registers our three handlers. The first handler is a [CommandHandler](https://python-telegram-bot.readthedocs.io/telegram.ext.commandhandler.html). Whenever an user sends a /start command to the bot, the function `start` is called. Same situation with the third handler: Whenever an user sends the /help command, `help_command` gets called.
The second handler is a [CallbackQueryHandler](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.callbackqueryhandler.html). A [Callbackquery](https://python-telegram-bot.readthedocs.io/en/stable/telegram.callbackquery.html) is what an user sends after he presses an [InlineButton](https://python-telegram-bot.readthedocs.io/en/stable/telegram.inlinekeyboardbutton.html). Every press of a button gets send to the `button` handler.
The second handler is a [CallbackQueryHandler](https://python-telegram-bot.readthedocs.io/telegram.ext.callbackqueryhandler.html). A [Callbackquery](https://python-telegram-bot.readthedocs.io/telegram.callbackquery.html) is what an user sends after he presses an [InlineButton](https://python-telegram-bot.readthedocs.io/telegram.inlinekeyboardbutton.html). Every press of a button gets send to the `button` handler.
```python
updater.start_polling()
@ -44,7 +44,7 @@ Let's start our way through the handlers in the same way we would expect an user
```python
def start(update: Update, context: CallbackContext) -> None:
```
[Line 20](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L20) we define a function called start. It takes the two arguments update (instance of an [Update](https://python-telegram-bot.readthedocs.io/en/stable/telegram.update.html)) and context (instance of a [CallbackContext](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.callbackcontext.html)). The `->` indicates to a type checker that this function returns nothing.
[Line 20](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L20) we define a function called start. It takes the two arguments update (instance of an [Update](https://python-telegram-bot.readthedocs.io/telegram.update.html)) and context (instance of a [CallbackContext](https://python-telegram-bot.readthedocs.io/telegram.ext.callbackcontext.html)). The `->` indicates to a type checker that this function returns nothing.
```python
keyboard = [
@ -66,7 +66,7 @@ reply_markup = InlineKeyboardMarkup(keyboard)
```python
update.message.reply_text('Please choose:', reply_markup=reply_markup)
```
[Line 32](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L32) we reply to the update message with a text (hence [reply_text](https://python-telegram-bot.readthedocs.io/en/stable/telegram.message.html#telegram.Message.reply_text)) and pass the keyboard along in the `reply_markup` argument.
[Line 32](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L32) we reply to the update message with a text (hence [reply_text](https://python-telegram-bot.readthedocs.io/telegram.message.html#telegram.Message.reply_text)) and pass the keyboard along in the `reply_markup` argument.
Now we expect people to press one of the provided buttons, so let's jump to the button callback
## button
@ -79,13 +79,13 @@ def button(update: Update, context: CallbackContext) -> None:
```python
query = update.callback_query
```
[Line 37](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L37) query is defined as a shortcut to access the provided [CallbackQuery](https://python-telegram-bot.readthedocs.io/en/stable/telegram.callbackquery.html). This is the part of the update which has all the information in it, remember, it gets generated/send to the bot once a user presses a button.
[Line 37](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L37) query is defined as a shortcut to access the provided [CallbackQuery](https://python-telegram-bot.readthedocs.io/telegram.callbackquery.html). This is the part of the update which has all the information in it, remember, it gets generated/send to the bot once a user presses a button.
```python
query.answer()
```
[Line 41](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L41) here we answer the `CallbackQuery`. We use a convenient shortcut PTB provides. It takes care of calling the [actual function](https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot.answer_callback_query) and passing all the required parameters to it. If you check out the function, you see that you can pass a `text` argument to it, which will be displayed in a little pop-up on the client end, and if you pass `show_alert` on top of it, the user has to dismiss the pop-up. Not useful for this example, so we just pass it without these optional arguments.
[Line 41](https://github.com/python-telegram-bot/python-telegram-bot/blob/92cb6f3ae8d5c3e49b9019a9348d4408135ffc95/examples/inlinekeyboard.py#L41) here we answer the `CallbackQuery`. We use a convenient shortcut PTB provides. It takes care of calling the [actual function](https://python-telegram-bot.readthedocs.io/telegram.bot.html#telegram.Bot.answer_callback_query) and passing all the required parameters to it. If you check out the function, you see that you can pass a `text` argument to it, which will be displayed in a little pop-up on the client end, and if you pass `show_alert` on top of it, the user has to dismiss the pop-up. Not useful for this example, so we just pass it without these optional arguments.
```python
query.edit_message_text(text=f"Selected option: {query.data}")

@ -1,10 +1,10 @@
## Pure Telegram Bot API
The Bot API is exposed via the [`telegram.Bot`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html) class.
The Bot API is exposed via the [`telegram.Bot`](https://python-telegram-bot.readthedocs.io/telegram.bot.html) class.
The methods are the `snake_case` equivalents of the methods described in the official [Telegram Bot API](https://core.telegram.org/bots/api).
The exact `camelCase` method names as in the Telegram docs are also available for your convenience.
For example, `telegram.Bot.send_message` is the same as `telegram.Bot.sendMessage`.
All the classes of the Bot API can also be found in the `telegram` module, e.g. the `Message` class is available as [`telegram.Message`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.message.html).
All the classes of the Bot API can also be found in the `telegram` module, e.g. the `Message` class is available as [`telegram.Message`](https://python-telegram-bot.readthedocs.io/telegram.message.html).
To generate an Access Token, you have to talk to [BotFather](https://t.me/botfather) and follow a few simple steps (described [here](https://core.telegram.org/bots#6-botfather)).

@ -4,8 +4,8 @@ Bot API 5.0 (and therefore local API server) is supported by PTB since v13.1.
## How to use a local Bot API Server with PTB
* Before you can move your bot from the official server cloud to a self hosted server, you need to call the [`log_out`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot.log_out) method.
* Before moving from one self hosted instance to another, you need to use the [`delete_webhook`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot.delete_webhook) and [`close`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot.close) methods.
* Before you can move your bot from the official server cloud to a self hosted server, you need to call the [`log_out`](https://python-telegram-bot.readthedocs.io/telegram.bot.html#telegram.Bot.log_out) method.
* Before moving from one self hosted instance to another, you need to use the [`delete_webhook`](https://python-telegram-bot.readthedocs.io/telegram.bot.html#telegram.Bot.delete_webhook) and [`close`](https://python-telegram-bot.readthedocs.io/telegram.bot.html#telegram.Bot.close) methods.
* To make PTB aware that you're not using the official server, pass the following to your [`Application`](https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.applicationbuilder.html#telegram.ext.ApplicationBuilder.base_file_url) (or [`Bot`](https://python-telegram-bot.readthedocs.io/en/latest/telegram.bot.html#telegram.Bot.params.base_url)):
* `base_url='your-bot-api-server.com/bot'`
* If you are running a local bot API server without the `--local` flag, also pass:

@ -15,7 +15,7 @@ In V12.0b1 we added a persistence mechanism to `telegram.ext`. This wiki page is
* `ExtBot.callback_data_cache` persistent.
* `Job`'s and the `job_queue` is not supported.
However, the current `JobQueue` backend [APScheduler](https://apscheduler.readthedocs.io/en/stable/) has its own persistence logic that you can leverage.
However, the current `JobQueue` backend [APScheduler](https://apscheduler.readthedocs.io/) has its own persistence logic that you can leverage.
See e.g. [`ptbcontrib/ptb_sqlalchemy_jobstore`](https://github.com/python-telegram-bot/ptbcontrib/tree/main/ptbcontrib/ptb_sqlalchemy_jobstore)
* For a special note about `Bot` instances, see [below](#storing-bots)
@ -50,13 +50,13 @@ For example `ConversationHandler(..., persistent=True, name='my_name')`. `persis
Adding these arguments and adding the conversation handler to a persistence-aware `Application` will make it persistent.
When starting the `Application` with `Application.start()` or `Application.run_{polling, webhook}`, it will automatically update the persistence in regular intervals.
You can customize the interval via the [`update_interval`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.basepersistence.html#telegram.ext.BasePersistence.params.update_interval) argument of `Base/Pickle/Dict/…Persistence`.
You can customize the interval via the [`update_interval`](https://python-telegram-bot.readthedocs.io/telegram.ext.basepersistence.html#telegram.ext.BasePersistence.params.update_interval) argument of `Base/Pickle/Dict/…Persistence`.
## Refreshing at runtime
If your persistence reads the data from an external database, the entries in this database could change at runtime.
This is the case in particular, if the entries in the database are created by a 3rd party service independently of your bot.
If you want to make sure that the data in `context.user/chat/bot_data` are always up-to-date, your persistence class should implement the methods [`refresh_bot/chat/user_data`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.basepersistence.html#telegram.ext.BasePersistence.refresh_chat_data).
If you want to make sure that the data in `context.user/chat/bot_data` are always up-to-date, your persistence class should implement the methods [`refresh_bot/chat/user_data`](https://python-telegram-bot.readthedocs.io/telegram.ext.basepersistence.html#telegram.ext.BasePersistence.refresh_chat_data).
Those will be called when in update comes in, before any of your callbacks are called.
These methods can also be useful to implement a lazy-loading strategy.
@ -75,5 +75,5 @@ For example, it can check if the data equals the attribute `BasePersistence.bot`
When loading the data, the `BasePersistence.bot` can be reinserted instead of the placeholder.
Indeed, this is basically what the built-in `PicklePersistence` does.
For more technical details, please refer to the documentation of [`BasePersistence`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.basepersistence.html#telegram-ext-basepersistence),
[`PicklePersistence`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.picklepersistence.html#telegram-ext-picklepersistence)
For more technical details, please refer to the documentation of [`BasePersistence`](https://python-telegram-bot.readthedocs.io/telegram.ext.basepersistence.html#telegram-ext-basepersistence),
[`PicklePersistence`](https://python-telegram-bot.readthedocs.io/telegram.ext.picklepersistence.html#telegram-ext-picklepersistence)

@ -72,7 +72,7 @@ def main():
...
```
See also: [`migrate_chat_data`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.application.html#telegram.ext.Application.migrate_chat_data)
See also: [`migrate_chat_data`](https://python-telegram-bot.readthedocs.io/telegram.ext.application.html#telegram.ext.Application.migrate_chat_data)
To be entirely sure that the update will be processed by this handler, either add it first or put it in its own group.

@ -79,7 +79,7 @@ Note: For simple testing using `https://example.org` as the callback_url is fine
Note: The documentation for the scope can be found [here](https://core.telegram.org/passport#passportscope). In the example above we are requesting an ID document (like passport, drivers license etc.) that includes a selfie, a document that shows the users' address, and their phone number and email. You can also use [Telegram Passport > Passport example](https://core.telegram.org/passport/example) to figure out the different scope combinations.
### Step 5) Add a MessageHandler that accepts PassportData elements
Now you wanna add a [MessageHandler](https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.messagehandler.html) to your dispatcher so that you are able to receive [Message](https://python-telegram-bot.readthedocs.io/en/latest/telegram.message.html) elements. This is because the [PassportData](https://python-telegram-bot.readthedocs.io/en/latest/telegram.passportdata.html) will be present as an attribute ([passport_data](https://python-telegram-bot.readthedocs.io/en/latest/telegram.message.html#telegram.Message.passport_data)) of [Message](https://python-telegram-bot.readthedocs.io/en/latest/telegram.message.html). If you want to limit a message handler to only receive Telegram Passports (recommended), use the [filters.PASSPORT_DATA ](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.filters.html#telegram.ext.filters.StatusUpdate) filter.
Now you wanna add a [MessageHandler](https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.messagehandler.html) to your dispatcher so that you are able to receive [Message](https://python-telegram-bot.readthedocs.io/en/latest/telegram.message.html) elements. This is because the [PassportData](https://python-telegram-bot.readthedocs.io/en/latest/telegram.passportdata.html) will be present as an attribute ([passport_data](https://python-telegram-bot.readthedocs.io/en/latest/telegram.message.html#telegram.Message.passport_data)) of [Message](https://python-telegram-bot.readthedocs.io/en/latest/telegram.message.html). If you want to limit a message handler to only receive Telegram Passports (recommended), use the [filters.PASSPORT_DATA ](https://python-telegram-bot.readthedocs.io/telegram.ext.filters.html#telegram.ext.filters.StatusUpdate) filter.
In our example folder you will find a [passportbot.py](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/passportbot.py) example bot script. This script will simply decrypt and print all Telegram Passport data that it receives. It will also download all [PassportFiles](https://python-telegram-bot.readthedocs.io/en/latest/telegram.passportfile.html) that it finds to the current directory. To get started with it, replace `TOKEN` with your bot token, and put your `private.key` in the same directory as the script.

@ -186,7 +186,7 @@ Note that in the last case, the order is the order that the filters were execute
Also note that `context.match` is a shortcut for `context.matches[0]`. Very useful when you are only interested in the first match.
### Special note about `Filters.command` and `Filters.text`:
As of **version 12.4**, `Filters.command` checks for `MessageEntity.BOT_COMMAND` instead of a leading slash and accordingld, `Filters.text` accepts text with a leading slash. Use `Filters.text & (~Filters.command)` to filter for text messages that have no commands. For more details, please see the [changelog](https://python-telegram-bot.readthedocs.io/en/stable/changelog.html#version-12-4-0) and the documentation on filters.
As of **version 12.4**, `Filters.command` checks for `MessageEntity.BOT_COMMAND` instead of a leading slash and accordingld, `Filters.text` accepts text with a leading slash. Use `Filters.text & (~Filters.command)` to filter for text messages that have no commands. For more details, please see the [changelog](https://python-telegram-bot.readthedocs.io/changelog.html#version-12-4-0) and the documentation on filters.
***
# Persistence

@ -64,7 +64,7 @@ the new `Bot` instance will be inserted.
Note that changing the used bot token may lead to e.g. `Chat not found` errors.
*Alright, almost all instances. For the limitations, see [`replace_bot`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.basepersistence.html#telegram.ext.BasePersistence.replace_bot) and [`insert_bot`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.basepersistence.html#telegram.ext.BasePersistence.insert_bot).
*Alright, almost all instances. For the limitations, see [`replace_bot`](https://python-telegram-bot.readthedocs.io/telegram.ext.basepersistence.html#telegram.ext.BasePersistence.replace_bot) and [`insert_bot`](https://python-telegram-bot.readthedocs.io/telegram.ext.basepersistence.html#telegram.ext.BasePersistence.insert_bot).
## Converting existing pickle files
@ -91,7 +91,7 @@ As PTB is currently up to date with the Telegram API, this shouldn't affect your
# JobQueue Refactored
Previously, PTB implemented the scheduling of tasks inside the `JobQueue` manually. As timing logic is not always straightforward, maintaining the `JobQueue` was not easy and new features were only reluctantly added. To decrease development effort in that area, we refactored the `JobQueue` in v13. Now, it relies on the third party library [APScheduler](https://apscheduler.readthedocs.io/en/stable/) behind the scenes.
Previously, PTB implemented the scheduling of tasks inside the `JobQueue` manually. As timing logic is not always straightforward, maintaining the `JobQueue` was not easy and new features were only reluctantly added. To decrease development effort in that area, we refactored the `JobQueue` in v13. Now, it relies on the third party library [APScheduler](https://apscheduler.readthedocs.io/) behind the scenes.
But what does this mean for you in detail? If you're scheduling tasks vanilla style as e.g.
@ -119,15 +119,15 @@ That said, here are the perks and changes:
### New features
* `run_repeating` now has a `last` parameter as originally proposed in #1333
* `JobQueue.run_custom` allows you to run a job with a custom scheduling logic. See the APS [User Guide](https://apscheduler.readthedocs.io/en/stable/userguide.html) and the page on [how to combine triggers](https://apscheduler.readthedocs.io/en/stable/modules/triggers/combining.html#module-apscheduler.triggers.combining) for more details.
* All methods `JobQueue.run_*` now have a `job_kwargs` argument that accepts a dictionary. Use this to specify additional kwargs for [`JobQueue.scheduler.add_job()`](https://apscheduler.readthedocs.io/en/stable/modules/schedulers/base.html#apscheduler.schedulers.base.BaseScheduler.add_job).
* Persistence of jobs: APScheduler has it's own logic of persisting jobs. Because of the aforementioned reasons, we decided to not integrate this logic with PTBs own persistence logic (at least for now). You may however set up persistence for jobs yourself. See the APS [User Guide](https://apscheduler.readthedocs.io/en/stable/userguide.html) for details.
* `JobQueue.run_custom` allows you to run a job with a custom scheduling logic. See the APS [User Guide](https://apscheduler.readthedocs.io/userguide.html) and the page on [how to combine triggers](https://apscheduler.readthedocs.io/modules/triggers/combining.html#module-apscheduler.triggers.combining) for more details.
* All methods `JobQueue.run_*` now have a `job_kwargs` argument that accepts a dictionary. Use this to specify additional kwargs for [`JobQueue.scheduler.add_job()`](https://apscheduler.readthedocs.io/modules/schedulers/base.html#apscheduler.schedulers.base.BaseScheduler.add_job).
* Persistence of jobs: APScheduler has it's own logic of persisting jobs. Because of the aforementioned reasons, we decided to not integrate this logic with PTBs own persistence logic (at least for now). You may however set up persistence for jobs yourself. See the APS [User Guide](https://apscheduler.readthedocs.io/userguide.html) for details.
### Changes
Most importantly, the `Job` class is now a wrapper for APSchedulers own `Job` class, i.e. `job.job` is an `apscheduler.job` (don't get confused here!). In particular, attributes like `days`, `interval` and `is_monthly` were removed. Some of those could previously be used to alter the scheduling of the job. You will now have to use `job.job.modify` for that. Please see the [APScheduler docs](https://apscheduler.readthedocs.io/en/stable/modules/job.html#apscheduler.job.Job.modify) for details.
Most importantly, the `Job` class is now a wrapper for APSchedulers own `Job` class, i.e. `job.job` is an `apscheduler.job` (don't get confused here!). In particular, attributes like `days`, `interval` and `is_monthly` were removed. Some of those could previously be used to alter the scheduling of the job. You will now have to use `job.job.modify` for that. Please see the [APScheduler docs](https://apscheduler.readthedocs.io/modules/job.html#apscheduler.job.Job.modify) for details.
There are some other minor changes, most of which will likely not affect you. For details, please see the documentation of [`JobQueue`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.jobqueue.html) and [`Job`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.job.html).
There are some other minor changes, most of which will likely not affect you. For details, please see the documentation of [`JobQueue`](https://python-telegram-bot.readthedocs.io/telegram.ext.jobqueue.html) and [`Job`](https://python-telegram-bot.readthedocs.io/telegram.ext.job.html).
## Setting up a `JobQueue`

@ -14,12 +14,12 @@ application.add_handler(CommandHandler("start", start_callback))
For different kinds of user input, the received `telegram.Update` will have different attributes set. For example an incoming message will result in `update.message` containing the sent message. The pressing an inline button will result in `update.callback_query` being set. To differentiate between all those updates, `telegram.ext` provides
1) [`telegram.ext.MessageHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.messagehandler.html) for all message updates
2) [`telegram.ext.CommandHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.commandhandler.html) for messages with bot commands
3) multiple handlers for all the other different types of updates, e.g. [`telegram.ext.CallbackQueryhandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.callbackqueryhandler.html) for `update.callback_query` and [`telegram.ext.InlineQueryHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.inlinequeryhandler.html) for `update.inline_query`
1) [`telegram.ext.MessageHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.messagehandler.html) for all message updates
2) [`telegram.ext.CommandHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.commandhandler.html) for messages with bot commands
3) multiple handlers for all the other different types of updates, e.g. [`telegram.ext.CallbackQueryhandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.callbackqueryhandler.html) for `update.callback_query` and [`telegram.ext.InlineQueryHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.inlinequeryhandler.html) for `update.inline_query`
4) A few more handlers for more advanced use cases
The special thing about `MessageHandler` is that there is such a vast variety of message types (text, gif, image, document, sticker, …) that it's infeasible to provide a different `Handler` for each type. Instead `MessageHandler` is coupled with so called [filters](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.filters.html) that allow to make fine-grained distinctions: `MessageHandler(filters.ALL, callback)` will handle all updates that contain
The special thing about `MessageHandler` is that there is such a vast variety of message types (text, gif, image, document, sticker, …) that it's infeasible to provide a different `Handler` for each type. Instead `MessageHandler` is coupled with so called [filters](https://python-telegram-bot.readthedocs.io/telegram.ext.filters.html) that allow to make fine-grained distinctions: `MessageHandler(filters.ALL, callback)` will handle all updates that contain
* `update.message`
* `update.edited_message`
@ -61,7 +61,7 @@ Also, since this is an URL parameter, you have to pay attention on how to correc
## Pattern matching: `filters.Regex`
For more complex inputs you can employ the [`telegram.ext.MessageHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.messagehandler.html) with [`telegram.ext.filters.Regex`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.filters.html#telegram.ext.filters.Regex), which internally uses the `re`-module to match textual user input with a supplied pattern.
For more complex inputs you can employ the [`telegram.ext.MessageHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.messagehandler.html) with [`telegram.ext.filters.Regex`](https://python-telegram-bot.readthedocs.io/telegram.ext.filters.html#telegram.ext.filters.Regex), which internally uses the `re`-module to match textual user input with a supplied pattern.
Keep in mind that for extracting URLs, #Hashtags, @Mentions, and other Telegram entities, there's no need to parse them with a regex filter because the Bot API already sends them to us with every update. Refer to [[this snippet|Code-snippets#message-entities]] to learn how to work with entities instead.
@ -71,8 +71,8 @@ This tutorial only covers some of the available handlers (for now). Refer to the
In some cases, it's useful to handle updates that are not from Telegram. E.g. you might want to handle notifications from a 3rd party service and forward them to your users. For such use cases, PTB provides
* [`TypeHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.typehandler.html)
* [`StringCommandHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.stringcommandhandler.html)
* [`StringRegexHandler`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.stringregexhandler.html)
* [`TypeHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.typehandler.html)
* [`StringCommandHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.stringcommandhandler.html)
* [`StringRegexHandler`](https://python-telegram-bot.readthedocs.io/telegram.ext.stringregexhandler.html)
See also this [FAQ entry](https://github.com/python-telegram-bot/python-telegram-bot/wiki/Frequently-Asked-Questions#i-want-to-handle-updates-from-an-external-service-in-addition-to-the-telegram-updates-how-do-i-do-that)

@ -22,7 +22,7 @@ proxy_url = 'http://USERNAME:PASSWORD@PROXY_HOST:PROXY_PORT' # can also be a ht
app = ApplicationBuilder().token("TOKEN").proxy_url(proxy_url).get_updates_proxy_url(proxy_url).build()
```
In the last line, we setup the proxy such that it'll be used both for making requests to the Bot API like `Bot.send_message` ([`proxy_url()`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.applicationbuilder.html#telegram.ext.ApplicationBuilder.proxy_url)) and for fetching updates from Telegram ([`get_updates_proxy_url`](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.applicationbuilder.html#telegram.ext.ApplicationBuilder.get_updates_proxy_url)). It is not necessary to setup a proxy for both, you can do it for either of them.
In the last line, we setup the proxy such that it'll be used both for making requests to the Bot API like `Bot.send_message` ([`proxy_url()`](https://python-telegram-bot.readthedocs.io/telegram.ext.applicationbuilder.html#telegram.ext.ApplicationBuilder.proxy_url)) and for fetching updates from Telegram ([`get_updates_proxy_url`](https://python-telegram-bot.readthedocs.io/telegram.ext.applicationbuilder.html#telegram.ext.ApplicationBuilder.get_updates_proxy_url)). It is not necessary to setup a proxy for both, you can do it for either of them.
# Working Behind a Socks5 Server
This configuration is supported, but requires an optional/extra python package.