Make use of github mkdown alerts and many fixes

Harshil 2023-12-15 18:11:50 +04:00
parent 6800f7ea71
commit d91024aa61
No known key found for this signature in database
GPG key ID: 4AC061E441A1F727
9 changed files with 48 additions and 37 deletions

@ -11,7 +11,7 @@
> ⚠️ Please make sure to read this page in its entirety and in particular the section on [tailor-made concurrency](#tailor-made-concurrency)
PTB is build on top of Pythons [`asyncio`](https://docs.python.org/3/library/asyncio.html), which allows writing concurrent code using the `async`/`await` syntax.
PTB is built on top of Python's [`asyncio`](https://docs.python.org/3/library/asyncio.html), which allows writing concurrent code using the `async`/`await` syntax.
This greatly helps to design code that efficiently uses the wait time during I/O operations like network communication (e.g. sending a message to a user) or reading/writing on the hard drive.
**Note:**
@ -49,7 +49,7 @@ async def process_update(self, update):
## Using concurrency
We want to reply to both *User A* and *User B* as fast as possible and while sending the reply to user *User A* we'd like to already get started on handling *Update B*.
PTB comes with three built-in mechanism that can help with that.
PTB comes with three built-in mechanisms that can help with that.
### `Handler.block`

@ -75,7 +75,8 @@ You may have noticed that when using [`filters.Regex`](https://python-telegram-b
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.
**Note:** The values of the returned dict must be *lists*. This is necessary to make sure that multiple data filters can be merged meaningfully.
> [!IMPORTANT]
> The values of the returned dict must be *lists*. This is necessary to make sure that multiple data filters can be merged meaningfully.
If you want this to work with your custom handler, make sure that `YourHandler.collect_additional_context` does something like

@ -13,9 +13,12 @@ The extension class [`telegram.ext.JobQueue`](https://docs.python-telegram-bot.o
In addition to the tutorial below, there is also the `timerbot.py` example at the [examples directory](https://github.com/python-telegram-bot/python-telegram-bot/tree/master/examples).
# Usage
> :warning: Since v20, you must install PTB with the optional requirement `job-queue`, i.e.
> [!WARNING]
> Since v20, you must install PTB with the optional requirement `job-queue`, i.e.
>
> `pip install 'python-telegram-bot[job-queue]'`
> ```sh
> pip install 'python-telegram-bot[job-queue]'
> ```
The `JobQueue` class is tightly integrated with other `telegram.ext` classes.
@ -83,7 +86,8 @@ 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/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).
> [!CAUTION]
> [`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 [`data`](https://python-telegram-bot.readthedocs.io/telegram.ext.job.html#telegram.ext.Job.params.data), [`chat_id`](https://python-telegram-bot.readthedocs.io/telegram.ext.job.html#telegram.ext.Job.params.chat_id) or [`user_id`](https://python-telegram-bot.readthedocs.io/telegram.ext.job.html#telegram.ext.Job.params.user_id) keyword arguments of `Job`. You can pass any object as a `data` parameter when you launch a `Job` and retrieve it at a later stage as long as the `Job` exists. The `chat_id`/`user_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`/`context.user_data` in the job's `callback`. Let's see how it looks in code:

@ -11,7 +11,8 @@ You can then register handlers of different types in the `Application`, which wi
Every handler is an instance of any subclass of the [`telegram.ext.BaseHandler`](https://docs.python-telegram-bot.org/telegram.ext.basehandler.html#telegram.ext.BaseHandler) class. The library provides [[handler classes for almost all use cases|Types-of-Handlers]], but if you need something very specific, you can also subclass `Handler` yourself.
To begin, you'll need an Access Token. If you have already read and followed [[Introduction to the API|Introduction-to-the-API]], you can use the one you generated then. If not: To generate an Access Token, you have to talk to [@BotFather](https://telegram.me/botfather) and follow a few simple steps (described [here](https://core.telegram.org/bots/features#botfather)). You should really read the introduction first, though.
> [!TIP]
> To begin, you'll need an Access Token. If you have already read and followed [[Introduction to the API|Introduction-to-the-API]], you can use the one you generated then. If not: To generate an Access Token, you have to talk to [@BotFather](https://telegram.me/botfather) and follow a few simple steps (described [here](https://core.telegram.org/bots/features#botfather)). You should really read the introduction first, though.
## Your first Bot, step-by-step
@ -83,7 +84,7 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
The goal is to have this function called every time the Bot receives a Telegram message that contains the `/start` command.
As you can see, this function will receive two parameters: an `update`, which is an object that contains all the information and data that are coming from telegram itself (like the message, the user who issued the command, etc) and a `context`, which is another object that contains information and data about the status of the library itself (like the `Bot`, the `Application`, the `job_queue`, etc).
As you can see, this function will receive two parameters: an `update`, which is an object that contains all the information and data that are coming from Telegram itself (like the message, the user who issued the command, etc) and a `context`, which is another object that contains information and data about the status of the library itself (like the `Bot`, the `Application`, the `job_queue`, etc).
**Related docs:** [`send_message`](https://docs.python-telegram-bot.org/telegram.bot.html#telegram.Bot.send_message), [`telegram.ext.CallbackContext` (the type of the context argument)](https://docs.python-telegram-bot.org/telegram.ext.callbackcontext.html), [`telegram.Update` (the type of update argument)](https://docs.python-telegram-bot.org/telegram.update.html)
@ -133,7 +134,8 @@ if __name__ == '__main__':
From now on, your bot should echo all non-command messages it receives.
**Note:** The `filters` module contains a number of so-called filters that filter incoming messages for text, images, status updates and more. Any message that returns `True` for at least one of the filters passed to `MessageHandler` will be accepted. You can also write your own filters if you want. See more in [[Advanced Filters|Extensions---Advanced-Filters]].
> [!NOTE]
> The `filters` module contains a number of so-called filters that filter incoming messages for text, images, status updates and more. Any message that returns `True` for at least one of the filters passed to `MessageHandler` will be accepted. You can also write your own filters if you want. See more in [[Advanced Filters|Extensions---Advanced-Filters]].
Let's add some actual functionality to your bot. We want to implement a `/caps` command that will take some text as an argument (e.g. `/caps argument`) and reply to it in CAPS. To make things easy, you will receive the arguments (as a `list`, split on spaces) that were passed to a command in the callback function:
@ -153,7 +155,8 @@ if __name__ == '__main__':
application.run_polling()
```
**Note:** Take a look at the usage of [`context.args`](https://docs.python-telegram-bot.org/telegram.ext.callbackcontext.html#telegram.ext.CallbackContext.args). The `CallbackContext` will have several attributes, depending on which handler is used.
> [!NOTE]
> Take a look at the usage of [`context.args`](https://docs.python-telegram-bot.org/telegram.ext.callbackcontext.html#telegram.ext.CallbackContext.args). The `CallbackContext` will have several attributes, depending on which handler is used.
Another cool feature of the Telegram Bot API is the [inline mode](https://core.telegram.org/bots/inline). If you want to implement inline functionality for your bot, please first talk to [@BotFather](https://telegram.me/botfather) and enable inline mode using `/setinline`. It sometimes takes a while until your Bot registers as an inline bot on your client. You might be able to speed up the process by restarting your Telegram App (or sometimes, you just have to wait for a while).
@ -208,11 +211,12 @@ if __name__ == '__main__':
application.run_polling()
```
**Note:** This handler *must* be added last.
If you added it before the other handlers, it would be triggered before the `CommandHandlers` had a chance to look at the update.
Once an update is handled, all further handlers are ignored.
To circumvent this, you can pass the keyword argument `group (int)` to `add_handler` with a value other than 0.
See [`telegram.ext.Application.add_handler`](https://docs.python-telegram-bot.org/telegram.ext.application.html#telegram.ext.Application.add_handler) and [[this wiki page|Frequently-requested-design-patterns#how-to-handle-updates-in-several-handlers]] for details.
> [!IMPORTANT]
> This handler *must* be added last.
> If you added it before the other handlers, it would be triggered before the `CommandHandlers` had a chance to look at the update.
> Once an update is handled, all further handlers are ignored.
> To circumvent this, you can pass the keyword argument `group (int)` to `add_handler` with a value other than 0.
> See [`telegram.ext.Application.add_handler`](https://docs.python-telegram-bot.org/telegram.ext.application.html#telegram.ext.Application.add_handler) and [[this wiki page|Frequently-requested-design-patterns#how-to-handle-updates-in-several-handlers]] for details.
If you're done playing around, stop the bot by pressing `CTRL+C`.

@ -87,7 +87,7 @@ In some cases, using a userbot can help overcome restrictions of the Bot API. Pl
Note that userbots are *not* what python-telegram-bot is for.
Please also note that some methods marked in the Telegram API (aka MTProto) are marked as "usable for bots". This does *not* necessarily mean that they can be used directly via the Bot API.
See [this GitHub thread](https://github.com/tdlib/telegram-bot-api/issues/1#issuecomment-721873231) and [this discusson](https://github.com/tdlib/telegram-bot-api/issues/62) for more info on that.
See [this GitHub thread](https://github.com/tdlib/telegram-bot-api/issues/1#issuecomment-721873231) and [this discussion](https://github.com/tdlib/telegram-bot-api/issues/62) for more info on that.
### I'm using `ConversationHandler` and want one handler to be run multiple times. How do I do that?
@ -107,11 +107,12 @@ If your third-party service requires some other setup for fetching updates, that
### Why am I getting `ImportError: cannot import name 'XY' from 'telegram'`?
There are two common reasons for this kind of exception:
There are three common reasons for this kind of exception:
1. You installed `pip install telegram` instead of `pip install python-telegram-bot`. Run `pip uninstall telegram` to uninstall the [telegram library](https://pypi.org/project/telegram/) and then run `pip install python-telegram-bot` again.
2. You have a file named `telegram.py` or a directory/module named `telegram` in your working directory. This leads to namespace issues.
Rename them to something else.
3. You have misconfigured your python path/environment. Please check that the location listed in `pip show python-telegram-bot` is in your [`PYTHONPATH`](https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH), or your [`sys.path`](https://docs.python.org/3/library/sys.html#sys.path). If not, then you may for e.g. append it to `PYTHONPATH` with `export PYTHONPATH=$PYTHONPATH:/path/to/python-telegram-bot`, or append it to `sys.path` with `sys.path.append('/path/to/python-telegram-bot')`.
### What do the `per_*` settings in `ConversationHandler` do?

@ -39,32 +39,34 @@ Here we simply call the API method [getMe](https://core.telegram.org/bots/api#ge
The `async with bot:` ensures that PTB can properly acquire and release resources.
If you run the file you should get an output along the lines
```pycon
>>> python main.py
User(first_name='Toledo's Palace Bot', is_bot=True, username='ToledosPalaceBot', ...)
```sh
$ python main.py
User(first_name="Toledo's Palace Bot", is_bot=True, username="ToledosPalaceBot", ...)
```
So far so good.
Now we can try and actually do something - let's send a message.
However, bots can't initiate conversations with users.
A user must either add them to a group or send them a message first.
People can use ``telegram.me/<bot_username>`` links or username search to find your bot.
> [!IMPORTANT]
> Bots can't initiate conversations with users.
> A user must either add them to a group or send them a message first.
> People can use ``t.me/<bot_username>`` links or username search to find your bot.
Because of above note, we'll have to first send a message to the bot.
If we've done that, we can fetch the update by refactoring the `main` function in our file with
Because of that restriction, we'll have to first send a message to the bot.
After we've done that, we can fetch the update by refactoring the `main` function in our file with
```python
async def main():
bot = telegram.Bot("TOKEN")
async with bot:
print((await bot.get_updates())[0])
updates = (await bot.get_updates())[0]
print(updates)
```
The output should now look something like this (we abbreviated the output a bit):
```pycon
>>> python main.py
```sh
$ python main.py
Update(message=Message(chat=Chat(first_name='John', id=1234567890, last_name='Doe', ...), from_user=User(first_name='John', id=1234567890, last_name='Doe', ...), text='Hi!', ...), update_id=219017225)
```

@ -56,9 +56,8 @@ You can customize the interval via the [`update_interval`](https://python-telegr
You can also selectively store only some of `{bot,chat,user,callback}_data` by passing a `PersistenceInput` to the `store_data` argument your persistence class.
### ⚠️ Note
Since the persisted data is loaded on start-up, any data written to `Application.{bot, chat, user_data}` *before* startup will hence be overridden! To manually write data into these *after* the persisted data has been loaded, please use [`Application.post_init`](https://docs.python-telegram-bot.org/telegram.ext.applicationbuilder.html?highlight=ApplicationBuilder#telegram.ext.ApplicationBuilder.post_init).
> [!NOTE]
> Since the persisted data is loaded on start-up, any data written to `Application.{bot, chat, user_data}` *before* startup will hence be overridden! To manually write data into these *after* the persisted data has been loaded, please use [`Application.post_init`](https://docs.python-telegram-bot.org/telegram.ext.applicationbuilder.html?highlight=ApplicationBuilder#telegram.ext.ApplicationBuilder.post_init).
## Refreshing at runtime
@ -86,5 +85,5 @@ 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/telegram.ext.basepersistence.html#telegram-ext-basepersistence),
[`PicklePersistence`](https://python-telegram-bot.readthedocs.io/telegram.ext.picklepersistence.html#telegram-ext-picklepersistence)
### ⚠️ Note
Although `PicklePersistence` does the 'placeholder' process described above, all the data are deep copied with `copy.deepcopy` before being handed over to persistence. This means that you should either store only copyable data (e.g. no `telegram.Bot` objects) and/or ensure that your stored data defines appropriate custom deepcopy behavior. This technical detail is described in a note [here](https://docs.python-telegram-bot.org/telegram.ext.application.html#telegram.ext.Application.update_persistence)
> [!NOTE]
> Although `PicklePersistence` does the 'placeholder' process described above, all the data are deep copied with `copy.deepcopy` before being handed over to persistence. This means that you should either store only copyable data (e.g. no `telegram.Bot` objects) and/or ensure that your stored data defines appropriate custom deepcopy behavior. This technical detail is described in a note [here](https://docs.python-telegram-bot.org/telegram.ext.application.html#telegram.ext.Application.update_persistence)

@ -61,7 +61,7 @@ When in doubt, please check the official PTB resources.
* **[How to create a Bot on Codenvy](https://github.com/p92camcj/Tutorial-telegram-bot)** by [p92camcj](https://github.com/p92camcj/Tutorial-telegram-bot)
* [Koding](https://koding.com/)
* [Cloud9](https://c9.io/)
* [Repl.it](https://repl.it/)
* [Replit](https://replit.com/)
* [Glitch](https://glitch.com/)
### Tunnels

@ -22,8 +22,7 @@ Please also check out the [official Telegram API docs](https://core.telegram.org
Let's have a look at how sending a document can be done. In these examples, we'll be using `Bot`'s [`send_document()`](https://python-telegram-bot.readthedocs.io/telegram.bot.html#telegram.Bot.send_document) method.
> **Note:**
>
> [!NOTE]
> In discussion and examples below, we will be using methods of `Bot`, but most of them
> (including [`send_document()`](https://python-telegram-bot.readthedocs.io/telegram.bot.html#telegram.Bot.send_document))
> have shortcut methods in classes like `User`, `Chat` or `Message` that can be more
@ -83,7 +82,8 @@ media_1 = InputMediaDocument(media='https://python-telegram-bot.org/static/testf
media_1 = InputMediaDocument(media=file_id, ...)
```
> Note that for the `InputMedia*` classes, passing a file path only works if your bot is running in [local mode](docs.python-telegram-bot.org/telegram.bot.html#telegram.Bot.params.local_mode).
> [!CAUTION]
> For the `InputMedia*` classes, passing a file path only works if your bot is running in [local mode](docs.python-telegram-bot.org/telegram.bot.html#telegram.Bot.params.local_mode).
### Sending files via inline mode