mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 23:55:29 +00:00
Compare commits
385 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1902c0ac36 | |||
| 544a3fbf48 | |||
| 36d49ea9cd | |||
| 25506f131d | |||
| 70aba136e4 | |||
| 40995b19fe | |||
| 32da6d6fce | |||
| f31787a8ef | |||
| b43a599e53 | |||
| 7a3fd83570 | |||
| 9ada2a7cca | |||
| be54cf4ece | |||
| 0c9915243d | |||
| 9930725e2a | |||
| ffd675daec | |||
| 6a831f926b | |||
| 6903d58142 | |||
| 07b6ee69d2 | |||
| c8a3c31dcc | |||
| 91e0271e4c | |||
| 9ddb361f76 | |||
| 89c522d883 | |||
| 2effff8254 | |||
| 2788191657 | |||
| aec6d3bada | |||
| 80b34811ab | |||
| 2d7a974b8f | |||
| ef703d19e9 | |||
| 77a8c64f6c | |||
| 786762bb73 | |||
| e0dbb99b08 | |||
| 73b0e29a30 | |||
| d27d1ea4d5 | |||
| ca04daf782 | |||
| ae9ce60b55 | |||
| 1cd3a0a156 | |||
| 58b9882021 | |||
| df6d5f0840 | |||
| 425716f966 | |||
| 8d9bb26cca | |||
| d1438a9b23 | |||
| 27b03edc59 | |||
| ac449deb5d | |||
| 3b9187ed5a | |||
| 9831458e22 | |||
| a0cd6e8fef | |||
| 8e7c0d6976 | |||
| 92b9370c23 | |||
| 237e73bfb4 | |||
| ff3fd34f08 | |||
| 83791d34e7 | |||
| 02cd7b642f | |||
| 165a24e13d | |||
| 88440079e3 | |||
| 9be4c7563b | |||
| b554f1a85d | |||
| 3b4559dd95 | |||
| 9ae48fecfe | |||
| 6af6648509 | |||
| 264b2c9c72 | |||
| 8efb05290a | |||
| 83a8874bb5 | |||
| bf68942c91 | |||
| 5fd7606084 | |||
| 103b115486 | |||
| b07e42ef33 | |||
| 3842846b2d | |||
| 7daddfb54d | |||
| 2d4d48b89d | |||
| 2381724b7c | |||
| 19a4f9e53a | |||
| 3930072659 | |||
| 5555582b72 | |||
| e67b995e64 | |||
| 0d419ed6b4 | |||
| 97adcdf538 | |||
| 2989108e95 | |||
| 897a20d758 | |||
| ed3a9b64e2 | |||
| 49c0c9e4d1 | |||
| bb34c79909 | |||
| a0720b9ac6 | |||
| faa93fbf75 | |||
| da452df07d | |||
| 3304cc5c90 | |||
| 9105d83d37 | |||
| b6b42b2043 | |||
| f857e1c23b | |||
| fc5844c13d | |||
| dea24bcb7c | |||
| 2789fd2bff | |||
| d6f8077a50 | |||
| 0189442525 | |||
| fd0325fbe5 | |||
| ff4bb15fef | |||
| 9288e4f2e4 | |||
| e60318166e | |||
| 15268acb27 | |||
| 927502e588 | |||
| 0af5cc2db8 | |||
| 6005861f46 | |||
| 8406889179 | |||
| a4e78f6183 | |||
| 8c6cb44a85 | |||
| ac7cc7fe5e | |||
| a42b68933c | |||
| c2d91c752f | |||
| 5057825586 | |||
| 613175b2c4 | |||
| 1330696259 | |||
| 5898e1fe7a | |||
| b6dec118c1 | |||
| 186fd1b418 | |||
| 284786fdb8 | |||
| c7c56ad24e | |||
| ae17ce977e | |||
| 7e231183c4 | |||
| 8427346a0d | |||
| 632b989d90 | |||
| 76567ba635 | |||
| 2bd3f2a65a | |||
| 26a5006bf1 | |||
| 110e2df443 | |||
| 57546795c5 | |||
| 314f87ec44 | |||
| 4bbcd51ef5 | |||
| 38a33581b1 | |||
| fe821c08e6 | |||
| 0a9f4bfbdd | |||
| c4364c7166 | |||
| d63e710784 | |||
| f379f54d5a | |||
| bdf0cb91f3 | |||
| 3101ea8432 | |||
| beb8ba3db0 | |||
| f0b1aeb6fd | |||
| d65558888e | |||
| 61a66a32c8 | |||
| 392d4e1a9c | |||
| 9cb34af65a | |||
| e9cb6675ca | |||
| 982f6707e1 | |||
| d55d981e22 | |||
| f20953f7a9 | |||
| e18220be10 | |||
| 90729c21d7 | |||
| 55e3ecf9f8 | |||
| 8d2c7af1f3 | |||
| e86ae25a62 | |||
| 2d3357bfeb | |||
| b6f4783fd3 | |||
| f94ea9acbb | |||
| 157652cfdf | |||
| 104d0127aa | |||
| e0b22e60b4 | |||
| 16613d7ce0 | |||
| eac7f02211 | |||
| 28ded6718e | |||
| 13a641b3d7 | |||
| 27cccc7734 | |||
| f7ec7a7c4c | |||
| 8d6970ab02 | |||
| 1dc67dcbda | |||
| 14f712b3c4 | |||
| 0fb0fbb93f | |||
| 72ecc696cb | |||
| a447760411 | |||
| 6da529c46b | |||
| bd1b2fb6c1 | |||
| f9a8cd924c | |||
| 7b3b278c7c | |||
| cf3635d408 | |||
| 84cfc6f7fa | |||
| bf06fa2c18 | |||
| 960c7a0c70 | |||
| bacabbe767 | |||
| d8dcdeea75 | |||
| 818475bd93 | |||
| f97ac90af7 | |||
| 90eeb40ae8 | |||
| 6d9d11b8bd | |||
| f6b663f175 | |||
| 43bfebb150 | |||
| 743e2fce07 | |||
| 4c2a3d07ce | |||
| 423794f473 | |||
| a397e6c3c6 | |||
| 7cde6ca268 | |||
| 408062dd43 | |||
| d96d233dc5 | |||
| 3eb2cef600 | |||
| 0b87f4b274 | |||
| 0df526d390 | |||
| cb9af36937 | |||
| fbb7e0e645 | |||
| d9d65cc2ac | |||
| 62f514f068 | |||
| 08bbeca8ec | |||
| 38b9f4b9bc | |||
| 3d59b2f581 | |||
| e3c8466e41 | |||
| 1d92f52c6a | |||
| 33280a7fe0 | |||
| 4b5ba15d31 | |||
| d2466f1e6e | |||
| 883c6b5901 | |||
| 1e7f4fae6f | |||
| dae5ab47a0 | |||
| a9d9b1d750 | |||
| 90496f70a5 | |||
| 940b42e048 | |||
| a582515766 | |||
| 3d42df3366 | |||
| 2c67a9833b | |||
| 5e8a961669 | |||
| a5ba64becb | |||
| 2a3169a22f | |||
| 894d8281ab | |||
| 2fdf48023b | |||
| 4e717a172b | |||
| 10c9ec2313 | |||
| 096a7c3593 | |||
| e9d9f01bd4 | |||
| 8b4b22cc89 | |||
| b294c92bad | |||
| 264de2b7c1 | |||
| ac64027580 | |||
| 34bdbc632a | |||
| bbcff96804 | |||
| 93449443b2 | |||
| 8cdb20a85a | |||
| 6fddb49af5 | |||
| b0aef0c718 | |||
| 88eccc6608 | |||
| 3d8771bbdf | |||
| 7152b5aaf9 | |||
| 98147fce32 | |||
| e54e9f2347 | |||
| 3545139dd7 | |||
| d0c27e2d46 | |||
| 3318239cf6 | |||
| aadb6df271 | |||
| 2cc9aac7dc | |||
| 1d007b1b60 | |||
| 3257148d13 | |||
| 805a798b50 | |||
| e60a42010b | |||
| ae88129f0f | |||
| 3812251dac | |||
| e1193425ca | |||
| ccf5e6c692 | |||
| 32dd415fb8 | |||
| f13aeaa2a1 | |||
| 4cd07361d1 | |||
| b38a1840b2 | |||
| fba3cc90d9 | |||
| 965ad17af8 | |||
| d5399de99b | |||
| 280306d1e9 | |||
| c84e21d8eb | |||
| 738e5a0784 | |||
| ec6dc7fa10 | |||
| b71196dad3 | |||
| 425912da4a | |||
| 2c92c356b8 | |||
| f379a34ccd | |||
| 4328eaefb2 | |||
| 79dc6edf25 | |||
| c7e9281068 | |||
| edad6e8b53 | |||
| 7eb7c30741 | |||
| 3ae14dda80 | |||
| ac60d057a5 | |||
| e492d5b97b | |||
| 3afb0ae6c3 | |||
| 179cf14bd8 | |||
| a1eabc0cae | |||
| 5e90231f4e | |||
| 2cb6377dab | |||
| 316d046628 | |||
| 5e0e4c01ff | |||
| 24546bda67 | |||
| d70577b9cf | |||
| 3fc57479f3 | |||
| e11efa2e5b | |||
| d84551134b | |||
| cebd2d6a86 | |||
| 725c21b88d | |||
| 9d005d5124 | |||
| 2cde878d1e | |||
| 984bea16d1 | |||
| 474ff8ae41 | |||
| 2ed4cbd26d | |||
| 7944805627 | |||
| b5891a6a61 | |||
| df813c46e1 | |||
| 36a74da4f4 | |||
| 0c10c537f7 | |||
| 26ce9bb343 | |||
| 39d686b1a1 | |||
| 60f2044bbd | |||
| dda7ca18cd | |||
| 07c51d236b | |||
| 9f1eccf569 | |||
| cd7c642f49 | |||
| f7abb21323 | |||
| 7e2dbdd4b3 | |||
| b64698e4b6 | |||
| d0936f76ad | |||
| da342af7ed | |||
| 446c54cf8d | |||
| f5bfe2f29c | |||
| b02b68880f | |||
| 2c5eade4f0 | |||
| 950ec35970 | |||
| d33e1d9913 | |||
| 2e203e41e4 | |||
| e54a3188ce | |||
| 710f43a23a | |||
| 27b757df32 | |||
| 66e43c5932 | |||
| 7fcbfc19f5 | |||
| a60c07f549 | |||
| 1b52e6148e | |||
| 487bce18dd | |||
| 5c45e469d5 | |||
| 25e5449e97 | |||
| a8bade4d73 | |||
| e08afe7fb2 | |||
| 9817310788 | |||
| ed33c4a7a9 | |||
| 1ee53e9e17 | |||
| 3e8d71582d | |||
| c03160c07f | |||
| 23fe991b85 | |||
| 7eeb670a59 | |||
| f23298a13b | |||
| 92f407bfb3 | |||
| 0cf0cccbc5 | |||
| 378784f55e | |||
| 384173115f | |||
| ea5b301b59 | |||
| 9b66681ee4 | |||
| 92e7427689 | |||
| f82ceee777 | |||
| d2e2fe9ccc | |||
| 76a72e9742 | |||
| cf69a234d4 | |||
| eaf6dc2b88 | |||
| 9596343efd | |||
| 30cc0f8cf9 | |||
| f252436cd4 | |||
| c9630ee8c5 | |||
| 9d99660ba9 | |||
| eca0ccf6b3 | |||
| 9ece7fdb1c | |||
| 4861d1a20d | |||
| dbf364e168 | |||
| d6d0dec6e0 | |||
| 0bbca65a95 | |||
| 1d715f0d36 | |||
| f6f8667d6c | |||
| 8731365911 | |||
| d9ae4be2b3 | |||
| b5a3d7852a | |||
| 3d8ab23d66 | |||
| 6c36316aed | |||
| 4c66ba3a8d | |||
| c714a177d1 | |||
| 3829666a53 | |||
| 9c1b493f37 | |||
| af2d716129 | |||
| 5252a493cb | |||
| e75615cbf6 | |||
| cf95027308 | |||
| 439790375e | |||
| b9f56ca479 | |||
| e247fa7c2c | |||
| b8c288ff4a | |||
| bbe633e571 | |||
| f2b06728e9 | |||
| b2fb4264a3 | |||
| 19591c955a | |||
| 259a1faedc | |||
| 09bdb88822 |
+47
-11
@@ -25,7 +25,7 @@ Setting things up
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo pip install -r requirements.txt -r requirements-dev.txt
|
||||
$ pip install -r requirements.txt -r requirements-dev.txt
|
||||
|
||||
|
||||
5. Install pre-commit hooks:
|
||||
@@ -41,7 +41,9 @@ If you already know what you'd like to work on, you can skip this section.
|
||||
|
||||
If you have an idea for something to do, first check if it's already been filed on the `issue tracker`_. If so, add a comment to the issue saying you'd like to work on it, and we'll help you get started! Otherwise, please file a new issue and assign yourself to it.
|
||||
|
||||
Another great way to start contributing is by writing tests. Tests are really important because they help prevent developers from accidentally breaking existing code, allowing them to build cool things faster. If you're interested in helping out, let the development team know by posting to the `developers' mailing list`_, and we'll help you get started.
|
||||
Another great way to start contributing is by writing tests. Tests are really important because they help prevent developers from accidentally breaking existing code, allowing them to build cool things faster. If you're interested in helping out, let the development team know by posting to the `Telegram group`_ (use `@admins` to mention the maintainers), and we'll help you get started.
|
||||
|
||||
That being said, we want to mention that we are very hesitant about adding new requirements to our projects. If you intend to do this, please state this in an issue and get a verification from one of the maintainers.
|
||||
|
||||
Instructions for making a code change
|
||||
#####################################
|
||||
@@ -67,12 +69,38 @@ Here's how to make a one-off code change.
|
||||
|
||||
- Your code should adhere to the `PEP 8 Style Guide`_, with the exception that we have a maximum line length of 99.
|
||||
|
||||
- For consistency, please conform to `Google Python Style Guide`_ and `Google Python Style Docstrings`_. In addition, code should be formatted consistently with other code around it.
|
||||
- Provide static typing with signature annotations. The documentation of `MyPy`_ will be a good start, the cheat sheet is `here`_. We also have some custom type aliases in ``telegram.utils.helpers.typing``.
|
||||
|
||||
- Document your code. This project uses `sphinx`_ to generate static HTML docs. To build them, first make sure you have the required dependencies:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install -r docs/requirements-docs.txt
|
||||
|
||||
then run the following from the PTB root directory:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ make -C docs html
|
||||
|
||||
or, if you don't have ``make`` available (e.g. on Windows):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sphinx-build docs/source docs/build/html
|
||||
|
||||
Once the process terminates, you can view the built documentation by opening ``docs/build/html/index.html`` with a browser.
|
||||
|
||||
- Add ``.. versionadded:: version``, ``.. versionchanged:: version`` or ``.. deprecated:: version`` to the associated documentation of your changes, depending on what kind of change you made. This only applies if the change you made is visible to an end user. The directives should be added to class/method descriptions if their general behaviour changed and to the description of all arguments & attributes that changed.
|
||||
|
||||
- For consistency, please conform to `Google Python Style Guide`_ and `Google Python Style Docstrings`_.
|
||||
|
||||
- The following exceptions to the above (Google's) style guides applies:
|
||||
|
||||
- Documenting types of global variables and complex types of class members can be done using the Sphinx docstring convention.
|
||||
|
||||
- In addition, PTB uses the `Black`_ coder formatting. Plugins for Black exist for some `popular editors`_. You can use those instead of manually formatting everything.
|
||||
|
||||
- Please ensure that the code you write is well-tested.
|
||||
|
||||
- Don’t break backward compatibility.
|
||||
@@ -91,6 +119,14 @@ Here's how to make a one-off code change.
|
||||
|
||||
$ pytest -v
|
||||
|
||||
To run ``test_official`` (particularly useful if you made API changes), run
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ export TEST_OFFICIAL=true
|
||||
|
||||
prior to running the tests.
|
||||
|
||||
- To actually make the commit (this will trigger tests for yapf, lint and pep8 automatically):
|
||||
|
||||
.. code-block:: bash
|
||||
@@ -157,11 +193,6 @@ Here's how to make a one-off code change.
|
||||
Style commandments
|
||||
------------------
|
||||
|
||||
Specific commandments
|
||||
#####################
|
||||
|
||||
- Avoid using "double quotes" where you can reasonably use 'single quotes'.
|
||||
|
||||
Assert comparison order
|
||||
#######################
|
||||
|
||||
@@ -215,8 +246,13 @@ break the API classes. For example:
|
||||
|
||||
.. _`Code of Conduct`: https://www.python.org/psf/codeofconduct/
|
||||
.. _`issue tracker`: https://github.com/python-telegram-bot/python-telegram-bot/issues
|
||||
.. _`developers' mailing list`: mailto:devs@python-telegram-bot.org
|
||||
.. _`Telegram group`: https://telegram.me/pythontelegrambotgroup
|
||||
.. _`PEP 8 Style Guide`: https://www.python.org/dev/peps/pep-0008/
|
||||
.. _`Google Python Style Guide`: https://google-styleguide.googlecode.com/svn/trunk/pyguide.html
|
||||
.. _`Google Python Style Docstrings`: http://sphinx-doc.org/latest/ext/example_google.html
|
||||
.. _`sphinx`: http://sphinx-doc.org
|
||||
.. _`Google Python Style Guide`: http://google.github.io/styleguide/pyguide.html
|
||||
.. _`Google Python Style Docstrings`: https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html
|
||||
.. _AUTHORS.rst: ../AUTHORS.rst
|
||||
.. _`MyPy`: https://mypy.readthedocs.io/en/stable/index.html
|
||||
.. _`here`: https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html
|
||||
.. _`Black`: https://black.readthedocs.io/en/stable/index.html
|
||||
.. _`popular editors`: https://black.readthedocs.io/en/stable/editor_integration.html
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[BUG]"
|
||||
labels: 'bug :bug:'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Thanks for reporting issues of python-telegram-bot!
|
||||
|
||||
Use this template to notify us if you found a bug, or if you want to request a new feature.
|
||||
If you're looking for help with programming your bot using our library, feel free to ask your
|
||||
questions in out telegram group at: https://t.me/pythontelegrambotgroup
|
||||
Use this template to notify us if you found a bug.
|
||||
|
||||
To make it easier for us to help you please enter detailed information below.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Telegram Group
|
||||
url: https://telegram.me/pythontelegrambotgroup
|
||||
about: Questions asked on the group usually get answered faster.
|
||||
- name: IRC Channel
|
||||
url: https://webchat.freenode.net/?channels=##python-telegram-bot
|
||||
about: In case you are unable to join our group due to Telegram restrictions, you can use our IRC channel
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: "[FEATURE]"
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Is your feature request related to a problem? Please describe.
|
||||
A clear and concise description of what the problem is.
|
||||
Ex. *I want to do X, but there is no way to do it.*
|
||||
|
||||
#### Describe the solution you'd like
|
||||
A clear and concise description of what you want to happen.
|
||||
Ex. *I think it would be nice if you would add feature Y so it will make it easier.*
|
||||
|
||||
#### Describe alternatives you've considered
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
Ex. *I considered Z, but that didn't work because...*
|
||||
|
||||
#### Additional context
|
||||
Add any other context or screenshots about the feature request here.
|
||||
Ex. *Here's a photo of my cat!*
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: Question
|
||||
about: Get help with errors or general questions
|
||||
title: "[QUESTION]"
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Hey there, you have a question? We are happy to answer. Please make sure no similar question was opened already.
|
||||
|
||||
To make it easier for us to help you, please read this article https://git.io/JURJO and try to follow the template below as closely as possible.
|
||||
|
||||
Please mind that there is also a users' Telegram group at https://t.me/pythontelegrambotgroup for questions about the library. Questions asked there might be answered quicker than here. In case you are unable to join our group due to Telegram restrictions, you can use our IRC channel at https://webchat.freenode.net/?channels=##python-telegram-bot to participate in the group.
|
||||
-->
|
||||
|
||||
### Issue I am facing
|
||||
Please describe the issue here in as much detail as possible
|
||||
|
||||
### Traceback to the issue
|
||||
```
|
||||
put it here
|
||||
```
|
||||
|
||||
### Related part of your code
|
||||
```python
|
||||
put it here
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
<!--
|
||||
Hey! You're PRing? Cool! Please have a look at the below checklist. It's here to help both you and the maintainers to remember some aspects. Make sure to check out our contribution guide (https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.github/CONTRIBUTING.rst).
|
||||
-->
|
||||
|
||||
### Checklist for PRs
|
||||
|
||||
- [ ] Added `.. versionadded:: version`, `.. versionchanged:: version` or `.. deprecated:: version` to the docstrings for user facing changes (for methods/class descriptions, arguments and attributes)
|
||||
- [ ] Created new or adapted existing unit tests
|
||||
- [ ] Added myself alphabetically to `AUTHORS.rst` (optional)
|
||||
|
||||
|
||||
### If the PR contains API changes (otherwise, you can delete this passage)
|
||||
|
||||
* New classes:
|
||||
- [ ] Added `self._id_attrs` and corresponding documentation
|
||||
- [ ] `__init__` accepts `**_kwargs`
|
||||
|
||||
* Added new shortcuts:
|
||||
- [ ] In `Chat` & `User` for all methods that accept `chat/user_id`
|
||||
- [ ] In `Message` for all methods that accept `chat_id` and `message_id`
|
||||
- [ ] For new `Message` shortcuts: Added `quote` argument if methods accepts `reply_to_message_id`
|
||||
- [ ] In `CallbackQuery` for all methods that accept either `chat_id` and `message_id` or `inline_message_id`
|
||||
|
||||
* If relevant:
|
||||
|
||||
- [ ] Added new constants at `telegram.constants` and shortcuts to them as class variables
|
||||
- [ ] Added new handlers for new update types
|
||||
- [ ] Added new filters for new message (sub)types
|
||||
- [ ] Added or updated documentation for the changed class(es) and/or method(s)
|
||||
- [ ] Updated the Bot API version number in all places in `README.rst` and `README_RAW.rst`, including the badge
|
||||
@@ -0,0 +1,14 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 3
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 2
|
||||
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
|
||||
onlyLabels: question
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking as stale. Set to `false` to disable
|
||||
markComment: false
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been automatically closed due to inactivity. Feel free to comment in order to reopen
|
||||
or ask again in our Telegram support group at https://t.me/pythontelegrambotgroup.
|
||||
@@ -0,0 +1,14 @@
|
||||
name: Warning maintainers
|
||||
on:
|
||||
pull_request:
|
||||
paths: examples/**
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
name: about example change
|
||||
steps:
|
||||
- name: running the check
|
||||
uses: Poolitzer/notifier-action@master
|
||||
with:
|
||||
notify-message: Hey there. Relax, I am just a little warning for the maintainers to release directly after merging your PR, otherwise we have broken examples and people might get confused :)
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,18 @@
|
||||
name: 'Lock Closed Threads'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '8 4 * * *'
|
||||
- cron: '42 17 * * *'
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2.0.1
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: '1'
|
||||
issue-lock-reason: ''
|
||||
pr-lock-inactive-days: '1'
|
||||
pr-lock-reason: ''
|
||||
@@ -0,0 +1,16 @@
|
||||
name: Warning maintainers
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- README.rst
|
||||
- README_RAW.rst
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
name: about readme change
|
||||
steps:
|
||||
- name: running the check
|
||||
uses: Poolitzer/notifier-action@master
|
||||
with:
|
||||
notify-message: Hey! Looks like you edited README.rst or README_RAW.rst. I'm just a friendly reminder to apply relevant changes to both of those files :)
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,115 @@
|
||||
name: GitHub Actions
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
pytest:
|
||||
name: pytest
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
python-version: 3.7
|
||||
test-build: True
|
||||
- os: windows-latest
|
||||
python-version: 3.7
|
||||
test-build: True
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Initialize vendored libs
|
||||
run:
|
||||
git submodule update --init --recursive
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -U codecov pytest-cov
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pytest -v -m nocoverage
|
||||
nocov_exit=$?
|
||||
pytest -v -m "not nocoverage" --cov
|
||||
cov_exit=$?
|
||||
global_exit=$(( nocov_exit > cov_exit ? nocov_exit : cov_exit ))
|
||||
exit ${global_exit}
|
||||
env:
|
||||
JOB_INDEX: ${{ strategy.job-index }}
|
||||
BOTS: W3sidG9rZW4iOiAiNjk2MTg4NzMyOkFBR1Z3RUtmSEhsTmpzY3hFRE5LQXdraEdzdFpfa28xbUMwIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WldGaU1UUmxNbVF5TnpNeSIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIENQeXRob24gMi43IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMzkwOTgzOTk3IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzI3X2JvdCJ9LCB7InRva2VuIjogIjY3MTQ2ODg4NjpBQUdQR2ZjaVJJQlVORmU4MjR1SVZkcTdKZTNfWW5BVE5HdyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpHWXdPVGxrTXpNeE4yWTIiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ0NjAyMjUyMiIsICJib3RfdXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8zNF9ib3QifSwgeyJ0b2tlbiI6ICI2MjkzMjY1Mzg6QUFGUnJaSnJCN29CM211ekdzR0pYVXZHRTVDUXpNNUNVNG8iLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpNbU01WVdKaFl6a3hNMlUxIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgQ1B5dGhvbiAzLjUiLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDE0OTY5MTc3NTAiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfdHJhdmlzX2NweXRob25fMzVfYm90In0sIHsidG9rZW4iOiAiNjQwMjA4OTQzOkFBRmhCalFwOXFtM1JUeFN6VXBZekJRakNsZS1Kano1aGNrIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WXpoa1pUZzFOamMxWXpWbCIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIENQeXRob24gMy42IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMzMzODcxNDYxIiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzM2X2JvdCJ9LCB7InRva2VuIjogIjY5NTEwNDA4ODpBQUhmenlsSU9qU0lJUy1lT25JMjB5MkUyMEhvZEhzZnotMCIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk9HUTFNRGd3WmpJd1pqRmwiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNyIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ3ODI5MzcxNCIsICJib3RfdXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8zN19ib3QifSwgeyJ0b2tlbiI6ICI2OTE0MjM1NTQ6QUFGOFdrakNaYm5IcVBfaTZHaFRZaXJGRWxackdhWU9oWDAiLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpZamM1TlRoaU1tUXlNV1ZoIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgUHlQeSAyLjciLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEzNjM5MzI1NzMiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfdHJhdmlzX3B5cHlfMjdfYm90In0sIHsidG9rZW4iOiAiNjg0MzM5OTg0OkFBRk1nRUVqcDAxcjVyQjAwN3lDZFZOc2c4QWxOc2FVLWNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TVRBek1UWTNNR1V5TmpnMCIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIFB5UHkgMy41IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDA3ODM2NjA1IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19weXB5XzM1X2JvdCJ9LCB7InRva2VuIjogIjY5MDA5MTM0NzpBQUZMbVI1cEFCNVljcGVfbU9oN3pNNEpGQk9oMHozVDBUbyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpEaGxOekU1TURrd1lXSmkiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIEFwcFZleW9yIHVzaW5nIENQeXRob24gMy40IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMjc5NjAwMDI2IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX2FwcHZleW9yX2NweXRob25fMzRfYm90In0sIHsidG9rZW4iOiAiNjk0MzA4MDUyOkFBRUIyX3NvbkNrNTVMWTlCRzlBTy1IOGp4aVBTNTVvb0JBIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WW1aaVlXWm1NakpoWkdNeSIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gQXBwVmV5b3IgdXNpbmcgQ1B5dGhvbiAyLjciLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEyOTMwNzkxNjUiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfYXBwdmV5b3JfY3B5dGhvbl8yN19ib3QifSwgeyJ0b2tlbiI6ICIxMDU1Mzk3NDcxOkFBRzE4bkJfUzJXQXd1SjNnN29oS0JWZ1hYY2VNbklPeVNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpBd056QXpZalZpTkdOayIsICJuYW1lIjogIlBUQiB0ZXN0cyBbMF0iLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDExODU1MDk2MzYiLCAidXNlcm5hbWUiOiAicHRiXzBfYm90In0sIHsidG9rZW4iOiAiMTA0NzMyNjc3MTpBQUY4bk90ODFGcFg4bGJidno4VWV3UVF2UmZUYkZmQnZ1SSIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOllUVTFOVEk0WkdSallqbGkiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzFdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDg0Nzk3NjEyIiwgInVzZXJuYW1lIjogInB0Yl8xX2JvdCJ9LCB7InRva2VuIjogIjk3MTk5Mjc0NTpBQUdPa09hVzBOSGpnSXY1LTlqUWJPajR2R3FkaFNGLVV1cyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk5XWmtNV1ZoWWpsallqVTUiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzJdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDAyMjU1MDcwIiwgInVzZXJuYW1lIjogInB0Yl8yX2JvdCJ9XQ==
|
||||
TEST_BUILD: ${{ matrix.test-build }}
|
||||
TEST_PRE_COMMIT: ${{ matrix.test-pre-commit }}
|
||||
shell: bash --noprofile --norc {0}
|
||||
|
||||
- name: Submit coverage
|
||||
uses: codecov/codecov-action@v1.0.13
|
||||
with:
|
||||
env_vars: OS,PYTHON
|
||||
name: ${{ matrix.os }}-${{ matrix.python-version }}
|
||||
fail_ci_if_error: true
|
||||
test_official:
|
||||
name: test-official
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Initialize vendored libs
|
||||
run:
|
||||
git submodule update --init --recursive
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
- name: Compare to official api
|
||||
run: |
|
||||
pytest -v tests/test_official.py
|
||||
exit $?
|
||||
env:
|
||||
TEST_OFFICIAL: "true"
|
||||
shell: bash --noprofile --norc {0}
|
||||
test_pre_commit:
|
||||
name: test-pre-commit
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Initialize vendored libs
|
||||
run:
|
||||
git submodule update --init --recursive
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
- name: Run pre-commit tests
|
||||
run: pre-commit run --all-files
|
||||
+10
@@ -23,6 +23,11 @@ var/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
.env
|
||||
.pybuild
|
||||
debian/tmp
|
||||
debian/python3-telegram
|
||||
debian/python3-telegram-doc
|
||||
debian/.debhelper
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
@@ -41,6 +46,7 @@ htmlcov/
|
||||
.coverage.*
|
||||
.cache
|
||||
.pytest_cache
|
||||
.mypy_cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
@@ -64,6 +70,7 @@ target/
|
||||
*.sublime*
|
||||
|
||||
# unitests files
|
||||
game.gif
|
||||
telegram.mp3
|
||||
telegram.mp4
|
||||
telegram2.mp4
|
||||
@@ -77,3 +84,6 @@ telegram.jpg
|
||||
|
||||
# Exclude .exrc file for Vim
|
||||
.exrc
|
||||
|
||||
# virtual env
|
||||
venv*
|
||||
|
||||
+26
-12
@@ -1,20 +1,34 @@
|
||||
- repo: git://github.com/python-telegram-bot/mirrors-yapf
|
||||
sha: master
|
||||
# Make sure that
|
||||
# * the revs specified here match requirements-dev.txt
|
||||
# * the makefile checks the same files as pre-commit
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 20.8b1
|
||||
hooks:
|
||||
- id: yapf
|
||||
files: ^(telegram|tests)/.*\.py$
|
||||
- id: black
|
||||
args:
|
||||
- --diff
|
||||
- repo: git://github.com/pre-commit/pre-commit-hooks
|
||||
sha: v1.2.0
|
||||
- --check
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.8.4
|
||||
hooks:
|
||||
- id: flake8
|
||||
exclude: ^(setup.py|docs/source/conf.py)$
|
||||
- repo: git://github.com/pre-commit/mirrors-pylint
|
||||
sha: v1.7.1
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: pylint-2.6.0
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^telegram/.*\.py$
|
||||
files: ^(telegram|examples)/.*\.py$
|
||||
args:
|
||||
- --errors-only
|
||||
- --disable=import-error
|
||||
- --rcfile=setup.cfg
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.790
|
||||
hooks:
|
||||
- id: mypy
|
||||
files: ^(telegram|examples)/.*\.py$
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.7.4
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
files: ^(telegram|examples|tests)/.*\.py$
|
||||
args:
|
||||
- --py36-plus
|
||||
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- "3.7-dev"
|
||||
- "pypy-5.7.1"
|
||||
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
- $HOME/.pre-commit
|
||||
before_cache:
|
||||
- rm -f $HOME/.cache/pip/log/debug.log
|
||||
- rm -f $HOME/.pre-commit/pre-commit.log
|
||||
|
||||
install:
|
||||
- pip install -U codecov pytest-cov
|
||||
- echo $TRAVIS_PYTHON_VERSION
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.7'* ]]; then pip install -U git+https://github.com/yaml/pyyaml.git; fi
|
||||
- pip install -U -r requirements.txt
|
||||
- pip install -U -r requirements-dev.txt
|
||||
- if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then pip install ujson; fi
|
||||
|
||||
script:
|
||||
- pytest -v -m nocoverage
|
||||
- pytest -v -m "not nocoverage" --cov
|
||||
|
||||
after_success:
|
||||
- coverage combine
|
||||
- codecov -F Travis
|
||||
+30
-1
@@ -2,10 +2,13 @@ Credits
|
||||
=======
|
||||
|
||||
``python-telegram-bot`` was originally created by
|
||||
`Leandro Toledo <https://github.com/leandrotoledo>`_ and is now maintained by
|
||||
`Leandro Toledo <https://github.com/leandrotoledo>`_ and is now maintained by `Hinrich Mahler <https://github.com/Bibo-Joshi>`_.
|
||||
Emeritus maintainers include
|
||||
`Jannes Höke <https://github.com/jh0ker>`_ (`@jh0ker <https://t.me/jh0ker>`_ on Telegram),
|
||||
`Noam Meltzer <https://github.com/tsnoam>`_, `Pieter Schutz <https://github.com/eldinnie>`_ and `Jasmin Bom <https://github.com/jsmnbom>`_.
|
||||
|
||||
The maintainers are actively supported by `Poolitzer <https://github.com/Poolitzer>`_ in terms of development and community liaison.
|
||||
|
||||
We're vendoring urllib3 as part of ``python-telegram-bot`` which is distributed under the MIT
|
||||
license. For more info, full credits & license terms, the sources can be found here:
|
||||
`https://github.com/python-telegram-bot/urllib3`.
|
||||
@@ -16,20 +19,32 @@ Contributors
|
||||
The following wonderful people contributed directly or indirectly to this project:
|
||||
|
||||
- `Alateas <https://github.com/alateas>`_
|
||||
- `Ales Dokshanin <https://github.com/alesdokshanin>`_
|
||||
- `Ambro17 <https://github.com/Ambro17>`_
|
||||
- `Andrej Zhilenkov <https://github.com/Andrej730>`_
|
||||
- `Anton Tagunov <https://github.com/anton-tagunov>`_
|
||||
- `Avanatiker <https://github.com/Avanatiker>`_
|
||||
- `Balduro <https://github.com/Balduro>`_
|
||||
- `Bibo-Joshi <https://github.com/Bibo-Joshi>`_
|
||||
- `bimmlerd <https://github.com/bimmlerd>`_
|
||||
- `d-qoi <https://github.com/d-qoi>`_
|
||||
- `daimajia <https://github.com/daimajia>`_
|
||||
- `Daniel Reed <https://github.com/nmlorg>`_
|
||||
- `D David Livingston <https://github.com/daviddl9>`_
|
||||
- `Eana Hufwe <https://github.com/blueset>`_
|
||||
- `Ehsan Online <https://github.com/ehsanonline>`_
|
||||
- `Eli Gao <https://github.com/eligao>`_
|
||||
- `Emilio Molinari <https://github.com/xates>`_
|
||||
- `ErgoZ Riftbit Vaper <https://github.com/ergoz>`_
|
||||
- `Eugene Lisitsky <https://github.com/lisitsky>`_
|
||||
- `Eugenio Panadero <https://github.com/azogue>`_
|
||||
- `Evan Haberecht <https://github.com/habereet>`_
|
||||
- `Evgeny Denisov <https://github.com/eIGato>`_
|
||||
- `evgfilim1 <https://github.com/evgfilim1>`_
|
||||
- `franciscod <https://github.com/franciscod>`_
|
||||
- `gamgi <https://github.com/gamgi>`_
|
||||
- `Gauthamram Ravichandran <https://github.com/GauthamramRavichandran>`_
|
||||
- `Harshil <https://github.com/harshil21>`_
|
||||
- `Hugo Damer <https://github.com/HakimusGIT>`_
|
||||
- `ihoru <https://github.com/ihoru>`_
|
||||
- `Jasmin Bom <https://github.com/jsmnbom>`_
|
||||
@@ -42,13 +57,18 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Joscha Götzer <https://github.com/Rostgnom>`_
|
||||
- `jossalgon <https://github.com/jossalgon>`_
|
||||
- `JRoot3D <https://github.com/JRoot3D>`_
|
||||
- `Kirill Vasin <https://github.com/vasinkd>`_
|
||||
- `Kjwon15 <https://github.com/kjwon15>`_
|
||||
- `Li-aung Yip <https://github.com/LiaungYip>`_
|
||||
- `Loo Zheng Yuan <https://github.com/loozhengyuan>`_
|
||||
- `LRezende <https://github.com/lrezende>`_
|
||||
- `macrojames <https://github.com/macrojames>`_
|
||||
- `Matheus Lemos <https://github.com/mlemosf>`_
|
||||
- `Michael Elovskikh <https://github.com/wronglink>`_
|
||||
- `Mischa Krüger <https://github.com/Makman2>`_
|
||||
- `naveenvhegde <https://github.com/naveenvhegde>`_
|
||||
- `neurrone <https://github.com/neurrone>`_
|
||||
- `NikitaPirate <https://github.com/NikitaPirate>`_
|
||||
- `njittam <https://github.com/njittam>`_
|
||||
- `Noam Meltzer <https://github.com/tsnoam>`_
|
||||
- `Oleg Shlyazhko <https://github.com/ollmer>`_
|
||||
@@ -58,16 +78,25 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Patrick Hofmann <https://github.com/PH89>`_
|
||||
- `Paul Larsen <https://github.com/PaulSonOfLars>`_
|
||||
- `Pieter Schutz <https://github.com/eldinnie>`_
|
||||
- `Poolitzer <https://github.com/Poolitzer>`_
|
||||
- `Pranjalya Tiwari <https://github.com/Pranjalya>`_
|
||||
- `Rahiel Kasim <https://github.com/rahiel>`_
|
||||
- `Riko Naka <https://github.com/rikonaka>`_
|
||||
- `Rizlas <https://github.com/rizlas>`_
|
||||
- `Sahil Sharma <https://github.com/sahilsharma811>`_
|
||||
- `Sascha <https://github.com/saschalalala>`_
|
||||
- `Shelomentsev D <https://github.com/shelomentsevd>`_
|
||||
- `Simon Schürrle <https://github.com/SitiSchu>`_
|
||||
- `sooyhwang <https://github.com/sooyhwang>`_
|
||||
- `syntx <https://github.com/syntx>`_
|
||||
- `thodnev <https://github.com/thodnev>`_
|
||||
- `Timur Kushukov <https://github.com/timqsh>`_
|
||||
- `Trainer Jono <https://github.com/Tr-Jono>`_
|
||||
- `Valentijn <https://github.com/Faalentijn>`_
|
||||
- `voider1 <https://github.com/voider1>`_
|
||||
- `Vorobjev Simon <https://github.com/simonvorobjev>`_
|
||||
- `Wagner Macedo <https://github.com/wagnerluis1982>`_
|
||||
- `wjt <https://github.com/wjt>`_
|
||||
- `zeshuaro <https://github.com/zeshuaro>`_
|
||||
|
||||
Please add yourself here alphabetically when you submit your first pull request.
|
||||
|
||||
+810
-25
@@ -1,9 +1,781 @@
|
||||
=======
|
||||
Changes
|
||||
=======
|
||||
=========
|
||||
Changelog
|
||||
=========
|
||||
|
||||
**2018-08-29**
|
||||
*Released 11.0.0*
|
||||
Version 13.2
|
||||
============
|
||||
*Released 2021-02-02*
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Introduce ``python-telegram-bot-raw`` (`#2324`_)
|
||||
- Explicit Signatures for Shortcuts (`#2240`_)
|
||||
|
||||
**New Features:**
|
||||
|
||||
- Add Missing Shortcuts to ``Message`` (`#2330`_)
|
||||
- Rich Comparison for ``Bot`` (`#2320`_)
|
||||
- Add ``run_async`` Parameter to ``ConversationHandler`` (`#2292`_)
|
||||
- Add New Shortcuts to ``Chat`` (`#2291`_)
|
||||
- Add New Constant ``MAX_ANSWER_CALLBACK_QUERY_TEXT_LENGTH`` (`#2282`_)
|
||||
- Allow Passing Custom Filename For All Media (`#2249`_)
|
||||
- Handle Bytes as File Input (`#2233`_)
|
||||
|
||||
**Bug Fixes:**
|
||||
|
||||
- Fix Escaping in Nested Entities in ``Message`` Properties (`#2312`_)
|
||||
- Adjust Calling of ``Dispatcher.update_persistence`` (`#2285`_)
|
||||
- Add ``quote`` kwarg to ``Message.reply_copy`` (`#2232`_)
|
||||
- ``ConversationHandler``: Docs & ``edited_channel_post`` behavior (`#2339`_)
|
||||
|
||||
**Minor changes, CI improvements, doc fixes and type hinting:**
|
||||
|
||||
- Doc Fixes (`#2253`_, `#2225`_)
|
||||
- Reduce Usage of ``typing.Any`` (`#2321`_)
|
||||
- Extend Deeplinking Example (`#2335`_)
|
||||
- Add pyupgrade to pre-commit Hooks (`#2301`_)
|
||||
- Add PR Template (`#2299`_)
|
||||
- Drop Nightly Tests & Update Badges (`#2323`_)
|
||||
- Update Copyright (`#2289`_, `#2287`_)
|
||||
- Change Order of Class DocStrings (`#2256`_)
|
||||
- Add macOS to Test Matrix (`#2266`_)
|
||||
- Start Using Versioning Directives in Docs (`#2252`_)
|
||||
- Improve Annotations & Docs of Handlers (`#2243`_)
|
||||
|
||||
.. _`#2324`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2324
|
||||
.. _`#2240`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2240
|
||||
.. _`#2330`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2330
|
||||
.. _`#2320`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2320
|
||||
.. _`#2292`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2292
|
||||
.. _`#2291`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2291
|
||||
.. _`#2282`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2282
|
||||
.. _`#2249`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2249
|
||||
.. _`#2233`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2233
|
||||
.. _`#2312`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2312
|
||||
.. _`#2285`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2285
|
||||
.. _`#2232`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2232
|
||||
.. _`#2339`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2339
|
||||
.. _`#2253`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2253
|
||||
.. _`#2225`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2225
|
||||
.. _`#2321`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2321
|
||||
.. _`#2335`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2335
|
||||
.. _`#2301`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2301
|
||||
.. _`#2299`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2299
|
||||
.. _`#2323`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2323
|
||||
.. _`#2289`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2289
|
||||
.. _`#2287`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2287
|
||||
.. _`#2256`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2256
|
||||
.. _`#2266`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2266
|
||||
.. _`#2252`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2252
|
||||
.. _`#2243`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2243
|
||||
|
||||
Version 13.1
|
||||
============
|
||||
*Released 2020-11-29*
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Full support of Bot API 5.0 (`#2181`_, `#2186`_, `#2190`_, `#2189`_, `#2183`_, `#2184`_, `#2188`_, `#2185`_, `#2192`_, `#2196`_, `#2193`_, `#2223`_, `#2199`_, `#2187`_, `#2147`_, `#2205`_)
|
||||
|
||||
**New Features:**
|
||||
|
||||
- Add ``Defaults.run_async`` (`#2210`_)
|
||||
- Improve and Expand ``CallbackQuery`` Shortcuts (`#2172`_)
|
||||
- Add XOR Filters and make ``Filters.name`` a Property (`#2179`_)
|
||||
- Add ``Filters.document.file_extension`` (`#2169`_)
|
||||
- Add ``Filters.caption_regex`` (`#2163`_)
|
||||
- Add ``Filters.chat_type`` (`#2128`_)
|
||||
- Handle Non-Binary File Input (`#2202`_)
|
||||
|
||||
**Bug Fixes:**
|
||||
|
||||
- Improve Handling of Custom Objects in ``BasePersistence.insert``/``replace_bot`` (`#2151`_)
|
||||
- Fix bugs in ``replace/insert_bot`` (`#2218`_)
|
||||
|
||||
**Minor changes, CI improvements, doc fixes and type hinting:**
|
||||
|
||||
- Improve Type hinting (`#2204`_, `#2118`_, `#2167`_, `#2136`_)
|
||||
- Doc Fixes & Extensions (`#2201`_, `#2161`_)
|
||||
- Use F-Strings Where Possible (`#2222`_)
|
||||
- Rename kwargs to _kwargs where possible (`#2182`_)
|
||||
- Comply with PEP561 (`#2168`_)
|
||||
- Improve Code Quality (`#2131`_)
|
||||
- Switch Code Formatting to Black (`#2122`_, `#2159`_, `#2158`_)
|
||||
- Update Wheel Settings (`#2142`_)
|
||||
- Update ``timerbot.py`` to ``v13.0`` (`#2149`_)
|
||||
- Overhaul Constants (`#2137`_)
|
||||
- Add Python 3.9 to Test Matrix (`#2132`_)
|
||||
- Switch Codecov to ``GitHub`` Action (`#2127`_)
|
||||
- Specify Required pytz Version (`#2121`_)
|
||||
|
||||
|
||||
.. _`#2181`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2181
|
||||
.. _`#2186`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2186
|
||||
.. _`#2190`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2190
|
||||
.. _`#2189`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2189
|
||||
.. _`#2183`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2183
|
||||
.. _`#2184`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2184
|
||||
.. _`#2188`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2188
|
||||
.. _`#2185`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2185
|
||||
.. _`#2192`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2192
|
||||
.. _`#2196`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2196
|
||||
.. _`#2193`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2193
|
||||
.. _`#2223`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2223
|
||||
.. _`#2199`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2199
|
||||
.. _`#2187`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2187
|
||||
.. _`#2147`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2147
|
||||
.. _`#2205`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2205
|
||||
.. _`#2210`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2210
|
||||
.. _`#2172`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2172
|
||||
.. _`#2179`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2179
|
||||
.. _`#2169`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2169
|
||||
.. _`#2163`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2163
|
||||
.. _`#2128`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2128
|
||||
.. _`#2202`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2202
|
||||
.. _`#2151`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2151
|
||||
.. _`#2218`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2218
|
||||
.. _`#2204`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2204
|
||||
.. _`#2118`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2118
|
||||
.. _`#2167`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2167
|
||||
.. _`#2136`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2136
|
||||
.. _`#2201`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2201
|
||||
.. _`#2161`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2161
|
||||
.. _`#2222`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2222
|
||||
.. _`#2182`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2182
|
||||
.. _`#2168`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2168
|
||||
.. _`#2131`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2131
|
||||
.. _`#2122`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2122
|
||||
.. _`#2159`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2159
|
||||
.. _`#2158`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2158
|
||||
.. _`#2142`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2142
|
||||
.. _`#2149`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2149
|
||||
.. _`#2137`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2137
|
||||
.. _`#2132`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2132
|
||||
.. _`#2127`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2127
|
||||
.. _`#2121`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2121
|
||||
|
||||
Version 13.0
|
||||
============
|
||||
*Released 2020-10-07*
|
||||
|
||||
**For a detailed guide on how to migrate from v12 to v13, see this** `wiki page <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Transition-guide-to-Version-13.0>`_.
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Deprecate old-style callbacks, i.e. set ``use_context=True`` by default (`#2050`_)
|
||||
- Refactor Handling of Message VS Update Filters (`#2032`_)
|
||||
- Deprecate ``Message.default_quote`` (`#1965`_)
|
||||
- Refactor persistence of Bot instances (`#1994`_)
|
||||
- Refactor ``JobQueue`` (`#1981`_)
|
||||
- Refactor handling of kwargs in Bot methods (`#1924`_)
|
||||
- Refactor ``Dispatcher.run_async``, deprecating the ``@run_async`` decorator (`#2051`_)
|
||||
|
||||
**New Features:**
|
||||
|
||||
- Type Hinting (`#1920`_)
|
||||
- Automatic Pagination for ``answer_inline_query`` (`#2072`_)
|
||||
- ``Defaults.tzinfo`` (`#2042`_)
|
||||
- Extend rich comparison of objects (`#1724`_)
|
||||
- Add ``Filters.via_bot`` (`#2009`_)
|
||||
- Add missing shortcuts (`#2043`_)
|
||||
- Allow ``DispatcherHandlerStop`` in ``ConversationHandler`` (`#2059`_)
|
||||
- Make Errors picklable (`#2106`_)
|
||||
|
||||
**Minor changes, CI improvements, doc fixes or bug fixes:**
|
||||
|
||||
- Fix Webhook not working on Windows with Python 3.8+ (`#2067`_)
|
||||
- Fix setting thumbs with ``send_media_group`` (`#2093`_)
|
||||
- Make ``MessageHandler`` filter for ``Filters.update`` first (`#2085`_)
|
||||
- Fix ``PicklePersistence.flush()`` with only ``bot_data`` (`#2017`_)
|
||||
- Add test for clean argument of ``Updater.start_polling/webhook`` (`#2002`_)
|
||||
- Doc fixes, refinements and additions (`#2005`_, `#2008`_, `#2089`_, `#2094`_, `#2090`_)
|
||||
- CI fixes (`#2018`_, `#2061`_)
|
||||
- Refine ``pollbot.py`` example (`#2047`_)
|
||||
- Refine Filters in examples (`#2027`_)
|
||||
- Rename ``echobot`` examples (`#2025`_)
|
||||
- Use Lock-Bot to lock old threads (`#2048`_, `#2052`_, `#2049`_, `#2053`_)
|
||||
|
||||
.. _`#2050`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2050
|
||||
.. _`#2032`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2032
|
||||
.. _`#1965`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1965
|
||||
.. _`#1994`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1994
|
||||
.. _`#1981`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1981
|
||||
.. _`#1924`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1924
|
||||
.. _`#2051`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2051
|
||||
.. _`#1920`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1920
|
||||
.. _`#2072`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2072
|
||||
.. _`#2042`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2042
|
||||
.. _`#1724`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1724
|
||||
.. _`#2009`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2009
|
||||
.. _`#2043`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2043
|
||||
.. _`#2059`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2059
|
||||
.. _`#2106`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2106
|
||||
.. _`#2067`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2067
|
||||
.. _`#2093`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2093
|
||||
.. _`#2085`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2085
|
||||
.. _`#2017`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2017
|
||||
.. _`#2002`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2002
|
||||
.. _`#2005`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2005
|
||||
.. _`#2008`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2008
|
||||
.. _`#2089`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2089
|
||||
.. _`#2094`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2094
|
||||
.. _`#2090`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2090
|
||||
.. _`#2018`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2018
|
||||
.. _`#2061`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2061
|
||||
.. _`#2047`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2047
|
||||
.. _`#2027`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2027
|
||||
.. _`#2025`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2025
|
||||
.. _`#2048`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2048
|
||||
.. _`#2052`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2052
|
||||
.. _`#2049`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2049
|
||||
.. _`#2053`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2053
|
||||
|
||||
Version 12.8
|
||||
============
|
||||
*Released 2020-06-22*
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Remove Python 2 support (`#1715`_)
|
||||
- Bot API 4.9 support (`#1980`_)
|
||||
- IDs/Usernames of ``Filters.user`` and ``Filters.chat`` can now be updated (`#1757`_)
|
||||
|
||||
**Minor changes, CI improvements, doc fixes or bug fixes:**
|
||||
|
||||
- Update contribution guide and stale bot (`#1937`_)
|
||||
- Remove ``NullHandlers`` (`#1913`_)
|
||||
- Improve and expand examples (`#1943`_, `#1995`_, `#1983`_, `#1997`_)
|
||||
- Doc fixes (`#1940`_, `#1962`_)
|
||||
- Add ``User.send_poll()`` shortcut (`#1968`_)
|
||||
- Ignore private attributes en ``TelegramObject.to_dict()`` (`#1989`_)
|
||||
- Stabilize CI (`#2000`_)
|
||||
|
||||
.. _`#1937`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1937
|
||||
.. _`#1913`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1913
|
||||
.. _`#1943`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1943
|
||||
.. _`#1757`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1757
|
||||
.. _`#1940`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1940
|
||||
.. _`#1962`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1962
|
||||
.. _`#1968`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1968
|
||||
.. _`#1989`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1989
|
||||
.. _`#1995`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1995
|
||||
.. _`#1983`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1983
|
||||
.. _`#1715`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1715
|
||||
.. _`#2000`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2000
|
||||
.. _`#1997`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1997
|
||||
.. _`#1980`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1980
|
||||
|
||||
Version 12.7
|
||||
============
|
||||
*Released 2020-05-02*
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Bot API 4.8 support. **Note:** The ``Dice`` object now has a second positional argument ``emoji``. This is relevant, if you instantiate ``Dice`` objects manually. (`#1917`_)
|
||||
- Added ``tzinfo`` argument to ``helpers.from_timestamp``. It now returns an timezone aware object. This is relevant for ``Message.{date,forward_date,edit_date}``, ``Poll.close_date`` and ``ChatMember.until_date`` (`#1621`_)
|
||||
|
||||
**New Features:**
|
||||
|
||||
- New method ``run_monthly`` for the ``JobQueue`` (`#1705`_)
|
||||
- ``Job.next_t`` now gives the datetime of the jobs next execution (`#1685`_)
|
||||
|
||||
**Minor changes, CI improvements, doc fixes or bug fixes:**
|
||||
|
||||
- Stabalize CI (`#1919`_, `#1931`_)
|
||||
- Use ABCs ``@abstractmethod`` instead of raising ``NotImplementedError`` for ``Handler``, ``BasePersistence`` and ``BaseFilter`` (`#1905`_)
|
||||
- Doc fixes (`#1914`_, `#1902`_, `#1910`_)
|
||||
|
||||
.. _`#1902`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1902
|
||||
.. _`#1685`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1685
|
||||
.. _`#1910`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1910
|
||||
.. _`#1914`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1914
|
||||
.. _`#1931`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1931
|
||||
.. _`#1905`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1905
|
||||
.. _`#1919`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1919
|
||||
.. _`#1621`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1621
|
||||
.. _`#1705`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1705
|
||||
.. _`#1917`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1917
|
||||
|
||||
Version 12.6.1
|
||||
==============
|
||||
*Released 2020-04-11*
|
||||
|
||||
**Bug fixes:**
|
||||
|
||||
- Fix serialization of ``reply_markup`` in media messages (`#1889`_)
|
||||
|
||||
.. _`#1889`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1889
|
||||
|
||||
Version 12.6
|
||||
============
|
||||
*Released 2020-04-10*
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Bot API 4.7 support. **Note:** In ``Bot.create_new_sticker_set`` and ``Bot.add_sticker_to_set``, the order of the parameters had be changed, as the ``png_sticker`` parameter is now optional. (`#1858`_)
|
||||
|
||||
**Minor changes, CI improvements or bug fixes:**
|
||||
|
||||
- Add tests for ``swtich_inline_query(_current_chat)`` with empty string (`#1635`_)
|
||||
- Doc fixes (`#1854`_, `#1874`_, `#1884`_)
|
||||
- Update issue templates (`#1880`_)
|
||||
- Favor concrete types over "Iterable" (`#1882`_)
|
||||
- Pass last valid ``CallbackContext`` to ``TIMEOUT`` handlers of ``ConversationHandler`` (`#1826`_)
|
||||
- Tweak handling of persistence and update persistence after job calls (`#1827`_)
|
||||
- Use checkout@v2 for GitHub actions (`#1887`_)
|
||||
|
||||
.. _`#1858`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1858
|
||||
.. _`#1635`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1635
|
||||
.. _`#1854`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1854
|
||||
.. _`#1874`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1874
|
||||
.. _`#1884`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1884
|
||||
.. _`#1880`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1880
|
||||
.. _`#1882`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1882
|
||||
.. _`#1826`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1826
|
||||
.. _`#1827`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1827
|
||||
.. _`#1887`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1887
|
||||
|
||||
Version 12.5.1
|
||||
==============
|
||||
*Released 2020-03-30*
|
||||
|
||||
**Minor changes, doc fixes or bug fixes:**
|
||||
|
||||
- Add missing docs for `PollHandler` and `PollAnswerHandler` (`#1853`_)
|
||||
- Fix wording in `Filters` docs (`#1855`_)
|
||||
- Reorder tests to make them more stable (`#1835`_)
|
||||
- Make `ConversationHandler` attributes immutable (`#1756`_)
|
||||
- Make `PrefixHandler` attributes `command` and `prefix` editable (`#1636`_)
|
||||
- Fix UTC as default `tzinfo` for `Job` (`#1696`_)
|
||||
|
||||
.. _`#1853`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1853
|
||||
.. _`#1855`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1855
|
||||
.. _`#1835`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1835
|
||||
.. _`#1756`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1756
|
||||
.. _`#1636`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1636
|
||||
.. _`#1696`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1696
|
||||
|
||||
Version 12.5
|
||||
============
|
||||
*Released 2020-03-29*
|
||||
|
||||
**New Features:**
|
||||
|
||||
- `Bot.link` gives the `t.me` link of the bot (`#1770`_)
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Bot API 4.5 and 4.6 support. (`#1508`_, `#1723`_)
|
||||
|
||||
**Minor changes, CI improvements or bug fixes:**
|
||||
|
||||
- Remove legacy CI files (`#1783`_, `#1791`_)
|
||||
- Update pre-commit config file (`#1787`_)
|
||||
- Remove builtin names (`#1792`_)
|
||||
- CI improvements (`#1808`_, `#1848`_)
|
||||
- Support Python 3.8 (`#1614`_, `#1824`_)
|
||||
- Use stale bot for auto closing stale issues (`#1820`_, `#1829`_, `#1840`_)
|
||||
- Doc fixes (`#1778`_, `#1818`_)
|
||||
- Fix typo in `edit_message_media` (`#1779`_)
|
||||
- In examples, answer CallbackQueries and use `edit_message_text` shortcut (`#1721`_)
|
||||
- Revert accidental change in vendored urllib3 (`#1775`_)
|
||||
|
||||
.. _`#1783`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1783
|
||||
.. _`#1787`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1787
|
||||
.. _`#1792`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1792
|
||||
.. _`#1791`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1791
|
||||
.. _`#1808`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1808
|
||||
.. _`#1614`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1614
|
||||
.. _`#1770`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1770
|
||||
.. _`#1824`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1824
|
||||
.. _`#1820`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1820
|
||||
.. _`#1829`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1829
|
||||
.. _`#1840`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1840
|
||||
.. _`#1778`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1778
|
||||
.. _`#1779`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1779
|
||||
.. _`#1721`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1721
|
||||
.. _`#1775`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1775
|
||||
.. _`#1848`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1848
|
||||
.. _`#1818`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1818
|
||||
.. _`#1508`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1508
|
||||
.. _`#1723`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1723
|
||||
|
||||
Version 12.4.2
|
||||
==============
|
||||
*Released 2020-02-10*
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Pass correct parse_mode to InlineResults if bot.defaults is None (`#1763`_)
|
||||
- Make sure PP can read files that dont have bot_data (`#1760`_)
|
||||
|
||||
.. _`#1763`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1763
|
||||
.. _`#1760`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1760
|
||||
|
||||
Version 12.4.1
|
||||
==============
|
||||
*Released 2020-02-08*
|
||||
|
||||
This is a quick release for `#1744`_ which was accidently left out of v12.4.0 though mentioned in the
|
||||
release notes.
|
||||
|
||||
|
||||
Version 12.4.0
|
||||
==============
|
||||
*Released 2020-02-08*
|
||||
|
||||
**New features:**
|
||||
|
||||
- Set default values for arguments appearing repeatedly. We also have a `wiki page for the new defaults`_. (`#1490`_)
|
||||
- Store data in ``CallbackContext.bot_data`` to access it in every callback. Also persists. (`#1325`_)
|
||||
- ``Filters.poll`` allows only messages containing a poll (`#1673`_)
|
||||
|
||||
**Major changes:**
|
||||
|
||||
- ``Filters.text`` now accepts messages that start with a slash, because ``CommandHandler`` checks for ``MessageEntity.BOT_COMMAND`` since v12. This might lead to your MessageHandlers receiving more updates than before (`#1680`_).
|
||||
- ``Filters.command`` new checks for ``MessageEntity.BOT_COMMAND`` instead of just a leading slash. Also by ``Filters.command(False)`` you can now filters for messages containing a command `anywhere` in the text (`#1744`_).
|
||||
|
||||
**Minor changes, CI improvements or bug fixes:**
|
||||
|
||||
- Add ``disptacher`` argument to ``Updater`` to allow passing a customized ``Dispatcher`` (`#1484`_)
|
||||
- Add missing names for ``Filters`` (`#1632`_)
|
||||
- Documentation fixes (`#1624`_, `#1647`_, `#1669`_, `#1703`_, `#1718`_, `#1734`_, `#1740`_, `#1642`_, `#1739`_, `#1746`_)
|
||||
- CI improvements (`#1716`_, `#1731`_, `#1738`_, `#1748`_, `#1749`_, `#1750`_, `#1752`_)
|
||||
- Fix spelling issue for ``encode_conversations_to_json`` (`#1661`_)
|
||||
- Remove double assignement of ``Dispatcher.job_queue`` (`#1698`_)
|
||||
- Expose dispatcher as property for ``CallbackContext`` (`#1684`_)
|
||||
- Fix ``None`` check in ``JobQueue._put()`` (`#1707`_)
|
||||
- Log datetimes correctly in ``JobQueue`` (`#1714`_)
|
||||
- Fix false ``Message.link`` creation for private groups (`#1741`_)
|
||||
- Add option ``--with-upstream-urllib3`` to `setup.py` to allow using non-vendored version (`#1725`_)
|
||||
- Fix persistence for nested ``ConversationHandlers`` (`#1679`_)
|
||||
- Improve handling of non-decodable server responses (`#1623`_)
|
||||
- Fix download for files without ``file_path`` (`#1591`_)
|
||||
- test_webhook_invalid_posts is now considered flaky and retried on failure (`#1758`_)
|
||||
|
||||
.. _`wiki page for the new defaults`: https://github.com/python-telegram-bot/python-telegram-bot/wiki/Adding-defaults-to-your-bot
|
||||
.. _`#1744`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1744
|
||||
.. _`#1752`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1752
|
||||
.. _`#1750`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1750
|
||||
.. _`#1591`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1591
|
||||
.. _`#1490`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1490
|
||||
.. _`#1749`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1749
|
||||
.. _`#1623`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1623
|
||||
.. _`#1748`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1748
|
||||
.. _`#1679`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1679
|
||||
.. _`#1711`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1711
|
||||
.. _`#1325`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1325
|
||||
.. _`#1746`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1746
|
||||
.. _`#1725`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1725
|
||||
.. _`#1739`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1739
|
||||
.. _`#1741`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1741
|
||||
.. _`#1642`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1642
|
||||
.. _`#1738`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1738
|
||||
.. _`#1740`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1740
|
||||
.. _`#1734`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1734
|
||||
.. _`#1680`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1680
|
||||
.. _`#1718`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1718
|
||||
.. _`#1714`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1714
|
||||
.. _`#1707`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1707
|
||||
.. _`#1731`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1731
|
||||
.. _`#1673`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1673
|
||||
.. _`#1684`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1684
|
||||
.. _`#1703`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1703
|
||||
.. _`#1698`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1698
|
||||
.. _`#1669`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1669
|
||||
.. _`#1661`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1661
|
||||
.. _`#1647`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1647
|
||||
.. _`#1632`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1632
|
||||
.. _`#1624`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1624
|
||||
.. _`#1716`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1716
|
||||
.. _`#1484`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1484
|
||||
.. _`#1758`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1484
|
||||
|
||||
Version 12.3.0
|
||||
==============
|
||||
*Released 2020-01-11*
|
||||
|
||||
**New features:**
|
||||
|
||||
- `Filters.caption` allows only messages with caption (`#1631`_).
|
||||
- Filter for exact messages/captions with new capability of `Filters.text` and `Filters.caption`. Especially useful in combination with ReplyKeyboardMarkup. (`#1631`_).
|
||||
|
||||
**Major changes:**
|
||||
|
||||
- Fix inconsistent handling of naive datetimes (`#1506`_).
|
||||
|
||||
**Minor changes, CI improvements or bug fixes:**
|
||||
|
||||
- Documentation fixes (`#1558`_, `#1569`_, `#1579`_, `#1572`_, `#1566`_, `#1577`_, `#1656`_).
|
||||
- Add mutex protection on `ConversationHandler` (`#1533`_).
|
||||
- Add `MAX_PHOTOSIZE_UPLOAD` constant (`#1560`_).
|
||||
- Add args and kwargs to `Message.forward()` (`#1574`_).
|
||||
- Transfer to GitHub Actions CI (`#1555`_, `#1556`_, `#1605`_, `#1606`_, `#1607`_, `#1612`_, `#1615`_, `#1645`_).
|
||||
- Fix deprecation warning with Py3.8 by vendored urllib3 (`#1618`_).
|
||||
- Simplify assignements for optional arguments (`#1600`_)
|
||||
- Allow private groups for `Message.link` (`#1619`_).
|
||||
- Fix wrong signature call for `ConversationHandler.TIMEOUT` handlers (`#1653`_).
|
||||
|
||||
.. _`#1631`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1631
|
||||
.. _`#1506`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1506
|
||||
.. _`#1558`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1558
|
||||
.. _`#1569`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1569
|
||||
.. _`#1579`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1579
|
||||
.. _`#1572`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1572
|
||||
.. _`#1566`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1566
|
||||
.. _`#1577`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1577
|
||||
.. _`#1533`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1533
|
||||
.. _`#1560`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1560
|
||||
.. _`#1574`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1574
|
||||
.. _`#1555`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1555
|
||||
.. _`#1556`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1556
|
||||
.. _`#1605`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1605
|
||||
.. _`#1606`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1606
|
||||
.. _`#1607`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1607
|
||||
.. _`#1612`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1612
|
||||
.. _`#1615`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1615
|
||||
.. _`#1618`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1618
|
||||
.. _`#1600`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1600
|
||||
.. _`#1619`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1619
|
||||
.. _`#1653`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1653
|
||||
.. _`#1656`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1656
|
||||
.. _`#1645`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1645
|
||||
|
||||
Version 12.2.0
|
||||
==============
|
||||
*Released 2019-10-14*
|
||||
|
||||
**New features:**
|
||||
|
||||
- Nested ConversationHandlers (`#1512`_).
|
||||
|
||||
**Minor changes, CI improvments or bug fixes:**
|
||||
|
||||
- Fix CI failures due to non-backward compat attrs depndency (`#1540`_).
|
||||
- travis.yaml: TEST_OFFICIAL removed from allowed_failures.
|
||||
- Fix typos in examples (`#1537`_).
|
||||
- Fix Bot.to_dict to use proper first_name (`#1525`_).
|
||||
- Refactor ``test_commandhandler.py`` (`#1408`_).
|
||||
- Add Python 3.8 (RC version) to Travis testing matrix (`#1543`_).
|
||||
- test_bot.py: Add to_dict test (`#1544`_).
|
||||
- Flake config moved into setup.cfg (`#1546`_).
|
||||
|
||||
.. _`#1512`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1512
|
||||
.. _`#1540`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1540
|
||||
.. _`#1537`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1537
|
||||
.. _`#1525`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1525
|
||||
.. _`#1408`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1408
|
||||
.. _`#1543`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1543
|
||||
.. _`#1544`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1544
|
||||
.. _`#1546`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1546
|
||||
|
||||
Version 12.1.1
|
||||
==============
|
||||
*Released 2019-09-18*
|
||||
|
||||
**Hot fix release**
|
||||
|
||||
Fixed regression in the vendored urllib3 (`#1517`_).
|
||||
|
||||
.. _`#1517`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1517
|
||||
|
||||
Version 12.1.0
|
||||
================
|
||||
*Released 2019-09-13*
|
||||
|
||||
**Major changes:**
|
||||
|
||||
- Bot API 4.4 support (`#1464`_, `#1510`_)
|
||||
- Add `get_file` method to `Animation` & `ChatPhoto`. Add, `get_small_file` & `get_big_file`
|
||||
methods to `ChatPhoto` (`#1489`_)
|
||||
- Tools for deep linking (`#1049`_)
|
||||
|
||||
**Minor changes and/or bug fixes:**
|
||||
|
||||
- Documentation fixes (`#1500`_, `#1499`_)
|
||||
- Improved examples (`#1502`_)
|
||||
|
||||
.. _`#1464`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1464
|
||||
.. _`#1502`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1502
|
||||
.. _`#1499`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1499
|
||||
.. _`#1500`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1500
|
||||
.. _`#1049`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1049
|
||||
.. _`#1489`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1489
|
||||
.. _`#1510`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1510
|
||||
|
||||
Version 12.0.0
|
||||
================
|
||||
*Released 2019-08-29*
|
||||
|
||||
Well... This felt like decades. But here we are with a new release.
|
||||
|
||||
Expect minor releases soon (mainly complete Bot API 4.4 support)
|
||||
|
||||
**Major and/or breaking changes:**
|
||||
|
||||
- Context based callbacks
|
||||
- Persistence
|
||||
- PrefixHandler added (Handler overhaul)
|
||||
- Deprecation of RegexHandler and edited_messages, channel_post, etc. arguments (Filter overhaul)
|
||||
- Various ConversationHandler changes and fixes
|
||||
- Bot API 4.1, 4.2, 4.3 support
|
||||
- Python 3.4 is no longer supported
|
||||
- Error Handler now handles all types of exceptions (`#1485`_)
|
||||
- Return UTC from from_timestamp() (`#1485`_)
|
||||
|
||||
**See the wiki page at https://git.io/fxJuV for a detailed guide on how to migrate from version 11 to version 12.**
|
||||
|
||||
Context based callbacks (`#1100`_)
|
||||
----------------------------------
|
||||
|
||||
- Use of ``pass_`` in handlers is deprecated.
|
||||
- Instead use ``use_context=True`` on ``Updater`` or ``Dispatcher`` and change callback from (bot, update, others...) to (update, context).
|
||||
- This also applies to error handlers ``Dispatcher.add_error_handler`` and JobQueue jobs (change (bot, job) to (context) here).
|
||||
- For users with custom handlers subclassing Handler, this is mostly backwards compatible, but to use the new context based callbacks you need to implement the new collect_additional_context method.
|
||||
- Passing bot to ``JobQueue.__init__`` is deprecated. Use JobQueue.set_dispatcher with a dispatcher instead.
|
||||
- Dispatcher makes sure to use a single `CallbackContext` for a entire update. This means that if an update is handled by multiple handlers (by using the group argument), you can add custom arguments to the `CallbackContext` in a lower group handler and use it in higher group handler. NOTE: Never use with @run_async, see docs for more info. (`#1283`_)
|
||||
- If you have custom handlers they will need to be updated to support the changes in this release.
|
||||
- Update all examples to use context based callbacks.
|
||||
|
||||
Persistence (`#1017`_)
|
||||
----------------------
|
||||
|
||||
- Added PicklePersistence and DictPersistence for adding persistence to your bots.
|
||||
- BasePersistence can be subclassed for all your persistence needs.
|
||||
- Add a new example that shows a persistent ConversationHandler bot
|
||||
|
||||
Handler overhaul (`#1114`_)
|
||||
---------------------------
|
||||
|
||||
- CommandHandler now only triggers on actual commands as defined by telegram servers (everything that the clients mark as a tabable link).
|
||||
- PrefixHandler can be used if you need to trigger on prefixes (like all messages starting with a "/" (old CommandHandler behaviour) or even custom prefixes like "#" or "!").
|
||||
|
||||
Filter overhaul (`#1221`_)
|
||||
--------------------------
|
||||
|
||||
- RegexHandler is deprecated and should be replaced with a MessageHandler with a regex filter.
|
||||
- Use update filters to filter update types instead of arguments (message_updates, channel_post_updates and edited_updates) on the handlers.
|
||||
- Completely remove allow_edited argument - it has been deprecated for a while.
|
||||
- data_filters now exist which allows filters that return data into the callback function. This is how the regex filter is implemented.
|
||||
- All this means that it no longer possible to use a list of filters in a handler. Use bitwise operators instead!
|
||||
|
||||
ConversationHandler
|
||||
-------------------
|
||||
|
||||
- Remove ``run_async_timeout`` and ``timed_out_behavior`` arguments (`#1344`_)
|
||||
- Replace with ``WAITING`` constant and behavior from states (`#1344`_)
|
||||
- Only emit one warning for multiple CallbackQueryHandlers in a ConversationHandler (`#1319`_)
|
||||
- Use warnings.warn for ConversationHandler warnings (`#1343`_)
|
||||
- Fix unresolvable promises (`#1270`_)
|
||||
|
||||
|
||||
Bug fixes & improvements
|
||||
------------------------
|
||||
|
||||
- Handlers should be faster due to deduped logic.
|
||||
- Avoid compiling compiled regex in regex filter. (`#1314`_)
|
||||
- Add missing ``left_chat_member`` to Message.MESSAGE_TYPES (`#1336`_)
|
||||
- Make custom timeouts actually work properly (`#1330`_)
|
||||
- Add convenience classmethods (from_button, from_row and from_column) to InlineKeyboardMarkup
|
||||
- Small typo fix in setup.py (`#1306`_)
|
||||
- Add Conflict error (HTTP error code 409) (`#1154`_)
|
||||
- Change MAX_CAPTION_LENGTH to 1024 (`#1262`_)
|
||||
- Remove some unnecessary clauses (`#1247`_, `#1239`_)
|
||||
- Allow filenames without dots in them when sending files (`#1228`_)
|
||||
- Fix uploading files with unicode filenames (`#1214`_)
|
||||
- Replace http.server with Tornado (`#1191`_)
|
||||
- Allow SOCKSConnection to parse username and password from URL (`#1211`_)
|
||||
- Fix for arguments in passport/data.py (`#1213`_)
|
||||
- Improve message entity parsing by adding text_mention (`#1206`_)
|
||||
- Documentation fixes (`#1348`_, `#1397`_, `#1436`_)
|
||||
- Merged filters short-circuit (`#1350`_)
|
||||
- Fix webhook listen with tornado (`#1383`_)
|
||||
- Call task_done() on update queue after update processing finished (`#1428`_)
|
||||
- Fix send_location() - latitude may be 0 (`#1437`_)
|
||||
- Make MessageEntity objects comparable (`#1465`_)
|
||||
- Add prefix to thread names (`#1358`_)
|
||||
|
||||
Buf fixes since v12.0.0b1
|
||||
-------------------------
|
||||
|
||||
- Fix setting bot on ShippingQuery (`#1355`_)
|
||||
- Fix _trigger_timeout() missing 1 required positional argument: 'job' (`#1367`_)
|
||||
- Add missing message.text check in PrefixHandler check_update (`#1375`_)
|
||||
- Make updates persist even on DispatcherHandlerStop (`#1463`_)
|
||||
- Dispatcher force updating persistence object's chat data attribute(`#1462`_)
|
||||
|
||||
.. _`#1100`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1100
|
||||
.. _`#1283`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1283
|
||||
.. _`#1017`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1017
|
||||
.. _`#1325`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1325
|
||||
.. _`#1301`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1301
|
||||
.. _`#1312`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1312
|
||||
.. _`#1324`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1324
|
||||
.. _`#1114`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1114
|
||||
.. _`#1221`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1221
|
||||
.. _`#1314`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1314
|
||||
.. _`#1336`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1336
|
||||
.. _`#1330`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1330
|
||||
.. _`#1306`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1306
|
||||
.. _`#1154`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1154
|
||||
.. _`#1262`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1262
|
||||
.. _`#1247`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1247
|
||||
.. _`#1239`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1239
|
||||
.. _`#1228`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1228
|
||||
.. _`#1214`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1214
|
||||
.. _`#1191`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1191
|
||||
.. _`#1211`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1211
|
||||
.. _`#1213`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1213
|
||||
.. _`#1206`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1206
|
||||
.. _`#1344`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1344
|
||||
.. _`#1319`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1319
|
||||
.. _`#1343`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1343
|
||||
.. _`#1270`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1270
|
||||
.. _`#1348`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1348
|
||||
.. _`#1350`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1350
|
||||
.. _`#1383`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1383
|
||||
.. _`#1397`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1397
|
||||
.. _`#1428`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1428
|
||||
.. _`#1436`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1436
|
||||
.. _`#1437`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1437
|
||||
.. _`#1465`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1465
|
||||
.. _`#1358`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1358
|
||||
.. _`#1355`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1355
|
||||
.. _`#1367`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1367
|
||||
.. _`#1375`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1375
|
||||
.. _`#1463`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1463
|
||||
.. _`#1462`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1462
|
||||
.. _`#1483`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1483
|
||||
.. _`#1485`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1485
|
||||
|
||||
Internal improvements
|
||||
---------------------
|
||||
|
||||
- Finally fix our CI builds mostly (too many commits and PRs to list)
|
||||
- Use multiple bots for CI to improve testing times significantly.
|
||||
- Allow pypy to fail in CI.
|
||||
- Remove the last CamelCase CheckUpdate methods from the handlers we missed earlier.
|
||||
- test_official is now executed in a different job
|
||||
|
||||
Version 11.1.0
|
||||
==============
|
||||
*Released 2018-09-01*
|
||||
|
||||
Fixes and updates for Telegram Passport: (`#1198`_)
|
||||
|
||||
- Fix passport decryption failing at random times
|
||||
- Added support for middle names.
|
||||
- Added support for translations for documents
|
||||
- Add errors for translations for documents
|
||||
- Added support for requesting names in the language of the user's country of residence
|
||||
- Replaced the payload parameter with the new parameter nonce
|
||||
- Add hash to EncryptedPassportElement
|
||||
|
||||
.. _`#1198`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1198
|
||||
|
||||
Version 11.0.0
|
||||
==============
|
||||
*Released 2018-08-29*
|
||||
|
||||
Fully support Bot API version 4.0!
|
||||
(also some bugfixes :))
|
||||
@@ -58,8 +830,9 @@ Non Bot API 4.0 changes:
|
||||
.. _`#1184`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1184
|
||||
.. _`our telegram passport wiki page`: https://git.io/fAvYd
|
||||
|
||||
**2018-05-02**
|
||||
*Released 10.1.0*
|
||||
Version 10.1.0
|
||||
==============
|
||||
*Released 2018-05-02*
|
||||
|
||||
Fixes changing previous behaviour:
|
||||
|
||||
@@ -85,8 +858,9 @@ Fixes:
|
||||
.. _`#1096`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1096
|
||||
.. _`#1099`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1099
|
||||
|
||||
**2018-04-17**
|
||||
*Released 10.0.2*
|
||||
Version 10.0.2
|
||||
==============
|
||||
*Released 2018-04-17*
|
||||
|
||||
Important fix:
|
||||
|
||||
@@ -117,8 +891,9 @@ Fixes:
|
||||
.. _`#1076`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1076
|
||||
.. _`#1071`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1071
|
||||
|
||||
**2018-03-05**
|
||||
*Released 10.0.1*
|
||||
Version 10.0.1
|
||||
==============
|
||||
*Released 2018-03-05*
|
||||
|
||||
Fixes:
|
||||
|
||||
@@ -128,8 +903,9 @@ Fixes:
|
||||
.. _`#1032`: https://github.com/python-telegram-bot/python-telegram-bot/pull/826
|
||||
.. _`#912`: https://github.com/python-telegram-bot/python-telegram-bot/pull/826
|
||||
|
||||
**2018-03-02**
|
||||
*Released 10.0.0*
|
||||
Version 10.0.0
|
||||
==============
|
||||
*Released 2018-03-02*
|
||||
|
||||
Non backward compatabile changes and changed defaults
|
||||
|
||||
@@ -194,8 +970,9 @@ Changes
|
||||
.. _`#1019`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1019
|
||||
.. _`#1020`: https://github.com/python-telegram-bot/python-telegram-bot/pull/1020
|
||||
|
||||
**2017-12-08**
|
||||
*Released 9.0.0*
|
||||
Version 9.0.0
|
||||
=============
|
||||
*Released 2017-12-08*
|
||||
|
||||
Breaking changes (possibly)
|
||||
|
||||
@@ -220,15 +997,17 @@ Changes
|
||||
.. _`#694`: https://github.com/python-telegram-bot/python-telegram-bot/pull/694
|
||||
.. _`#870`: https://github.com/python-telegram-bot/python-telegram-bot/pull/870
|
||||
|
||||
**2017-10-15**
|
||||
*Released 8.1.1*
|
||||
Version 8.1.1
|
||||
=============
|
||||
*Released 2017-10-15*
|
||||
|
||||
- Fix Commandhandler crashing on single character messages (PR `#873`_).
|
||||
|
||||
.. _`#873`: https://github.com/python-telegram-bot/python-telegram-bot/pull/871
|
||||
|
||||
**2017-10-14**
|
||||
*Released 8.1.0*
|
||||
Version 8.1.0
|
||||
=============
|
||||
*Released 2017-10-14*
|
||||
|
||||
New features
|
||||
- Support Bot API 3.4 (PR `#865`_).
|
||||
@@ -245,8 +1024,9 @@ Changes
|
||||
.. _`#865`: https://github.com/python-telegram-bot/python-telegram-bot/pull/865
|
||||
.. _`#869`: https://github.com/python-telegram-bot/python-telegram-bot/pull/869
|
||||
|
||||
**2017-09-01**
|
||||
*Released 8.0.0*
|
||||
Version 8.0.0
|
||||
=============
|
||||
*Released 2017-09-01*
|
||||
|
||||
New features
|
||||
|
||||
@@ -287,14 +1067,16 @@ Changes
|
||||
.. _`#793`: https://github.com/python-telegram-bot/python-telegram-bot/pull/793
|
||||
.. _`#810`: https://github.com/python-telegram-bot/python-telegram-bot/pull/810
|
||||
|
||||
**2017-07-28**
|
||||
*Released 7.0.1*
|
||||
Version 7.0.1
|
||||
===============
|
||||
*Released 2017-07-28*
|
||||
|
||||
- Fix TypeError exception in RegexHandler (PR #751).
|
||||
- Small documentation fix (PR #749).
|
||||
|
||||
**2017-07-25**
|
||||
*Released 7.0.0*
|
||||
Version 7.0.0
|
||||
=============
|
||||
*Released 2017-07-25*
|
||||
|
||||
- Fully support Bot API 3.2.
|
||||
- New filters for handling messages from specific chat/user id (PR #677).
|
||||
@@ -312,6 +1094,9 @@ Changes
|
||||
- Improved documentation.
|
||||
- Improved unitests.
|
||||
|
||||
Pre-version 7.0
|
||||
===============
|
||||
|
||||
**2017-06-18**
|
||||
|
||||
*Released 6.1.0*
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
include LICENSE LICENSE.lesser Makefile requirements.txt
|
||||
include LICENSE LICENSE.lesser Makefile requirements.txt README_RAW.rst telegram/py.typed
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
.DEFAULT_GOAL := help
|
||||
.PHONY: clean pep257 pep8 yapf lint test install
|
||||
.PHONY: clean pep8 black lint test install
|
||||
|
||||
PYLINT := pylint
|
||||
PYTEST := pytest
|
||||
PEP257 := pep257
|
||||
PEP8 := flake8
|
||||
YAPF := yapf
|
||||
BLACK := black
|
||||
MYPY := mypy
|
||||
PIP := pip
|
||||
|
||||
clean:
|
||||
@@ -14,19 +14,20 @@ clean:
|
||||
find . -name '*.pyc' -exec rm -f {} \;
|
||||
find . -name '*.pyo' -exec rm -f {} \;
|
||||
find . -name '*~' -exec rm -f {} \;
|
||||
find . -regex "./telegram.\(mp3\|mp4\|ogg\|png\|webp\)" -exec rm {} \;
|
||||
|
||||
pep257:
|
||||
$(PEP257) telegram
|
||||
find . -regex "./telegram[0-9]*.\(jpg\|mp3\|mp4\|ogg\|png\|webp\)" -exec rm {} \;
|
||||
|
||||
pep8:
|
||||
$(PEP8) telegram
|
||||
$(PEP8) telegram tests examples
|
||||
|
||||
yapf:
|
||||
$(YAPF) -r telegram
|
||||
black:
|
||||
$(BLACK) .
|
||||
|
||||
lint:
|
||||
$(PYLINT) -E telegram --disable=no-name-in-module,import-error
|
||||
$(PYLINT) --rcfile=setup.cfg telegram examples
|
||||
|
||||
mypy:
|
||||
$(MYPY) -p telegram
|
||||
$(MYPY) examples
|
||||
|
||||
test:
|
||||
$(PYTEST) -v
|
||||
@@ -37,16 +38,16 @@ install:
|
||||
help:
|
||||
@echo "Available targets:"
|
||||
@echo "- clean Clean up the source directory"
|
||||
@echo "- pep257 Check docstring style with pep257"
|
||||
@echo "- pep8 Check style with flake8"
|
||||
@echo "- lint Check style with pylint"
|
||||
@echo "- yapf Check style with yapf"
|
||||
@echo "- black Check style with black"
|
||||
@echo "- mypy Check type hinting with mypy"
|
||||
@echo "- test Run tests using pytest"
|
||||
@echo
|
||||
@echo "Available variables:"
|
||||
@echo "- PYLINT default: $(PYLINT)"
|
||||
@echo "- PYTEST default: $(PYTEST)"
|
||||
@echo "- PEP257 default: $(PEP257)"
|
||||
@echo "- PEP8 default: $(PEP8)"
|
||||
@echo "- YAPF default: $(YAPF)"
|
||||
@echo "- BLACK default: $(BLACK)"
|
||||
@echo "- MYPY default: $(MYPY)"
|
||||
@echo "- PIP default: $(PIP)"
|
||||
|
||||
+41
-23
@@ -1,3 +1,6 @@
|
||||
..
|
||||
Make user to apply any changes to this file to README_RAW.rst as well!
|
||||
|
||||
.. image:: https://github.com/python-telegram-bot/logos/blob/master/logo-text/png/ptb-logo-text_768.png?raw=true
|
||||
:align: center
|
||||
:target: https://python-telegram-bot.org
|
||||
@@ -17,36 +20,42 @@ We have a vibrant community of developers helping each other in our `Telegram gr
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://www.cpu.re/static/python-telegram-bot/downloads.svg
|
||||
:target: https://www.cpu.re/static/python-telegram-bot/downloads-by-python-version.txt
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-5.0-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/python-telegram-bot
|
||||
:target: https://pypistats.org/packages/python-telegram-bot
|
||||
:alt: PyPi Package Monthly Download
|
||||
|
||||
.. image:: https://img.shields.io/badge/docs-latest-af1a97.svg
|
||||
:target: https://python-telegram-bot.readthedocs.io/
|
||||
.. image:: https://readthedocs.org/projects/python-telegram-bot/badge/?version=stable
|
||||
:target: https://python-telegram-bot.readthedocs.io/en/stable/?badge=stable
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/pypi/l/python-telegram-bot.svg
|
||||
:target: https://www.gnu.org/licenses/lgpl-3.0.html
|
||||
:alt: LGPLv3 License
|
||||
|
||||
.. image:: https://travis-ci.org/python-telegram-bot/python-telegram-bot.svg?branch=master
|
||||
:target: https://travis-ci.org/python-telegram-bot/python-telegram-bot
|
||||
:alt: Travis CI Status
|
||||
|
||||
.. image:: https://img.shields.io/appveyor/ci/python-telegram-bot/python-telegram-bot/master.svg?logo=appveyor
|
||||
:target: https://ci.appveyor.com/project/python-telegram-bot/python-telegram-bot
|
||||
:alt: AppVeyor CI Status
|
||||
|
||||
.. image:: https://github.com/python-telegram-bot/python-telegram-bot/workflows/GitHub%20Actions/badge.svg
|
||||
:target: https://github.com/python-telegram-bot/python-telegram-bot/
|
||||
:alt: Github Actions workflow
|
||||
|
||||
.. image:: https://codecov.io/gh/python-telegram-bot/python-telegram-bot/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
:alt: Code coverage
|
||||
|
||||
|
||||
.. image:: http://isitmaintained.com/badge/resolution/python-telegram-bot/python-telegram-bot.svg
|
||||
:target: http://isitmaintained.com/project/python-telegram-bot/python-telegram-bot
|
||||
:alt: Median time to resolve an issue
|
||||
|
||||
.. image:: https://img.shields.io/badge/Telegram-Group-blue.svg
|
||||
.. image:: https://api.codacy.com/project/badge/Grade/99d901eaa09b44b4819aec05c330c968
|
||||
:target: https://www.codacy.com/app/python-telegram-bot/python-telegram-bot?utm_source=github.com&utm_medium=referral&utm_content=python-telegram-bot/python-telegram-bot&utm_campaign=Badge_Grade
|
||||
:alt: Code quality
|
||||
|
||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
:target: https://github.com/psf/black
|
||||
|
||||
.. image:: https://img.shields.io/badge/Telegram-Group-blue.svg?logo=telegram
|
||||
:target: https://telegram.me/pythontelegrambotgroup
|
||||
:alt: Telegram Group
|
||||
|
||||
@@ -84,18 +93,25 @@ Introduction
|
||||
|
||||
This library provides a pure Python interface for the
|
||||
`Telegram Bot API <https://core.telegram.org/bots/api>`_.
|
||||
It's compatible with Python versions 2.7, 3.3+ and `PyPy <http://pypy.org/>`_.
|
||||
It also works with `Google App Engine <https://cloud.google.com/appengine>`_.
|
||||
It's compatible with Python versions 3.6+. PTB might also work on `PyPy <http://pypy.org/>`_, though there have been a lot of issues before. Hence, PyPy is not officially supported.
|
||||
|
||||
In addition to the pure API implementation, this library features a number of high-level classes to
|
||||
make the development of bots easy and straightforward. These classes are contained in the
|
||||
``telegram.ext`` submodule.
|
||||
|
||||
A pure API implementation *without* ``telegram.ext`` is available as the standalone package ``python-telegram-bot-raw``. `See here for details. <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/README_RAW.rst>`_
|
||||
|
||||
----
|
||||
Note
|
||||
----
|
||||
|
||||
Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conjunction will result in undesired side-effects, so only install *one* of both.
|
||||
|
||||
====================
|
||||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **4.0** are supported.
|
||||
All types and methods of the Telegram Bot API **5.0** are supported.
|
||||
|
||||
==========
|
||||
Installing
|
||||
@@ -139,9 +155,9 @@ Other references:
|
||||
Learning by example
|
||||
-------------------
|
||||
|
||||
We believe that the best way to learn and understand this simple package is by example. So here
|
||||
are some examples for you to review. Even if it's not your approach for learning, please take a
|
||||
look at ``echobot2``, it is de facto the base for most of the bots out there. Best of all,
|
||||
We believe that the best way to learn this package is by example. Here
|
||||
are some examples for you to review. Even if it is not your approach for learning, please take a
|
||||
look at ``echobot.py``, it is the de facto base for most of the bots out there. Best of all,
|
||||
the code for these examples are released to the public domain, so you can start by grabbing the
|
||||
code and building on top of it.
|
||||
|
||||
@@ -189,11 +205,13 @@ You can get help in several ways:
|
||||
|
||||
1. We have a vibrant community of developers helping each other in our `Telegram group <https://telegram.me/pythontelegrambotgroup>`_. Join us!
|
||||
|
||||
2. Our `Wiki pages <https://github.com/python-telegram-bot/python-telegram-bot/wiki/>`_ offer a growing amount of resources.
|
||||
2. In case you are unable to join our group due to Telegram restrictions, you can use our `IRC channel <https://webchat.freenode.net/?channels=##python-telegram-bot>`_.
|
||||
|
||||
3. You can ask for help on Stack Overflow using the `python-telegram-bot tag <https://stackoverflow.com/questions/tagged/python-telegram-bot>`_.
|
||||
3. Report bugs, request new features or ask questions by `creating an issue <https://github.com/python-telegram-bot/python-telegram-bot/issues/new/choose>`_ or `a discussion <https://github.com/python-telegram-bot/python-telegram-bot/discussions/new>`_.
|
||||
|
||||
4. As last resort, the developers are ready to help you with `serious issues <https://github.com/python-telegram-bot/python-telegram-bot/issues/new>`_.
|
||||
4. Our `Wiki pages <https://github.com/python-telegram-bot/python-telegram-bot/wiki/>`_ offer a growing amount of resources.
|
||||
|
||||
5. You can even ask for help on Stack Overflow using the `python-telegram-bot tag <https://stackoverflow.com/questions/tagged/python-telegram-bot>`_.
|
||||
|
||||
|
||||
============
|
||||
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
..
|
||||
Make user to apply any changes to this file to README.rst as well!
|
||||
|
||||
.. image:: https://github.com/python-telegram-bot/logos/blob/master/logo-text/png/ptb-raw-logo-text_768.png?raw=true
|
||||
:align: center
|
||||
:target: https://python-telegram-bot.org
|
||||
:alt: python-telegram-bot-raw Logo
|
||||
|
||||
We have made you a wrapper you can't refuse
|
||||
|
||||
We have a vibrant community of developers helping each other in our `Telegram group <https://telegram.me/pythontelegrambotgroup>`_. Join us!
|
||||
|
||||
*Stay tuned for library updates and new releases on our* `Telegram Channel <https://telegram.me/pythontelegrambotchannel>`_.
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/python-telegram-bot-raw.svg
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: PyPi Package Version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/pyversions/python-telegram-bot-raw.svg
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-5.0-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/python-telegram-bot-raw
|
||||
:target: https://pypistats.org/packages/python-telegram-bot
|
||||
:alt: PyPi Package Monthly Download
|
||||
|
||||
.. image:: https://img.shields.io/badge/docs-latest-af1a97.svg
|
||||
:target: https://python-telegram-bot.readthedocs.io/
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/pypi/l/python-telegram-bot-raw.svg
|
||||
:target: https://www.gnu.org/licenses/lgpl-3.0.html
|
||||
:alt: LGPLv3 License
|
||||
|
||||
.. image:: https://github.com/python-telegram-bot/python-telegram-bot/workflows/GitHub%20Actions/badge.svg
|
||||
:target: https://github.com/python-telegram-bot/python-telegram-bot/
|
||||
:alt: Github Actions workflow
|
||||
|
||||
.. image:: https://codecov.io/gh/python-telegram-bot/python-telegram-bot/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
:alt: Code coverage
|
||||
|
||||
.. image:: http://isitmaintained.com/badge/resolution/python-telegram-bot/python-telegram-bot.svg
|
||||
:target: http://isitmaintained.com/project/python-telegram-bot/python-telegram-bot
|
||||
:alt: Median time to resolve an issue
|
||||
|
||||
.. image:: https://api.codacy.com/project/badge/Grade/99d901eaa09b44b4819aec05c330c968
|
||||
:target: https://www.codacy.com/app/python-telegram-bot/python-telegram-bot?utm_source=github.com&utm_medium=referral&utm_content=python-telegram-bot/python-telegram-bot&utm_campaign=Badge_Grade
|
||||
:alt: Code quality
|
||||
|
||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
:target: https://github.com/psf/black
|
||||
|
||||
.. image:: https://img.shields.io/badge/Telegram-Group-blue.svg?logo=telegram
|
||||
:target: https://telegram.me/pythontelegrambotgroup
|
||||
:alt: Telegram Group
|
||||
|
||||
.. image:: https://img.shields.io/badge/IRC-Channel-blue.svg
|
||||
:target: https://webchat.freenode.net/?channels=##python-telegram-bot
|
||||
:alt: IRC Bridge
|
||||
|
||||
=================
|
||||
Table of contents
|
||||
=================
|
||||
|
||||
- `Introduction`_
|
||||
|
||||
- `Telegram API support`_
|
||||
|
||||
- `Installing`_
|
||||
|
||||
- `Getting started`_
|
||||
|
||||
#. `Logging`_
|
||||
|
||||
#. `Documentation`_
|
||||
|
||||
- `Getting help`_
|
||||
|
||||
- `Contributing`_
|
||||
|
||||
- `License`_
|
||||
|
||||
============
|
||||
Introduction
|
||||
============
|
||||
|
||||
This library provides a pure Python, lightweight interface for the
|
||||
`Telegram Bot API <https://core.telegram.org/bots/api>`_.
|
||||
It's compatible with Python versions 3.6+. PTB-Raw might also work on `PyPy <http://pypy.org/>`_, though there have been a lot of issues before. Hence, PyPy is not officially supported.
|
||||
|
||||
``python-telegram-bot-raw`` is part of the `python-telegram-bot <https://python-telegram-bot.org>`_ ecosystem and provides the pure API functionality extracted from PTB. It therefore does *not* have independent release schedules, changelogs or documentation. Please consult the PTB resources.
|
||||
|
||||
----
|
||||
Note
|
||||
----
|
||||
|
||||
Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conjunction will result in undesired side-effects, so only install *one* of both.
|
||||
|
||||
====================
|
||||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **5.0** are supported.
|
||||
|
||||
==========
|
||||
Installing
|
||||
==========
|
||||
|
||||
You can install or upgrade python-telegram-bot-raw with:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ pip install python-telegram-bot-raw --upgrade
|
||||
|
||||
Or you can install from source with:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ git clone https://github.com/python-telegram-bot/python-telegram-bot --recursive
|
||||
$ cd python-telegram-bot
|
||||
$ python setup-raw.py install
|
||||
|
||||
In case you have a previously cloned local repository already, you should initialize the added urllib3 submodule before installing with:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ git submodule update --init --recursive
|
||||
|
||||
----
|
||||
Note
|
||||
----
|
||||
|
||||
Installing the `.tar.gz` archive available on PyPi directly via `pip` will *not* work as expected, as `pip` does not recognize that it should use `setup-raw.py` instead of `setup.py`.
|
||||
|
||||
===============
|
||||
Getting started
|
||||
===============
|
||||
|
||||
Our Wiki contains an `Introduction to the API <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Introduction-to-the-API>`_. Other references are:
|
||||
|
||||
- the `Telegram API documentation <https://core.telegram.org/bots/api>`_
|
||||
- the `python-telegram-bot documentation <https://python-telegram-bot.readthedocs.io/>`_
|
||||
|
||||
-------
|
||||
Logging
|
||||
-------
|
||||
|
||||
This library uses the ``logging`` module. To set up logging to standard output, put:
|
||||
|
||||
.. code:: python
|
||||
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
|
||||
at the beginning of your script.
|
||||
|
||||
You can also use logs in your application by calling ``logging.getLogger()`` and setting the log level you want:
|
||||
|
||||
.. code:: python
|
||||
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
If you want DEBUG logs instead:
|
||||
|
||||
.. code:: python
|
||||
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
=============
|
||||
Documentation
|
||||
=============
|
||||
|
||||
``python-telegram-bot``'s documentation lives at `readthedocs.io <https://python-telegram-bot.readthedocs.io/>`_, which
|
||||
includes the relevant documentation for ``python-telegram-bot-raw``.
|
||||
|
||||
============
|
||||
Getting help
|
||||
============
|
||||
|
||||
You can get help in several ways:
|
||||
|
||||
1. We have a vibrant community of developers helping each other in our `Telegram group <https://telegram.me/pythontelegrambotgroup>`_. Join us!
|
||||
|
||||
2. In case you are unable to join our group due to Telegram restrictions, you can use our `IRC channel <https://webchat.freenode.net/?channels=##python-telegram-bot>`_.
|
||||
|
||||
3. Report bugs, request new features or ask questions by `creating an issue <https://github.com/python-telegram-bot/python-telegram-bot/issues/new/choose>`_ or `a discussion <https://github.com/python-telegram-bot/python-telegram-bot/discussions/new>`_.
|
||||
|
||||
4. Our `Wiki pages <https://github.com/python-telegram-bot/python-telegram-bot/wiki/>`_ offer a growing amount of resources.
|
||||
|
||||
5. You can even ask for help on Stack Overflow using the `python-telegram-bot tag <https://stackoverflow.com/questions/tagged/python-telegram-bot>`_.
|
||||
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
|
||||
Contributions of all sizes are welcome. Please review our `contribution guidelines <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.github/CONTRIBUTING.rst>`_ to get started. You can also help by `reporting bugs <https://github.com/python-telegram-bot/python-telegram-bot/issues/new>`_.
|
||||
|
||||
=======
|
||||
License
|
||||
=======
|
||||
|
||||
You may copy, distribute and modify the software provided that modifications are described and licensed for free under `LGPL-3 <https://www.gnu.org/licenses/lgpl-3.0.html>`_. Derivatives works (including modifications or anything statically linked to the library) can only be redistributed under LGPL-3, but applications that use the library don't have to be.
|
||||
@@ -1,38 +0,0 @@
|
||||
environment:
|
||||
|
||||
matrix:
|
||||
# For Python versions available on Appveyor, see
|
||||
# http://www.appveyor.com/docs/installed-software#python
|
||||
# The list here is complete (excluding Python 2.6, which
|
||||
# isn't covered by this document) at the time of writing.
|
||||
|
||||
- PYTHON: "C:\\Python27"
|
||||
- PYTHON: "C:\\Python34"
|
||||
- PYTHON: "C:\\Python35"
|
||||
- PYTHON: "C:\\Python36"
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
skip_branch_with_pr: true
|
||||
|
||||
max_jobs: 1
|
||||
|
||||
install:
|
||||
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
|
||||
- "git submodule update --init --recursive"
|
||||
# Check that we have the expected version and architecture for Python
|
||||
- "python --version"
|
||||
# We need wheel installed to build wheels
|
||||
- "pip install -U codecov pytest-cov"
|
||||
- "pip install -r requirements.txt"
|
||||
- "pip install -r requirements-dev.txt"
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- "pytest -m \"not nocoverage\" --cov --cov-report xml:coverage.xml"
|
||||
|
||||
after_test:
|
||||
- "codecov -f coverage.xml -F Appveyor"
|
||||
@@ -1 +1,10 @@
|
||||
comment: false
|
||||
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
# We allow small coverage decreases in the project because we don't retry
|
||||
# on hitting flood limits, which adds noise to the coverage
|
||||
target: auto
|
||||
threshold: 0.1%
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
cp -R contrib/debian .
|
||||
debuild -us -uc
|
||||
debian/rules clean
|
||||
rm -rf debian
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram (12.0.0b1) unstable; urgency=medium
|
||||
|
||||
* Debian packaging;
|
||||
* Initial Release.
|
||||
|
||||
-- Marco Marinello <me@marcomarinello.it> Thu, 22 Aug 2019 20:36:47 +0200
|
||||
@@ -0,0 +1 @@
|
||||
11
|
||||
@@ -0,0 +1,25 @@
|
||||
Source: telegram
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Marco Marinello <me@marcomarinello.it>
|
||||
Build-Depends: debhelper (>= 11), dh-python, python3-all, python3-setuptools
|
||||
Standards-Version: 4.1.3
|
||||
Homepage: https://python-telegram-bot.org
|
||||
X-Python-Version: >= 3.2
|
||||
Vcs-Browser: https://github.com/python-telegram-bot/python-telegram-bot
|
||||
Vcs-Git: https://github.com/python-telegram-bot/python-telegram-bot.git
|
||||
|
||||
Package: python3-telegram-bot
|
||||
Architecture: any
|
||||
Depends: ${python3:Depends}, ${misc:Depends}
|
||||
Description: We have made you a wrapper you can't refuse!
|
||||
The Python Telegram bot (Python 3)
|
||||
This library provides a pure Python interface for the Telegram Bot API.
|
||||
It's compatible with Python versions 3.5+ and PyPy.
|
||||
.
|
||||
In addition to the pure API implementation, this library features
|
||||
a number of high-level
|
||||
classes to make the development of bots easy and straightforward.
|
||||
These classes are contained in the telegram.ext submodule.
|
||||
.
|
||||
This package installs the library for Python 3.
|
||||
@@ -0,0 +1,30 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: telegram
|
||||
Source: https://github.com/python-telegram-bot/python-telegram-bot
|
||||
|
||||
Files: *
|
||||
Copyright: 2019 Leandro Toledo
|
||||
2019 see AUTHORS file
|
||||
License: LGPLv3
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2019 Marco Marinello <me@marcomarinello.it>
|
||||
License: GPL-3.0+
|
||||
|
||||
License: GPL-3.0+
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
AUTHORS.rst /usr/share/doc/python3-telegram-bot
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/make -f
|
||||
# See debhelper(7) (uncomment to enable)
|
||||
# output every command that modifies files on the build system.
|
||||
#export DH_VERBOSE = 1
|
||||
|
||||
export PYBUILD_NAME=telegram
|
||||
|
||||
%:
|
||||
DEB_BUILD_OPTIONS=nocheck dh $@ --with python3 --buildsystem=pybuild
|
||||
|
||||
|
||||
# If you need to rebuild the Sphinx documentation
|
||||
# Add spinxdoc to the dh --with line
|
||||
#override_dh_auto_build:
|
||||
# dh_auto_build
|
||||
# PYTHONPATH=. http_proxy='127.0.0.1:9' sphinx-build -N -bhtml docs/ build/html # HTML generator
|
||||
# PYTHONPATH=. http_proxy='127.0.0.1:9' sphinx-build -N -bman docs/ build/man # Manpage generator
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
3.0 (native)
|
||||
@@ -0,0 +1 @@
|
||||
extend-diff-ignore = "^[^/]*[.]egg-info/"
|
||||
@@ -1,3 +1,3 @@
|
||||
sphinx>=1.5.4
|
||||
sphinx>=1.7.9
|
||||
sphinx_rtd_theme
|
||||
sphinx-pypi-upload
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
.. include:: ../../CHANGES.rst
|
||||
+8
-4
@@ -24,7 +24,7 @@ sys.path.insert(0, os.path.abspath('../..'))
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = '1.5.4' # fixes issues with autodoc-skip-member and napoleon
|
||||
needs_sphinx = '1.7.9'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
@@ -50,7 +50,7 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Python Telegram Bot'
|
||||
copyright = u'2015-2018, Leandro Toledo'
|
||||
copyright = u'2015-2021, Leandro Toledo'
|
||||
author = u'Leandro Toledo'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
@@ -58,9 +58,9 @@ author = u'Leandro Toledo'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '11.0' # telegram.__version__[:3]
|
||||
version = '13.2' # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '11.0.0' # telegram.__version__
|
||||
release = '13.2' # telegram.__version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@@ -289,6 +289,10 @@ texinfo_documents = [
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
|
||||
# Napoleon stuff
|
||||
|
||||
napoleon_use_admonition_for_examples = True
|
||||
|
||||
# -- script stuff --------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
+20
-9
@@ -6,8 +6,23 @@
|
||||
Welcome to Python Telegram Bot's documentation!
|
||||
===============================================
|
||||
|
||||
Below you can find the documentation for the python-telegram-bot library. except for the .ext package most of the
|
||||
objects in the package reflect the types as defined by the `telegram bot api <https://core.telegram.org/bots/api>`_.
|
||||
Guides and tutorials
|
||||
====================
|
||||
|
||||
If you're just starting out with the library, we recommend following our `"Your first Bot" <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Extensions-%E2%80%93-Your-first-Bot>`_ tutorial that you can find on our `wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki>`_.
|
||||
On our wiki you will also find guides like how to use handlers, webhooks, emoji, proxies and much more.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
A great way to learn is by looking at examples. Ours can be found at our `github in the examples folder <https://github.com/python-telegram-bot/python-telegram-bot/tree/master/examples>`_.
|
||||
|
||||
|
||||
Reference
|
||||
=========
|
||||
|
||||
Below you can find a reference of all the classes and methods in python-telegram-bot.
|
||||
Apart from the `telegram.ext` package the objects should reflect the types defined in the `official telegram bot api documentation <https://core.telegram.org/bots/api>`_.
|
||||
|
||||
.. toctree::
|
||||
telegram
|
||||
@@ -15,13 +30,9 @@ objects in the package reflect the types as defined by the `telegram bot api <ht
|
||||
Changelog
|
||||
---------
|
||||
|
||||
.. include:: ../../CHANGES.rst
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
changelog
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.BotCommand
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.BotCommand
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ChatLocation
|
||||
=====================
|
||||
|
||||
.. autoclass:: telegram.ChatLocation
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ChatPermissions
|
||||
========================
|
||||
|
||||
.. autoclass:: telegram.ChatPermissions
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.Dice
|
||||
=============
|
||||
|
||||
.. autoclass:: telegram.Dice
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.BasePersistence
|
||||
============================
|
||||
|
||||
.. autoclass:: telegram.ext.BasePersistence
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,5 @@
|
||||
telegram.ext.CallbackContext
|
||||
============================
|
||||
|
||||
.. autoclass:: telegram.ext.CallbackContext
|
||||
:members:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.Defaults
|
||||
=====================
|
||||
|
||||
.. autoclass:: telegram.ext.Defaults
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.DictPersistence
|
||||
============================
|
||||
|
||||
.. autoclass:: telegram.ext.DictPersistence
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.DispatcherHandlerStop
|
||||
==================================
|
||||
|
||||
.. autoclass:: telegram.ext.DispatcherHandlerStop
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.PicklePersistence
|
||||
==============================
|
||||
|
||||
.. autoclass:: telegram.ext.PicklePersistence
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.PollAnswerHandler
|
||||
==============================
|
||||
|
||||
.. autoclass:: telegram.ext.PollAnswerHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.PollHandler
|
||||
========================
|
||||
|
||||
.. autoclass:: telegram.ext.PollHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.PrefixHandler
|
||||
===========================
|
||||
|
||||
.. autoclass:: telegram.ext.PrefixHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -5,7 +5,9 @@ telegram.ext package
|
||||
|
||||
telegram.ext.updater
|
||||
telegram.ext.dispatcher
|
||||
telegram.ext.filters
|
||||
telegram.ext.dispatcherhandlerstop
|
||||
telegram.ext.callbackcontext
|
||||
telegram.ext.defaults
|
||||
telegram.ext.job
|
||||
telegram.ext.jobqueue
|
||||
telegram.ext.messagequeue
|
||||
@@ -19,13 +21,33 @@ Handlers
|
||||
telegram.ext.handler
|
||||
telegram.ext.callbackqueryhandler
|
||||
telegram.ext.choseninlineresulthandler
|
||||
telegram.ext.conversationhandler
|
||||
telegram.ext.commandhandler
|
||||
telegram.ext.conversationhandler
|
||||
telegram.ext.inlinequeryhandler
|
||||
telegram.ext.messagehandler
|
||||
telegram.ext.filters
|
||||
telegram.ext.pollanswerhandler
|
||||
telegram.ext.pollhandler
|
||||
telegram.ext.precheckoutqueryhandler
|
||||
telegram.ext.prefixhandler
|
||||
telegram.ext.regexhandler
|
||||
telegram.ext.shippingqueryhandler
|
||||
telegram.ext.stringcommandhandler
|
||||
telegram.ext.stringregexhandler
|
||||
telegram.ext.typehandler
|
||||
|
||||
Persistence
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.ext.basepersistence
|
||||
telegram.ext.picklepersistence
|
||||
telegram.ext.dictpersistence
|
||||
|
||||
utils
|
||||
-----
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.ext.utils.promise
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.utils.promise.Promise
|
||||
==================================
|
||||
|
||||
.. autoclass:: telegram.ext.utils.promise.Promise
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.KeyboardButtonPollType
|
||||
===============================
|
||||
|
||||
.. autoclass:: telegram.KeyboardButtonPollType
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.LoginUrl
|
||||
=================
|
||||
|
||||
.. autoclass:: telegram.LoginUrl
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.MessageId
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.MessageId
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.Poll
|
||||
=============
|
||||
|
||||
.. autoclass:: telegram.Poll
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.PollAnswer
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.PollAnswer
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.PollOption
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.PollOption
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ProximityAlertTriggered
|
||||
================================
|
||||
|
||||
.. autoclass:: telegram.ProximityAlertTriggered
|
||||
:members:
|
||||
:show-inheritance:
|
||||
+98
-94
@@ -1,117 +1,129 @@
|
||||
.. include:: telegram.ext.rst
|
||||
|
||||
|
||||
telegram package
|
||||
================
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.ext
|
||||
telegram.utils
|
||||
telegram.animation
|
||||
telegram.audio
|
||||
telegram.bot
|
||||
telegram.callbackquery
|
||||
telegram.chat
|
||||
telegram.chataction
|
||||
telegram.chatmember
|
||||
telegram.chatphoto
|
||||
telegram.constants
|
||||
telegram.contact
|
||||
telegram.document
|
||||
telegram.error
|
||||
telegram.file
|
||||
telegram.forcereply
|
||||
telegram.inlinekeyboardbutton
|
||||
telegram.inlinekeyboardmarkup
|
||||
telegram.inputfile
|
||||
telegram.inputmedia
|
||||
telegram.inputmediaanimation
|
||||
telegram.inputmediaaudio
|
||||
telegram.inputmediadocument
|
||||
telegram.inputmediaphoto
|
||||
telegram.inputmediavideo
|
||||
telegram.keyboardbutton
|
||||
telegram.location
|
||||
telegram.message
|
||||
telegram.messageentity
|
||||
telegram.parsemode
|
||||
telegram.photosize
|
||||
telegram.replykeyboardremove
|
||||
telegram.replykeyboardmarkup
|
||||
telegram.replymarkup
|
||||
telegram.telegramobject
|
||||
telegram.update
|
||||
telegram.user
|
||||
telegram.userprofilephotos
|
||||
telegram.venue
|
||||
telegram.video
|
||||
telegram.videonote
|
||||
telegram.voice
|
||||
telegram.webhookinfo
|
||||
telegram.animation
|
||||
telegram.audio
|
||||
telegram.bot
|
||||
telegram.botcommand
|
||||
telegram.callbackquery
|
||||
telegram.chat
|
||||
telegram.chataction
|
||||
telegram.chatlocation
|
||||
telegram.chatmember
|
||||
telegram.chatpermissions
|
||||
telegram.chatphoto
|
||||
telegram.constants
|
||||
telegram.contact
|
||||
telegram.dice
|
||||
telegram.document
|
||||
telegram.error
|
||||
telegram.file
|
||||
telegram.forcereply
|
||||
telegram.inlinekeyboardbutton
|
||||
telegram.inlinekeyboardmarkup
|
||||
telegram.inputfile
|
||||
telegram.inputmedia
|
||||
telegram.inputmediaanimation
|
||||
telegram.inputmediaaudio
|
||||
telegram.inputmediadocument
|
||||
telegram.inputmediaphoto
|
||||
telegram.inputmediavideo
|
||||
telegram.keyboardbutton
|
||||
telegram.keyboardbuttonpolltype
|
||||
telegram.location
|
||||
telegram.loginurl
|
||||
telegram.message
|
||||
telegram.messageid
|
||||
telegram.messageentity
|
||||
telegram.parsemode
|
||||
telegram.photosize
|
||||
telegram.poll
|
||||
telegram.pollanswer
|
||||
telegram.polloption
|
||||
telegram.proximityalerttriggered
|
||||
telegram.replykeyboardremove
|
||||
telegram.replykeyboardmarkup
|
||||
telegram.replymarkup
|
||||
telegram.telegramobject
|
||||
telegram.update
|
||||
telegram.user
|
||||
telegram.userprofilephotos
|
||||
telegram.venue
|
||||
telegram.video
|
||||
telegram.videonote
|
||||
telegram.voice
|
||||
telegram.webhookinfo
|
||||
|
||||
Stickers
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.sticker
|
||||
telegram.stickerset
|
||||
telegram.maskposition
|
||||
telegram.sticker
|
||||
telegram.stickerset
|
||||
telegram.maskposition
|
||||
|
||||
Inline Mode
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.inlinequery
|
||||
telegram.inlinequeryresult
|
||||
telegram.inlinequeryresultarticle
|
||||
telegram.inlinequeryresultaudio
|
||||
telegram.inlinequeryresultcachedaudio
|
||||
telegram.inlinequeryresultcacheddocument
|
||||
telegram.inlinequeryresultcachedgif
|
||||
telegram.inlinequeryresultcachedmpeg4gif
|
||||
telegram.inlinequeryresultcachedphoto
|
||||
telegram.inlinequeryresultcachedsticker
|
||||
telegram.inlinequeryresultcachedvideo
|
||||
telegram.inlinequeryresultcachedvoice
|
||||
telegram.inlinequeryresultcontact
|
||||
telegram.inlinequeryresultdocument
|
||||
telegram.inlinequeryresultgame
|
||||
telegram.inlinequeryresultgif
|
||||
telegram.inlinequeryresultlocation
|
||||
telegram.inlinequeryresultmpeg4gif
|
||||
telegram.inlinequeryresultphoto
|
||||
telegram.inlinequeryresultvenue
|
||||
telegram.inlinequeryresultvideo
|
||||
telegram.inlinequeryresultvoice
|
||||
telegram.inputmessagecontent
|
||||
telegram.inputtextmessagecontent
|
||||
telegram.inputlocationmessagecontent
|
||||
telegram.inputvenuemessagecontent
|
||||
telegram.inputcontactmessagecontent
|
||||
telegram.choseninlineresult
|
||||
telegram.inlinequery
|
||||
telegram.inlinequeryresult
|
||||
telegram.inlinequeryresultarticle
|
||||
telegram.inlinequeryresultaudio
|
||||
telegram.inlinequeryresultcachedaudio
|
||||
telegram.inlinequeryresultcacheddocument
|
||||
telegram.inlinequeryresultcachedgif
|
||||
telegram.inlinequeryresultcachedmpeg4gif
|
||||
telegram.inlinequeryresultcachedphoto
|
||||
telegram.inlinequeryresultcachedsticker
|
||||
telegram.inlinequeryresultcachedvideo
|
||||
telegram.inlinequeryresultcachedvoice
|
||||
telegram.inlinequeryresultcontact
|
||||
telegram.inlinequeryresultdocument
|
||||
telegram.inlinequeryresultgame
|
||||
telegram.inlinequeryresultgif
|
||||
telegram.inlinequeryresultlocation
|
||||
telegram.inlinequeryresultmpeg4gif
|
||||
telegram.inlinequeryresultphoto
|
||||
telegram.inlinequeryresultvenue
|
||||
telegram.inlinequeryresultvideo
|
||||
telegram.inlinequeryresultvoice
|
||||
telegram.inputmessagecontent
|
||||
telegram.inputtextmessagecontent
|
||||
telegram.inputlocationmessagecontent
|
||||
telegram.inputvenuemessagecontent
|
||||
telegram.inputcontactmessagecontent
|
||||
telegram.choseninlineresult
|
||||
|
||||
Payments
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.labeledprice
|
||||
telegram.invoice
|
||||
telegram.shippingaddress
|
||||
telegram.orderinfo
|
||||
telegram.shippingoption
|
||||
telegram.successfulpayment
|
||||
telegram.shippingquery
|
||||
telegram.precheckoutquery
|
||||
telegram.labeledprice
|
||||
telegram.invoice
|
||||
telegram.shippingaddress
|
||||
telegram.orderinfo
|
||||
telegram.shippingoption
|
||||
telegram.successfulpayment
|
||||
telegram.shippingquery
|
||||
telegram.precheckoutquery
|
||||
|
||||
Games
|
||||
-----
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.game
|
||||
telegram.callbackgame
|
||||
telegram.gamehighscore
|
||||
telegram.game
|
||||
telegram.callbackgame
|
||||
telegram.gamehighscore
|
||||
|
||||
Passport
|
||||
--------
|
||||
@@ -137,12 +149,4 @@ Passport
|
||||
telegram.encryptedpassportelement
|
||||
telegram.encryptedcredentials
|
||||
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: telegram
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
:noindex:
|
||||
.. include:: telegram.utils.rst
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
telegram.utils.promise.Promise
|
||||
==============================
|
||||
|
||||
.. autoclass:: telegram.utils.promise.Promise
|
||||
:members:
|
||||
:show-inheritance:
|
||||
.. py:class:: telegram.utils.promise.Promise
|
||||
|
||||
Shortcut for :class:`telegram.ext.utils.promise.Promise`.
|
||||
|
||||
.. deprecated:: 13.2
|
||||
Use :class:`telegram.ext.utils.promise.Promise` instead.
|
||||
|
||||
@@ -6,3 +6,4 @@ telegram.utils package
|
||||
telegram.utils.helpers
|
||||
telegram.utils.promise
|
||||
telegram.utils.request
|
||||
telegram.utils.types
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.utils.types Module
|
||||
===========================
|
||||
|
||||
.. automodule:: telegram.utils.types
|
||||
:members:
|
||||
:show-inheritance:
|
||||
+24
-3
@@ -1,10 +1,10 @@
|
||||
# Examples
|
||||
|
||||
In this folder there are small examples to show what a bot written with `python-telegram-bot` looks like. Some bots focus on one specific aspect of the Telegram Bot API while others focus on one of the mechanics of this library. Except for the [`echobot.py`](#pure-api) example, they all use the high-level framework this library provides with the [`telegram.ext`](https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.html) submodule.
|
||||
In this folder are small examples to show what a bot written with `python-telegram-bot` looks like. Some bots focus on one specific aspect of the Telegram Bot API while others focus on one of the mechanics of this library. Except for the [`rawapibot.py`](#pure-api) example, they all use the high-level framework this library provides with the [`telegram.ext`](https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.html) submodule.
|
||||
|
||||
All examples are licensed under the [CC0 License](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/LICENSE.txt) and are therefore fully dedicated to the public domain. You can use them as the base for your own bots without worrying about copyrights.
|
||||
|
||||
### [`echobot2.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/echobot2.py)
|
||||
### [`echobot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/echobot.py)
|
||||
This is probably the base for most of the bots made with `python-telegram-bot`. It simply replies to each text message with a message that contains the same text.
|
||||
|
||||
### [`timerbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/timerbot.py)
|
||||
@@ -16,14 +16,35 @@ A common task for a bot is to ask information from the user. In v5.0 of this lib
|
||||
### [`conversationbot2.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/conversationbot2.py)
|
||||
A more complex example of a bot that uses the `ConversationHandler`. It is also more confusing. Good thing there is a [fancy state diagram](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/conversationbot2.png) for this one, too!
|
||||
|
||||
### [`nestedconversationbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/nestedconversationbot.py)
|
||||
A even more complex example of a bot that uses the nested `ConversationHandler`s. While it's certainly not that complex that you couldn't built it without nested `ConversationHanldler`s, it gives a good impression on how to work with them. Of course, there is a [fancy state diagram](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/nestedconversationbot.png) for this example, too!
|
||||
|
||||
### [`persistentconversationbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/persistentconversationbot.py)
|
||||
A basic example of a bot store conversation state and user_data over multiple restarts.
|
||||
|
||||
### [`inlinekeyboard.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinekeyboard.py)
|
||||
This example sheds some light on inline keyboards, callback queries and message editing.
|
||||
|
||||
### [`inlinekeyboard2.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinekeyboard2.py)
|
||||
A more complex example about inline keyboards, callback queries and message editing. This example showcases how an interactive menu could be build using inline keyboards.
|
||||
|
||||
### [`deeplinking.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/deeplinking.py)
|
||||
A basic example on how to use deeplinking with inline keyboards.
|
||||
|
||||
### [`inlinebot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinebot.py)
|
||||
A basic example of an [inline bot](https://core.telegram.org/bots/inline). Don't forget to enable inline mode with [@BotFather](https://telegram.me/BotFather).
|
||||
|
||||
### [`pollbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/pollbot.py)
|
||||
This example sheds some light on polls, poll answers and the corresponding handlers.
|
||||
|
||||
### [`passportbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/passportbot.py)
|
||||
A basic example of a bot that can accept passports. Use in combination with [`passportbot.html`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/passportbot.html). Don't forget to enable and configure payments with [@BotFather](https://telegram.me/BotFather). Check out this [guide](https://git.io/fAvYd) on Telegram passports in PTB.
|
||||
|
||||
### [`paymentbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/paymentbot.py)
|
||||
A basic example of a bot that can accept payments. Don't forget to enable and configure payments with [@BotFather](https://telegram.me/BotFather).
|
||||
|
||||
### [`errorhandlerbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/errorhandlerbot.py)
|
||||
A basic example on how to set up a custom error handler.
|
||||
|
||||
## Pure API
|
||||
The [`echobot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/echobot.py) example uses only the pure, "bare-metal" API wrapper.
|
||||
The [`rawapibot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/rawapibot.py) example uses only the pure, "bare-metal" API wrapper.
|
||||
|
||||
+62
-60
@@ -1,11 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Simple Bot to reply to Telegram messages
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
"""
|
||||
This Bot uses the Updater class to handle the bot.
|
||||
|
||||
"""
|
||||
First, a few callback functions are defined. Then, those functions are passed to
|
||||
the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
@@ -17,84 +15,99 @@ Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
from telegram import (ReplyKeyboardMarkup, ReplyKeyboardRemove)
|
||||
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler,
|
||||
ConversationHandler)
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
|
||||
from telegram.ext import (
|
||||
Updater,
|
||||
CommandHandler,
|
||||
MessageHandler,
|
||||
Filters,
|
||||
ConversationHandler,
|
||||
CallbackContext,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GENDER, PHOTO, LOCATION, BIO = range(4)
|
||||
|
||||
|
||||
def start(bot, update):
|
||||
def start(update: Update, context: CallbackContext) -> int:
|
||||
reply_keyboard = [['Boy', 'Girl', 'Other']]
|
||||
|
||||
update.message.reply_text(
|
||||
'Hi! My name is Professor Bot. I will hold a conversation with you. '
|
||||
'Send /cancel to stop talking to me.\n\n'
|
||||
'Are you a boy or a girl?',
|
||||
reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
|
||||
reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True),
|
||||
)
|
||||
|
||||
return GENDER
|
||||
|
||||
|
||||
def gender(bot, update):
|
||||
def gender(update: Update, context: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
logger.info("Gender of %s: %s", user.first_name, update.message.text)
|
||||
update.message.reply_text('I see! Please send me a photo of yourself, '
|
||||
'so I know what you look like, or send /skip if you don\'t want to.',
|
||||
reply_markup=ReplyKeyboardRemove())
|
||||
update.message.reply_text(
|
||||
'I see! Please send me a photo of yourself, '
|
||||
'so I know what you look like, or send /skip if you don\'t want to.',
|
||||
reply_markup=ReplyKeyboardRemove(),
|
||||
)
|
||||
|
||||
return PHOTO
|
||||
|
||||
|
||||
def photo(bot, update):
|
||||
def photo(update: Update, context: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
photo_file = bot.get_file(update.message.photo[-1].file_id)
|
||||
photo_file = update.message.photo[-1].get_file()
|
||||
photo_file.download('user_photo.jpg')
|
||||
logger.info("Photo of %s: %s", user.first_name, 'user_photo.jpg')
|
||||
update.message.reply_text('Gorgeous! Now, send me your location please, '
|
||||
'or send /skip if you don\'t want to.')
|
||||
update.message.reply_text(
|
||||
'Gorgeous! Now, send me your location please, ' 'or send /skip if you don\'t want to.'
|
||||
)
|
||||
|
||||
return LOCATION
|
||||
|
||||
|
||||
def skip_photo(bot, update):
|
||||
def skip_photo(update: Update, context: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
logger.info("User %s did not send a photo.", user.first_name)
|
||||
update.message.reply_text('I bet you look great! Now, send me your location please, '
|
||||
'or send /skip.')
|
||||
update.message.reply_text(
|
||||
'I bet you look great! Now, send me your location please, ' 'or send /skip.'
|
||||
)
|
||||
|
||||
return LOCATION
|
||||
|
||||
|
||||
def location(bot, update):
|
||||
def location(update: Update, context: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
user_location = update.message.location
|
||||
logger.info("Location of %s: %f / %f", user.first_name, user_location.latitude,
|
||||
user_location.longitude)
|
||||
update.message.reply_text('Maybe I can visit you sometime! '
|
||||
'At last, tell me something about yourself.')
|
||||
logger.info(
|
||||
"Location of %s: %f / %f", user.first_name, user_location.latitude, user_location.longitude
|
||||
)
|
||||
update.message.reply_text(
|
||||
'Maybe I can visit you sometime! ' 'At last, tell me something about yourself.'
|
||||
)
|
||||
|
||||
return BIO
|
||||
|
||||
|
||||
def skip_location(bot, update):
|
||||
def skip_location(update: Update, context: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
logger.info("User %s did not send a location.", user.first_name)
|
||||
update.message.reply_text('You seem a bit paranoid! '
|
||||
'At last, tell me something about yourself.')
|
||||
update.message.reply_text(
|
||||
'You seem a bit paranoid! ' 'At last, tell me something about yourself.'
|
||||
)
|
||||
|
||||
return BIO
|
||||
|
||||
|
||||
def bio(bot, update):
|
||||
def bio(update: Update, context: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
logger.info("Bio of %s: %s", user.first_name, update.message.text)
|
||||
update.message.reply_text('Thank you! I hope we can talk again some day.')
|
||||
@@ -102,50 +115,39 @@ def bio(bot, update):
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def cancel(bot, update):
|
||||
def cancel(update: Update, context: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
logger.info("User %s canceled the conversation.", user.first_name)
|
||||
update.message.reply_text('Bye! I hope we can talk again some day.',
|
||||
reply_markup=ReplyKeyboardRemove())
|
||||
update.message.reply_text(
|
||||
'Bye! I hope we can talk again some day.', reply_markup=ReplyKeyboardRemove()
|
||||
)
|
||||
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the EventHandler and pass it your bot's token.
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO
|
||||
conv_handler = ConversationHandler(
|
||||
entry_points=[CommandHandler('start', start)],
|
||||
|
||||
states={
|
||||
GENDER: [RegexHandler('^(Boy|Girl|Other)$', gender)],
|
||||
|
||||
PHOTO: [MessageHandler(Filters.photo, photo),
|
||||
CommandHandler('skip', skip_photo)],
|
||||
|
||||
LOCATION: [MessageHandler(Filters.location, location),
|
||||
CommandHandler('skip', skip_location)],
|
||||
|
||||
BIO: [MessageHandler(Filters.text, bio)]
|
||||
GENDER: [MessageHandler(Filters.regex('^(Boy|Girl|Other)$'), gender)],
|
||||
PHOTO: [MessageHandler(Filters.photo, photo), CommandHandler('skip', skip_photo)],
|
||||
LOCATION: [
|
||||
MessageHandler(Filters.location, location),
|
||||
CommandHandler('skip', skip_location),
|
||||
],
|
||||
BIO: [MessageHandler(Filters.text & ~Filters.command, bio)],
|
||||
},
|
||||
|
||||
fallbacks=[CommandHandler('cancel', cancel)]
|
||||
fallbacks=[CommandHandler('cancel', cancel)],
|
||||
)
|
||||
|
||||
dp.add_handler(conv_handler)
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
dispatcher.add_handler(conv_handler)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Simple Bot to reply to Telegram messages
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
"""
|
||||
This Bot uses the Updater class to handle the bot.
|
||||
|
||||
"""
|
||||
First, a few callback functions are defined. Then, those functions are passed to
|
||||
the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
@@ -17,128 +15,134 @@ Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
from telegram import ReplyKeyboardMarkup
|
||||
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler,
|
||||
ConversationHandler)
|
||||
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from telegram import ReplyKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
Updater,
|
||||
CommandHandler,
|
||||
MessageHandler,
|
||||
Filters,
|
||||
ConversationHandler,
|
||||
CallbackContext,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CHOOSING, TYPING_REPLY, TYPING_CHOICE = range(3)
|
||||
|
||||
reply_keyboard = [['Age', 'Favourite colour'],
|
||||
['Number of siblings', 'Something else...'],
|
||||
['Done']]
|
||||
reply_keyboard = [
|
||||
['Age', 'Favourite colour'],
|
||||
['Number of siblings', 'Something else...'],
|
||||
['Done'],
|
||||
]
|
||||
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
|
||||
|
||||
|
||||
def facts_to_str(user_data):
|
||||
def facts_to_str(user_data: Dict[str, str]) -> str:
|
||||
facts = list()
|
||||
|
||||
for key, value in user_data.items():
|
||||
facts.append('{} - {}'.format(key, value))
|
||||
facts.append(f'{key} - {value}')
|
||||
|
||||
return "\n".join(facts).join(['\n', '\n'])
|
||||
|
||||
|
||||
def start(bot, update):
|
||||
def start(update: Update, context: CallbackContext) -> int:
|
||||
update.message.reply_text(
|
||||
"Hi! My name is Doctor Botter. I will hold a more complex conversation with you. "
|
||||
"Why don't you tell me something about yourself?",
|
||||
reply_markup=markup)
|
||||
reply_markup=markup,
|
||||
)
|
||||
|
||||
return CHOOSING
|
||||
|
||||
|
||||
def regular_choice(bot, update, user_data):
|
||||
def regular_choice(update: Update, context: CallbackContext) -> int:
|
||||
text = update.message.text
|
||||
user_data['choice'] = text
|
||||
update.message.reply_text(
|
||||
'Your {}? Yes, I would love to hear about that!'.format(text.lower()))
|
||||
context.user_data['choice'] = text
|
||||
update.message.reply_text(f'Your {text.lower()}? Yes, I would love to hear about that!')
|
||||
|
||||
return TYPING_REPLY
|
||||
|
||||
|
||||
def custom_choice(bot, update):
|
||||
update.message.reply_text('Alright, please send me the category first, '
|
||||
'for example "Most impressive skill"')
|
||||
def custom_choice(update: Update, context: CallbackContext) -> int:
|
||||
update.message.reply_text(
|
||||
'Alright, please send me the category first, ' 'for example "Most impressive skill"'
|
||||
)
|
||||
|
||||
return TYPING_CHOICE
|
||||
|
||||
|
||||
def received_information(bot, update, user_data):
|
||||
def received_information(update: Update, context: CallbackContext) -> int:
|
||||
user_data = context.user_data
|
||||
text = update.message.text
|
||||
category = user_data['choice']
|
||||
user_data[category] = text
|
||||
del user_data['choice']
|
||||
|
||||
update.message.reply_text("Neat! Just so you know, this is what you already told me:"
|
||||
"{}"
|
||||
"You can tell me more, or change your opinion on something.".format(
|
||||
facts_to_str(user_data)), reply_markup=markup)
|
||||
update.message.reply_text(
|
||||
"Neat! Just so you know, this is what you already told me:"
|
||||
f"{facts_to_str(user_data)} You can tell me more, or change your opinion"
|
||||
" on something.",
|
||||
reply_markup=markup,
|
||||
)
|
||||
|
||||
return CHOOSING
|
||||
|
||||
|
||||
def done(bot, update, user_data):
|
||||
def done(update: Update, context: CallbackContext) -> int:
|
||||
user_data = context.user_data
|
||||
if 'choice' in user_data:
|
||||
del user_data['choice']
|
||||
|
||||
update.message.reply_text("I learned these facts about you:"
|
||||
"{}"
|
||||
"Until next time!".format(facts_to_str(user_data)))
|
||||
update.message.reply_text(
|
||||
f"I learned these facts about you: {facts_to_str(user_data)} Until next time!"
|
||||
)
|
||||
|
||||
user_data.clear()
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO
|
||||
# Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY
|
||||
conv_handler = ConversationHandler(
|
||||
entry_points=[CommandHandler('start', start)],
|
||||
|
||||
states={
|
||||
CHOOSING: [RegexHandler('^(Age|Favourite colour|Number of siblings)$',
|
||||
regular_choice,
|
||||
pass_user_data=True),
|
||||
RegexHandler('^Something else...$',
|
||||
custom_choice),
|
||||
],
|
||||
|
||||
TYPING_CHOICE: [MessageHandler(Filters.text,
|
||||
regular_choice,
|
||||
pass_user_data=True),
|
||||
],
|
||||
|
||||
TYPING_REPLY: [MessageHandler(Filters.text,
|
||||
received_information,
|
||||
pass_user_data=True),
|
||||
],
|
||||
CHOOSING: [
|
||||
MessageHandler(
|
||||
Filters.regex('^(Age|Favourite colour|Number of siblings)$'), regular_choice
|
||||
),
|
||||
MessageHandler(Filters.regex('^Something else...$'), custom_choice),
|
||||
],
|
||||
TYPING_CHOICE: [
|
||||
MessageHandler(
|
||||
Filters.text & ~(Filters.command | Filters.regex('^Done$')), regular_choice
|
||||
)
|
||||
],
|
||||
TYPING_REPLY: [
|
||||
MessageHandler(
|
||||
Filters.text & ~(Filters.command | Filters.regex('^Done$')),
|
||||
received_information,
|
||||
)
|
||||
],
|
||||
},
|
||||
|
||||
fallbacks=[RegexHandler('^Done$', done, pass_user_data=True)]
|
||||
fallbacks=[MessageHandler(Filters.regex('^Done$'), done)],
|
||||
)
|
||||
|
||||
dp.add_handler(conv_handler)
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
dispatcher.add_handler(conv_handler)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Bot that explains Telegram's "Deep Linking Parameters" functionality.
|
||||
|
||||
This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
This Bot uses the Updater class to handle the bot.
|
||||
|
||||
First, a few handler functions are defined. Then, those functions are passed to
|
||||
the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
|
||||
Usage:
|
||||
Deep Linking example. Send /start to get the link.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import ParseMode, InlineKeyboardMarkup, InlineKeyboardButton, Update
|
||||
from telegram.ext import (
|
||||
Updater,
|
||||
CommandHandler,
|
||||
CallbackQueryHandler,
|
||||
Filters,
|
||||
CallbackContext,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
from telegram.utils import helpers
|
||||
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Define constants that will allow us to reuse the deep-linking parameters.
|
||||
CHECK_THIS_OUT = "check-this-out"
|
||||
USING_ENTITIES = "using-entities-here"
|
||||
USING_KEYBOARD = "using-keyboard-here"
|
||||
SO_COOL = "so-cool"
|
||||
|
||||
# Callback data to pass in 3rd level deeplinking
|
||||
KEYBOARD_CALLBACKDATA = "keyboard-callback-data"
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
"""Send a deep-linked URL when the command /start is issued."""
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.username, CHECK_THIS_OUT, group=True)
|
||||
text = "Feel free to tell your friends about it:\n\n" + url
|
||||
update.message.reply_text(text)
|
||||
|
||||
|
||||
def deep_linked_level_1(update: Update, context: CallbackContext) -> None:
|
||||
"""Reached through the CHECK_THIS_OUT payload"""
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.username, SO_COOL)
|
||||
text = (
|
||||
"Awesome, you just accessed hidden functionality! "
|
||||
" Now let's get back to the private chat."
|
||||
)
|
||||
keyboard = InlineKeyboardMarkup.from_button(
|
||||
InlineKeyboardButton(text="Continue here!", url=url)
|
||||
)
|
||||
update.message.reply_text(text, reply_markup=keyboard)
|
||||
|
||||
|
||||
def deep_linked_level_2(update: Update, context: CallbackContext) -> None:
|
||||
"""Reached through the SO_COOL payload"""
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.username, USING_ENTITIES)
|
||||
text = f"You can also mask the deep-linked URLs as links: [▶️ CLICK HERE]({url})."
|
||||
update.message.reply_text(text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True)
|
||||
|
||||
|
||||
def deep_linked_level_3(update: Update, context: CallbackContext) -> None:
|
||||
"""Reached through the USING_ENTITIES payload"""
|
||||
update.message.reply_text(
|
||||
"It is also possible to make deep-linking using InlineKeyboardButtons.",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[[InlineKeyboardButton(text="Like this!", callback_data=KEYBOARD_CALLBACKDATA)]]
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def deep_link_level_3_callback(update: Update, context: CallbackContext) -> None:
|
||||
"""Answers CallbackQuery with deeplinking url."""
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.username, USING_KEYBOARD)
|
||||
update.callback_query.answer(url=url)
|
||||
|
||||
|
||||
def deep_linked_level_4(update: Update, context: CallbackContext) -> None:
|
||||
"""Reached through the USING_KEYBOARD payload"""
|
||||
payload = context.args
|
||||
update.message.reply_text(
|
||||
f"Congratulations! This is as deep as it gets 👏🏻\n\nThe payload was: {payload}"
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
"""Start the bot."""
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# More info on what deep linking actually is (read this first if it's unclear to you):
|
||||
# https://core.telegram.org/bots#deep-linking
|
||||
|
||||
# Register a deep-linking handler
|
||||
dispatcher.add_handler(
|
||||
CommandHandler("start", deep_linked_level_1, Filters.regex(CHECK_THIS_OUT))
|
||||
)
|
||||
|
||||
# This one works with a textual link instead of an URL
|
||||
dispatcher.add_handler(CommandHandler("start", deep_linked_level_2, Filters.regex(SO_COOL)))
|
||||
|
||||
# We can also pass on the deep-linking payload
|
||||
dispatcher.add_handler(
|
||||
CommandHandler("start", deep_linked_level_3, Filters.regex(USING_ENTITIES), pass_args=True)
|
||||
)
|
||||
|
||||
# Possible with inline keyboard buttons aswell
|
||||
dispatcher.add_handler(
|
||||
CommandHandler("start", deep_linked_level_4, Filters.regex(USING_KEYBOARD))
|
||||
)
|
||||
|
||||
# register callback handler for inline keyboard button
|
||||
dispatcher.add_handler(
|
||||
CallbackQueryHandler(deep_link_level_3_callback, pattern=KEYBOARD_CALLBACKDATA)
|
||||
)
|
||||
|
||||
# Make sure the deep-linking handlers occur *before* the normal /start handler.
|
||||
dispatcher.add_handler(CommandHandler("start", start))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
# Run the bot until you press Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT. This should be used most of the time, since
|
||||
# start_polling() is non-blocking and will stop the bot gracefully.
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+56
-38
@@ -1,55 +1,73 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Simple Bot to reply to Telegram messages.
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
This is built on the API wrapper, see echobot2.py to see the same example built
|
||||
on the telegram.ext bot framework.
|
||||
This program is dedicated to the public domain under the CC0 license.
|
||||
"""
|
||||
Simple Bot to reply to Telegram messages.
|
||||
|
||||
First, a few handler functions are defined. Then, those functions are passed to
|
||||
the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
|
||||
Usage:
|
||||
Basic Echobot example, repeats messages.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import telegram
|
||||
from telegram.error import NetworkError, Unauthorized
|
||||
from time import sleep
|
||||
|
||||
from telegram import Update
|
||||
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
update_id = None
|
||||
# Define a few command handlers. These usually take the two arguments update and
|
||||
# context. Error handlers also receive the raised TelegramError object in error.
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
"""Send a message when the command /start is issued."""
|
||||
update.message.reply_text('Hi!')
|
||||
|
||||
|
||||
def help_command(update: Update, context: CallbackContext) -> None:
|
||||
"""Send a message when the command /help is issued."""
|
||||
update.message.reply_text('Help!')
|
||||
|
||||
|
||||
def echo(update: Update, context: CallbackContext) -> None:
|
||||
"""Echo the user message."""
|
||||
update.message.reply_text(update.message.text)
|
||||
|
||||
|
||||
def main():
|
||||
"""Run the bot."""
|
||||
global update_id
|
||||
# Telegram Bot Authorization Token
|
||||
bot = telegram.Bot('TOKEN')
|
||||
"""Start the bot."""
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# get the first pending update_id, this is so we can skip over it in case
|
||||
# we get an "Unauthorized" exception.
|
||||
try:
|
||||
update_id = bot.get_updates()[0].update_id
|
||||
except IndexError:
|
||||
update_id = None
|
||||
# Get the dispatcher to register handlers
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
# on different commands - answer in Telegram
|
||||
dispatcher.add_handler(CommandHandler("start", start))
|
||||
dispatcher.add_handler(CommandHandler("help", help_command))
|
||||
|
||||
while True:
|
||||
try:
|
||||
echo(bot)
|
||||
except NetworkError:
|
||||
sleep(1)
|
||||
except Unauthorized:
|
||||
# The user has removed or blocked the bot.
|
||||
update_id += 1
|
||||
# on noncommand i.e message - echo the message on Telegram
|
||||
dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, echo))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
def echo(bot):
|
||||
"""Echo the message the user sent."""
|
||||
global update_id
|
||||
# Request updates after the last update_id
|
||||
for update in bot.get_updates(offset=update_id, timeout=10):
|
||||
update_id = update.update_id + 1
|
||||
|
||||
if update.message: # your bot can receive updates without messages
|
||||
# Reply to the message
|
||||
update.message.reply_text(update.message.text)
|
||||
# Run the bot until you press Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT. This should be used most of the time, since
|
||||
# start_polling() is non-blocking and will stop the bot gracefully.
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Simple Bot to reply to Telegram messages.
|
||||
|
||||
This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
This Bot uses the Updater class to handle the bot.
|
||||
|
||||
First, a few handler functions are defined. Then, those functions are passed to
|
||||
the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
|
||||
Usage:
|
||||
Basic Echobot example, repeats messages.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
|
||||
import logging
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Define a few command handlers. These usually take the two arguments bot and
|
||||
# update. Error handlers also receive the raised TelegramError object in error.
|
||||
def start(bot, update):
|
||||
"""Send a message when the command /start is issued."""
|
||||
update.message.reply_text('Hi!')
|
||||
|
||||
|
||||
def help(bot, update):
|
||||
"""Send a message when the command /help is issued."""
|
||||
update.message.reply_text('Help!')
|
||||
|
||||
|
||||
def echo(bot, update):
|
||||
"""Echo the user message."""
|
||||
update.message.reply_text(update.message.text)
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
|
||||
|
||||
def main():
|
||||
"""Start the bot."""
|
||||
# Create the EventHandler and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
||||
# on different commands - answer in Telegram
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
dp.add_handler(CommandHandler("help", help))
|
||||
|
||||
# on noncommand i.e message - echo the message on Telegram
|
||||
dp.add_handler(MessageHandler(Filters.text, echo))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
# Run the bot until you press Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT. This should be used most of the time, since
|
||||
# start_polling() is non-blocking and will stop the bot gracefully.
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
This is a very simple example on how one could implement a custom error handler
|
||||
"""
|
||||
import html
|
||||
import json
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from telegram import Update, ParseMode
|
||||
from telegram.ext import Updater, CallbackContext, CommandHandler
|
||||
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# The token you got from @botfather when you created the bot
|
||||
BOT_TOKEN = "TOKEN"
|
||||
|
||||
# This can be your own ID, or one for a developer group/channel.
|
||||
# You can use the /start command of this bot to see your chat id.
|
||||
DEVELOPER_CHAT_ID = 123456789
|
||||
|
||||
|
||||
def error_handler(update: Update, context: CallbackContext) -> None:
|
||||
"""Log the error and send a telegram message to notify the developer."""
|
||||
# Log the error before we do anything else, so we can see it even if something breaks.
|
||||
logger.error(msg="Exception while handling an update:", exc_info=context.error)
|
||||
|
||||
# traceback.format_exception returns the usual python message about an exception, but as a
|
||||
# list of strings rather than a single string, so we have to join them together.
|
||||
tb_list = traceback.format_exception(None, context.error, context.error.__traceback__)
|
||||
tb_string = ''.join(tb_list)
|
||||
|
||||
# Build the message with some markup and additional information about what happened.
|
||||
# You might need to add some logic to deal with messages longer than the 4096 character limit.
|
||||
message = (
|
||||
f'An exception was raised while handling an update\n'
|
||||
f'<pre>update = {html.escape(json.dumps(update.to_dict(), indent=2, ensure_ascii=False))}'
|
||||
'</pre>\n\n'
|
||||
f'<pre>context.chat_data = {html.escape(str(context.chat_data))}</pre>\n\n'
|
||||
f'<pre>context.user_data = {html.escape(str(context.user_data))}</pre>\n\n'
|
||||
f'<pre>{html.escape(tb_string)}</pre>'
|
||||
)
|
||||
|
||||
# Finally, send the message
|
||||
context.bot.send_message(chat_id=DEVELOPER_CHAT_ID, text=message, parse_mode=ParseMode.HTML)
|
||||
|
||||
|
||||
def bad_command(update: Update, context: CallbackContext) -> None:
|
||||
"""Raise an error to trigger the error handler."""
|
||||
context.bot.wrong_method_name()
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
update.effective_message.reply_html(
|
||||
'Use /bad_command to cause an error.\n'
|
||||
f'Your chat id is <code>{update.effective_chat.id}</code>.'
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater(BOT_TOKEN)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# Register the commands...
|
||||
dispatcher.add_handler(CommandHandler('start', start))
|
||||
dispatcher.add_handler(CommandHandler('bad_command', bad_command))
|
||||
|
||||
# ...and the error handler
|
||||
dispatcher.add_error_handler(error_handler)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
# Run the bot until you press Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT. This should be used most of the time, since
|
||||
# start_polling() is non-blocking and will stop the bot gracefully.
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+29
-40
@@ -1,12 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Simple Bot to reply to Telegram messages.
|
||||
|
||||
This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
This Bot uses the Updater class to handle the bot.
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
First, a few handler functions are defined. Then, those functions are passed to
|
||||
the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
@@ -16,80 +13,72 @@ Basic inline bot example. Applies different text transformations.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
import logging
|
||||
from uuid import uuid4
|
||||
|
||||
from telegram import InlineQueryResultArticle, ParseMode, InputTextMessageContent, Update
|
||||
from telegram.ext import Updater, InlineQueryHandler, CommandHandler, CallbackContext
|
||||
from telegram.utils.helpers import escape_markdown
|
||||
|
||||
from telegram import InlineQueryResultArticle, ParseMode, \
|
||||
InputTextMessageContent
|
||||
from telegram.ext import Updater, InlineQueryHandler, CommandHandler
|
||||
import logging
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Define a few command handlers. These usually take the two arguments bot and
|
||||
# update. Error handlers also receive the raised TelegramError object in error.
|
||||
def start(bot, update):
|
||||
# Define a few command handlers. These usually take the two arguments update and
|
||||
# context. Error handlers also receive the raised TelegramError object in error.
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
"""Send a message when the command /start is issued."""
|
||||
update.message.reply_text('Hi!')
|
||||
|
||||
|
||||
def help(bot, update):
|
||||
def help_command(update: Update, context: CallbackContext) -> None:
|
||||
"""Send a message when the command /help is issued."""
|
||||
update.message.reply_text('Help!')
|
||||
|
||||
|
||||
def inlinequery(bot, update):
|
||||
def inlinequery(update: Update, context: CallbackContext) -> None:
|
||||
"""Handle the inline query."""
|
||||
query = update.inline_query.query
|
||||
results = [
|
||||
InlineQueryResultArticle(
|
||||
id=uuid4(),
|
||||
title="Caps",
|
||||
input_message_content=InputTextMessageContent(
|
||||
query.upper())),
|
||||
id=uuid4(), title="Caps", input_message_content=InputTextMessageContent(query.upper())
|
||||
),
|
||||
InlineQueryResultArticle(
|
||||
id=uuid4(),
|
||||
title="Bold",
|
||||
input_message_content=InputTextMessageContent(
|
||||
"*{}*".format(escape_markdown(query)),
|
||||
parse_mode=ParseMode.MARKDOWN)),
|
||||
f"*{escape_markdown(query)}*", parse_mode=ParseMode.MARKDOWN
|
||||
),
|
||||
),
|
||||
InlineQueryResultArticle(
|
||||
id=uuid4(),
|
||||
title="Italic",
|
||||
input_message_content=InputTextMessageContent(
|
||||
"_{}_".format(escape_markdown(query)),
|
||||
parse_mode=ParseMode.MARKDOWN))]
|
||||
f"_{escape_markdown(query)}_", parse_mode=ParseMode.MARKDOWN
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
update.inline_query.answer(results)
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# on different commands - answer in Telegram
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
dp.add_handler(CommandHandler("help", help))
|
||||
dispatcher.add_handler(CommandHandler("start", start))
|
||||
dispatcher.add_handler(CommandHandler("help", help_command))
|
||||
|
||||
# on noncommand i.e message - echo the message on Telegram
|
||||
dp.add_handler(InlineQueryHandler(inlinequery))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
dispatcher.add_handler(InlineQueryHandler(inlinequery))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
+27
-24
@@ -1,54 +1,57 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Basic example for a bot that uses inline keyboards.
|
||||
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
Basic example for a bot that uses inline keyboards.
|
||||
"""
|
||||
import logging
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
|
||||
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext
|
||||
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def start(bot, update):
|
||||
keyboard = [[InlineKeyboardButton("Option 1", callback_data='1'),
|
||||
InlineKeyboardButton("Option 2", callback_data='2')],
|
||||
|
||||
[InlineKeyboardButton("Option 3", callback_data='3')]]
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("Option 1", callback_data='1'),
|
||||
InlineKeyboardButton("Option 2", callback_data='2'),
|
||||
],
|
||||
[InlineKeyboardButton("Option 3", callback_data='3')],
|
||||
]
|
||||
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
|
||||
update.message.reply_text('Please choose:', reply_markup=reply_markup)
|
||||
|
||||
|
||||
def button(bot, update):
|
||||
def button(update: Update, context: CallbackContext) -> None:
|
||||
query = update.callback_query
|
||||
|
||||
bot.edit_message_text(text="Selected option: {}".format(query.data),
|
||||
chat_id=query.message.chat_id,
|
||||
message_id=query.message.message_id)
|
||||
# CallbackQueries need to be answered, even if no notification to the user is needed
|
||||
# Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery
|
||||
query.answer()
|
||||
|
||||
query.edit_message_text(text=f"Selected option: {query.data}")
|
||||
|
||||
|
||||
def help(bot, update):
|
||||
def help_command(update: Update, context: CallbackContext) -> None:
|
||||
update.message.reply_text("Use /start to test this bot.")
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
updater.dispatcher.add_handler(CommandHandler('start', start))
|
||||
updater.dispatcher.add_handler(CallbackQueryHandler(button))
|
||||
updater.dispatcher.add_handler(CommandHandler('help', help))
|
||||
updater.dispatcher.add_error_handler(error)
|
||||
updater.dispatcher.add_handler(CommandHandler('help', help_command))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Simple inline keyboard bot with multiple CallbackQueryHandlers.
|
||||
|
||||
This Bot uses the Updater class to handle the bot.
|
||||
First, a few callback functions are defined as callback query handler. Then, those functions are
|
||||
passed to the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
Usage:
|
||||
Example of a bot that uses inline keyboard that has multiple CallbackQueryHandlers arranged in a
|
||||
ConversationHandler.
|
||||
Send /start to initiate the conversation.
|
||||
Press Ctrl-C on the command line to stop the bot.
|
||||
"""
|
||||
import logging
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
Updater,
|
||||
CommandHandler,
|
||||
CallbackQueryHandler,
|
||||
ConversationHandler,
|
||||
CallbackContext,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Stages
|
||||
FIRST, SECOND = range(2)
|
||||
# Callback data
|
||||
ONE, TWO, THREE, FOUR = range(4)
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
"""Send message on `/start`."""
|
||||
# Get user that sent /start and log his name
|
||||
user = update.message.from_user
|
||||
logger.info("User %s started the conversation.", user.first_name)
|
||||
# Build InlineKeyboard where each button has a displayed text
|
||||
# and a string as callback_data
|
||||
# The keyboard is a list of button rows, where each row is in turn
|
||||
# a list (hence `[[...]]`).
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("1", callback_data=str(ONE)),
|
||||
InlineKeyboardButton("2", callback_data=str(TWO)),
|
||||
]
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
# Send message with text and appended InlineKeyboard
|
||||
update.message.reply_text("Start handler, Choose a route", reply_markup=reply_markup)
|
||||
# Tell ConversationHandler that we're in state `FIRST` now
|
||||
return FIRST
|
||||
|
||||
|
||||
def start_over(update: Update, context: CallbackContext) -> None:
|
||||
"""Prompt same text & keyboard as `start` does but not as new message"""
|
||||
# Get CallbackQuery from Update
|
||||
query = update.callback_query
|
||||
# CallbackQueries need to be answered, even if no notification to the user is needed
|
||||
# Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery
|
||||
query.answer()
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("1", callback_data=str(ONE)),
|
||||
InlineKeyboardButton("2", callback_data=str(TWO)),
|
||||
]
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
# Instead of sending a new message, edit the message that
|
||||
# originated the CallbackQuery. This gives the feeling of an
|
||||
# interactive menu.
|
||||
query.edit_message_text(text="Start handler, Choose a route", reply_markup=reply_markup)
|
||||
return FIRST
|
||||
|
||||
|
||||
def one(update: Update, context: CallbackContext) -> None:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
query.answer()
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("3", callback_data=str(THREE)),
|
||||
InlineKeyboardButton("4", callback_data=str(FOUR)),
|
||||
]
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
query.edit_message_text(
|
||||
text="First CallbackQueryHandler, Choose a route", reply_markup=reply_markup
|
||||
)
|
||||
return FIRST
|
||||
|
||||
|
||||
def two(update: Update, context: CallbackContext) -> None:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
query.answer()
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("1", callback_data=str(ONE)),
|
||||
InlineKeyboardButton("3", callback_data=str(THREE)),
|
||||
]
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
query.edit_message_text(
|
||||
text="Second CallbackQueryHandler, Choose a route", reply_markup=reply_markup
|
||||
)
|
||||
return FIRST
|
||||
|
||||
|
||||
def three(update: Update, context: CallbackContext) -> None:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
query.answer()
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("Yes, let's do it again!", callback_data=str(ONE)),
|
||||
InlineKeyboardButton("Nah, I've had enough ...", callback_data=str(TWO)),
|
||||
]
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
query.edit_message_text(
|
||||
text="Third CallbackQueryHandler. Do want to start over?", reply_markup=reply_markup
|
||||
)
|
||||
# Transfer to conversation state `SECOND`
|
||||
return SECOND
|
||||
|
||||
|
||||
def four(update: Update, context: CallbackContext) -> None:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
query.answer()
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("2", callback_data=str(TWO)),
|
||||
InlineKeyboardButton("4", callback_data=str(FOUR)),
|
||||
]
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
query.edit_message_text(
|
||||
text="Fourth CallbackQueryHandler, Choose a route", reply_markup=reply_markup
|
||||
)
|
||||
return FIRST
|
||||
|
||||
|
||||
def end(update: Update, context: CallbackContext) -> None:
|
||||
"""Returns `ConversationHandler.END`, which tells the
|
||||
ConversationHandler that the conversation is over"""
|
||||
query = update.callback_query
|
||||
query.answer()
|
||||
query.edit_message_text(text="See you next time!")
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# Setup conversation handler with the states FIRST and SECOND
|
||||
# Use the pattern parameter to pass CallbackQueries with specific
|
||||
# data pattern to the corresponding handlers.
|
||||
# ^ means "start of line/string"
|
||||
# $ means "end of line/string"
|
||||
# So ^ABC$ will only allow 'ABC'
|
||||
conv_handler = ConversationHandler(
|
||||
entry_points=[CommandHandler('start', start)],
|
||||
states={
|
||||
FIRST: [
|
||||
CallbackQueryHandler(one, pattern='^' + str(ONE) + '$'),
|
||||
CallbackQueryHandler(two, pattern='^' + str(TWO) + '$'),
|
||||
CallbackQueryHandler(three, pattern='^' + str(THREE) + '$'),
|
||||
CallbackQueryHandler(four, pattern='^' + str(FOUR) + '$'),
|
||||
],
|
||||
SECOND: [
|
||||
CallbackQueryHandler(start_over, pattern='^' + str(ONE) + '$'),
|
||||
CallbackQueryHandler(end, pattern='^' + str(TWO) + '$'),
|
||||
],
|
||||
},
|
||||
fallbacks=[CommandHandler('start', start)],
|
||||
)
|
||||
|
||||
# Add ConversationHandler to dispatcher that will be used for handling
|
||||
# updates
|
||||
dispatcher.add_handler(conv_handler)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
# Run the bot until you press Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT. This should be used most of the time, since
|
||||
# start_polling() is non-blocking and will stop the bot gracefully.
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 492 KiB |
@@ -0,0 +1,391 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
First, a few callback functions are defined. Then, those functions are passed to
|
||||
the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
|
||||
Usage:
|
||||
Example of a bot-user conversation using nested ConversationHandlers.
|
||||
Send /start to initiate the conversation.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import InlineKeyboardMarkup, InlineKeyboardButton, Update
|
||||
from telegram.ext import (
|
||||
Updater,
|
||||
CommandHandler,
|
||||
MessageHandler,
|
||||
Filters,
|
||||
ConversationHandler,
|
||||
CallbackQueryHandler,
|
||||
CallbackContext,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# State definitions for top level conversation
|
||||
SELECTING_ACTION, ADDING_MEMBER, ADDING_SELF, DESCRIBING_SELF = map(chr, range(4))
|
||||
# State definitions for second level conversation
|
||||
SELECTING_LEVEL, SELECTING_GENDER = map(chr, range(4, 6))
|
||||
# State definitions for descriptions conversation
|
||||
SELECTING_FEATURE, TYPING = map(chr, range(6, 8))
|
||||
# Meta states
|
||||
STOPPING, SHOWING = map(chr, range(8, 10))
|
||||
# Shortcut for ConversationHandler.END
|
||||
END = ConversationHandler.END
|
||||
|
||||
# Different constants for this example
|
||||
(
|
||||
PARENTS,
|
||||
CHILDREN,
|
||||
SELF,
|
||||
GENDER,
|
||||
MALE,
|
||||
FEMALE,
|
||||
AGE,
|
||||
NAME,
|
||||
START_OVER,
|
||||
FEATURES,
|
||||
CURRENT_FEATURE,
|
||||
CURRENT_LEVEL,
|
||||
) = map(chr, range(10, 22))
|
||||
|
||||
|
||||
# Helper
|
||||
def _name_switcher(level):
|
||||
if level == PARENTS:
|
||||
return 'Father', 'Mother'
|
||||
return 'Brother', 'Sister'
|
||||
|
||||
|
||||
# Top level conversation callbacks
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
"""Select an action: Adding parent/child or show data."""
|
||||
text = (
|
||||
'You may add a familiy member, yourself show the gathered data or end the '
|
||||
'conversation. To abort, simply type /stop.'
|
||||
)
|
||||
buttons = [
|
||||
[
|
||||
InlineKeyboardButton(text='Add family member', callback_data=str(ADDING_MEMBER)),
|
||||
InlineKeyboardButton(text='Add yourself', callback_data=str(ADDING_SELF)),
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(text='Show data', callback_data=str(SHOWING)),
|
||||
InlineKeyboardButton(text='Done', callback_data=str(END)),
|
||||
],
|
||||
]
|
||||
keyboard = InlineKeyboardMarkup(buttons)
|
||||
|
||||
# If we're starting over we don't need do send a new message
|
||||
if context.user_data.get(START_OVER):
|
||||
update.callback_query.answer()
|
||||
update.callback_query.edit_message_text(text=text, reply_markup=keyboard)
|
||||
else:
|
||||
update.message.reply_text(
|
||||
'Hi, I\'m FamiliyBot and here to help you gather information' 'about your family.'
|
||||
)
|
||||
update.message.reply_text(text=text, reply_markup=keyboard)
|
||||
|
||||
context.user_data[START_OVER] = False
|
||||
return SELECTING_ACTION
|
||||
|
||||
|
||||
def adding_self(update: Update, context: CallbackContext) -> None:
|
||||
"""Add information about youself."""
|
||||
context.user_data[CURRENT_LEVEL] = SELF
|
||||
text = 'Okay, please tell me about yourself.'
|
||||
button = InlineKeyboardButton(text='Add info', callback_data=str(MALE))
|
||||
keyboard = InlineKeyboardMarkup.from_button(button)
|
||||
|
||||
update.callback_query.answer()
|
||||
update.callback_query.edit_message_text(text=text, reply_markup=keyboard)
|
||||
|
||||
return DESCRIBING_SELF
|
||||
|
||||
|
||||
def show_data(update: Update, context: CallbackContext) -> None:
|
||||
"""Pretty print gathered data."""
|
||||
|
||||
def prettyprint(user_data, level):
|
||||
people = user_data.get(level)
|
||||
if not people:
|
||||
return '\nNo information yet.'
|
||||
|
||||
text = ''
|
||||
if level == SELF:
|
||||
for person in user_data[level]:
|
||||
text += f"\nName: {person.get(NAME, '-')}, Age: {person.get(AGE, '-')}"
|
||||
else:
|
||||
male, female = _name_switcher(level)
|
||||
|
||||
for person in user_data[level]:
|
||||
gender = female if person[GENDER] == FEMALE else male
|
||||
text += f"\n{gender}: Name: {person.get(NAME, '-')}, Age: {person.get(AGE, '-')}"
|
||||
return text
|
||||
|
||||
user_data = context.user_data
|
||||
text = 'Yourself:' + prettyprint(user_data, SELF)
|
||||
text += '\n\nParents:' + prettyprint(user_data, PARENTS)
|
||||
text += '\n\nChildren:' + prettyprint(user_data, CHILDREN)
|
||||
|
||||
buttons = [[InlineKeyboardButton(text='Back', callback_data=str(END))]]
|
||||
keyboard = InlineKeyboardMarkup(buttons)
|
||||
|
||||
update.callback_query.answer()
|
||||
update.callback_query.edit_message_text(text=text, reply_markup=keyboard)
|
||||
user_data[START_OVER] = True
|
||||
|
||||
return SHOWING
|
||||
|
||||
|
||||
def stop(update: Update, context: CallbackContext) -> None:
|
||||
"""End Conversation by command."""
|
||||
update.message.reply_text('Okay, bye.')
|
||||
|
||||
return END
|
||||
|
||||
|
||||
def end(update: Update, context: CallbackContext) -> None:
|
||||
"""End conversation from InlineKeyboardButton."""
|
||||
update.callback_query.answer()
|
||||
|
||||
text = 'See you around!'
|
||||
update.callback_query.edit_message_text(text=text)
|
||||
|
||||
return END
|
||||
|
||||
|
||||
# Second level conversation callbacks
|
||||
def select_level(update: Update, context: CallbackContext) -> None:
|
||||
"""Choose to add a parent or a child."""
|
||||
text = 'You may add a parent or a child. Also you can show the gathered data or go back.'
|
||||
buttons = [
|
||||
[
|
||||
InlineKeyboardButton(text='Add parent', callback_data=str(PARENTS)),
|
||||
InlineKeyboardButton(text='Add child', callback_data=str(CHILDREN)),
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(text='Show data', callback_data=str(SHOWING)),
|
||||
InlineKeyboardButton(text='Back', callback_data=str(END)),
|
||||
],
|
||||
]
|
||||
keyboard = InlineKeyboardMarkup(buttons)
|
||||
|
||||
update.callback_query.answer()
|
||||
update.callback_query.edit_message_text(text=text, reply_markup=keyboard)
|
||||
|
||||
return SELECTING_LEVEL
|
||||
|
||||
|
||||
def select_gender(update: Update, context: CallbackContext) -> None:
|
||||
"""Choose to add mother or father."""
|
||||
level = update.callback_query.data
|
||||
context.user_data[CURRENT_LEVEL] = level
|
||||
|
||||
text = 'Please choose, whom to add.'
|
||||
|
||||
male, female = _name_switcher(level)
|
||||
|
||||
buttons = [
|
||||
[
|
||||
InlineKeyboardButton(text='Add ' + male, callback_data=str(MALE)),
|
||||
InlineKeyboardButton(text='Add ' + female, callback_data=str(FEMALE)),
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(text='Show data', callback_data=str(SHOWING)),
|
||||
InlineKeyboardButton(text='Back', callback_data=str(END)),
|
||||
],
|
||||
]
|
||||
keyboard = InlineKeyboardMarkup(buttons)
|
||||
|
||||
update.callback_query.answer()
|
||||
update.callback_query.edit_message_text(text=text, reply_markup=keyboard)
|
||||
|
||||
return SELECTING_GENDER
|
||||
|
||||
|
||||
def end_second_level(update: Update, context: CallbackContext) -> None:
|
||||
"""Return to top level conversation."""
|
||||
context.user_data[START_OVER] = True
|
||||
start(update, context)
|
||||
|
||||
return END
|
||||
|
||||
|
||||
# Third level callbacks
|
||||
def select_feature(update: Update, context: CallbackContext) -> None:
|
||||
"""Select a feature to update for the person."""
|
||||
buttons = [
|
||||
[
|
||||
InlineKeyboardButton(text='Name', callback_data=str(NAME)),
|
||||
InlineKeyboardButton(text='Age', callback_data=str(AGE)),
|
||||
InlineKeyboardButton(text='Done', callback_data=str(END)),
|
||||
]
|
||||
]
|
||||
keyboard = InlineKeyboardMarkup(buttons)
|
||||
|
||||
# If we collect features for a new person, clear the cache and save the gender
|
||||
if not context.user_data.get(START_OVER):
|
||||
context.user_data[FEATURES] = {GENDER: update.callback_query.data}
|
||||
text = 'Please select a feature to update.'
|
||||
|
||||
update.callback_query.answer()
|
||||
update.callback_query.edit_message_text(text=text, reply_markup=keyboard)
|
||||
# But after we do that, we need to send a new message
|
||||
else:
|
||||
text = 'Got it! Please select a feature to update.'
|
||||
update.message.reply_text(text=text, reply_markup=keyboard)
|
||||
|
||||
context.user_data[START_OVER] = False
|
||||
return SELECTING_FEATURE
|
||||
|
||||
|
||||
def ask_for_input(update: Update, context: CallbackContext) -> None:
|
||||
"""Prompt user to input data for selected feature."""
|
||||
context.user_data[CURRENT_FEATURE] = update.callback_query.data
|
||||
text = 'Okay, tell me.'
|
||||
|
||||
update.callback_query.answer()
|
||||
update.callback_query.edit_message_text(text=text)
|
||||
|
||||
return TYPING
|
||||
|
||||
|
||||
def save_input(update: Update, context: CallbackContext) -> None:
|
||||
"""Save input for feature and return to feature selection."""
|
||||
user_data = context.user_data
|
||||
user_data[FEATURES][user_data[CURRENT_FEATURE]] = update.message.text
|
||||
|
||||
user_data[START_OVER] = True
|
||||
|
||||
return select_feature(update, context)
|
||||
|
||||
|
||||
def end_describing(update: Update, context: CallbackContext) -> None:
|
||||
"""End gathering of features and return to parent conversation."""
|
||||
user_data = context.user_data
|
||||
level = user_data[CURRENT_LEVEL]
|
||||
if not user_data.get(level):
|
||||
user_data[level] = []
|
||||
user_data[level].append(user_data[FEATURES])
|
||||
|
||||
# Print upper level menu
|
||||
if level == SELF:
|
||||
user_data[START_OVER] = True
|
||||
start(update, context)
|
||||
else:
|
||||
select_level(update, context)
|
||||
|
||||
return END
|
||||
|
||||
|
||||
def stop_nested(update: Update, context: CallbackContext) -> None:
|
||||
"""Completely end conversation from within nested conversation."""
|
||||
update.message.reply_text('Okay, bye.')
|
||||
|
||||
return STOPPING
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# Set up third level ConversationHandler (collecting features)
|
||||
description_conv = ConversationHandler(
|
||||
entry_points=[
|
||||
CallbackQueryHandler(
|
||||
select_feature, pattern='^' + str(MALE) + '$|^' + str(FEMALE) + '$'
|
||||
)
|
||||
],
|
||||
states={
|
||||
SELECTING_FEATURE: [
|
||||
CallbackQueryHandler(ask_for_input, pattern='^(?!' + str(END) + ').*$')
|
||||
],
|
||||
TYPING: [MessageHandler(Filters.text & ~Filters.command, save_input)],
|
||||
},
|
||||
fallbacks=[
|
||||
CallbackQueryHandler(end_describing, pattern='^' + str(END) + '$'),
|
||||
CommandHandler('stop', stop_nested),
|
||||
],
|
||||
map_to_parent={
|
||||
# Return to second level menu
|
||||
END: SELECTING_LEVEL,
|
||||
# End conversation alltogether
|
||||
STOPPING: STOPPING,
|
||||
},
|
||||
)
|
||||
|
||||
# Set up second level ConversationHandler (adding a person)
|
||||
add_member_conv = ConversationHandler(
|
||||
entry_points=[CallbackQueryHandler(select_level, pattern='^' + str(ADDING_MEMBER) + '$')],
|
||||
states={
|
||||
SELECTING_LEVEL: [
|
||||
CallbackQueryHandler(select_gender, pattern=f'^{PARENTS}$|^{CHILDREN}$')
|
||||
],
|
||||
SELECTING_GENDER: [description_conv],
|
||||
},
|
||||
fallbacks=[
|
||||
CallbackQueryHandler(show_data, pattern='^' + str(SHOWING) + '$'),
|
||||
CallbackQueryHandler(end_second_level, pattern='^' + str(END) + '$'),
|
||||
CommandHandler('stop', stop_nested),
|
||||
],
|
||||
map_to_parent={
|
||||
# After showing data return to top level menu
|
||||
SHOWING: SHOWING,
|
||||
# Return to top level menu
|
||||
END: SELECTING_ACTION,
|
||||
# End conversation alltogether
|
||||
STOPPING: END,
|
||||
},
|
||||
)
|
||||
|
||||
# Set up top level ConversationHandler (selecting action)
|
||||
# Because the states of the third level conversation map to the ones of the econd level
|
||||
# conversation, we need to make sure the top level conversation can also handle them
|
||||
selection_handlers = [
|
||||
add_member_conv,
|
||||
CallbackQueryHandler(show_data, pattern='^' + str(SHOWING) + '$'),
|
||||
CallbackQueryHandler(adding_self, pattern='^' + str(ADDING_SELF) + '$'),
|
||||
CallbackQueryHandler(end, pattern='^' + str(END) + '$'),
|
||||
]
|
||||
conv_handler = ConversationHandler(
|
||||
entry_points=[CommandHandler('start', start)],
|
||||
states={
|
||||
SHOWING: [CallbackQueryHandler(start, pattern='^' + str(END) + '$')],
|
||||
SELECTING_ACTION: selection_handlers,
|
||||
SELECTING_LEVEL: selection_handlers,
|
||||
DESCRIBING_SELF: [description_conv],
|
||||
STOPPING: [CommandHandler('start', start)],
|
||||
},
|
||||
fallbacks=[CommandHandler('stop', stop)],
|
||||
)
|
||||
|
||||
dispatcher.add_handler(conv_handler)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
# Run the bot until you press Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT. This should be used most of the time, since
|
||||
# start_polling() is non-blocking and will stop the bot gracefully.
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+49
-28
@@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Simple Bot to print/download all incoming passport data
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
Simple Bot to print/download all incoming passport data
|
||||
|
||||
See https://telegram.org/blog/passport for info about what telegram passport is.
|
||||
|
||||
See https://git.io/fAvYd for how to use Telegram Passport properly with python-telegram-bot.
|
||||
@@ -11,22 +13,24 @@ See https://git.io/fAvYd for how to use Telegram Passport properly with python-t
|
||||
"""
|
||||
import logging
|
||||
|
||||
from telegram.ext import Updater, MessageHandler, Filters
|
||||
from telegram import Update
|
||||
from telegram.ext import Updater, MessageHandler, Filters, CallbackContext
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.DEBUG)
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.DEBUG
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def msg(bot, update):
|
||||
def msg(update: Update, context: CallbackContext) -> None:
|
||||
# If we received any passport data
|
||||
passport_data = update.message.passport_data
|
||||
if passport_data:
|
||||
# If our payload doesn't match what we think, this Update did not originate from us
|
||||
# Ideally you would randomize the payload on the server
|
||||
if passport_data.decrypted_credentials.payload != 'thisisatest':
|
||||
# If our nonce doesn't match what we think, this Update did not originate from us
|
||||
# Ideally you would randomize the nonce on the server
|
||||
if passport_data.decrypted_credentials.nonce != 'thisisatest':
|
||||
return
|
||||
|
||||
# Print the decrypted credential data
|
||||
@@ -38,18 +42,28 @@ def msg(bot, update):
|
||||
print('Phone: ', data.phone_number)
|
||||
elif data.type == 'email':
|
||||
print('Email: ', data.email)
|
||||
if data.type in ('personal_details', 'passport', 'driver_license', 'identity_card',
|
||||
'identity_passport', 'address'):
|
||||
if data.type in (
|
||||
'personal_details',
|
||||
'passport',
|
||||
'driver_license',
|
||||
'identity_card',
|
||||
'internal_passport',
|
||||
'address',
|
||||
):
|
||||
print(data.type, data.data)
|
||||
if data.type in ('utility_bill', 'bank_statement', 'rental_agreement',
|
||||
'passport_registration', 'temporary_registration'):
|
||||
if data.type in (
|
||||
'utility_bill',
|
||||
'bank_statement',
|
||||
'rental_agreement',
|
||||
'passport_registration',
|
||||
'temporary_registration',
|
||||
):
|
||||
print(data.type, len(data.files), 'files')
|
||||
for file in data.files:
|
||||
actual_file = file.get_file()
|
||||
print(actual_file)
|
||||
actual_file.download()
|
||||
if data.type in ('passport', 'driver_license', 'identity_card',
|
||||
'internal_passport'):
|
||||
if data.type in ('passport', 'driver_license', 'identity_card', 'internal_passport'):
|
||||
if data.front_side:
|
||||
file = data.front_side.get_file()
|
||||
print(data.type, file)
|
||||
@@ -59,17 +73,27 @@ def msg(bot, update):
|
||||
file = data.reverse_side.get_file()
|
||||
print(data.type, file)
|
||||
file.download()
|
||||
if data.type in ('passport', 'driver_license', 'identity_card',
|
||||
'internal_passport'):
|
||||
if data.type in ('passport', 'driver_license', 'identity_card', 'internal_passport'):
|
||||
if data.selfie:
|
||||
file = data.selfie.get_file()
|
||||
print(data.type, file)
|
||||
file.download()
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
if data.type in (
|
||||
'passport',
|
||||
'driver_license',
|
||||
'identity_card',
|
||||
'internal_passport',
|
||||
'utility_bill',
|
||||
'bank_statement',
|
||||
'rental_agreement',
|
||||
'passport_registration',
|
||||
'temporary_registration',
|
||||
):
|
||||
print(data.type, len(data.translation), 'translation')
|
||||
for file in data.translation:
|
||||
actual_file = file.get_file()
|
||||
print(actual_file)
|
||||
actual_file.download()
|
||||
|
||||
|
||||
def main():
|
||||
@@ -78,13 +102,10 @@ def main():
|
||||
updater = Updater("TOKEN", private_key=open('private.key', 'rb').read())
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# On messages that include passport data call msg
|
||||
dp.add_handler(MessageHandler(Filters.passport_data, msg))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
dispatcher.add_handler(MessageHandler(Filters.passport_data, msg))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
+67
-56
@@ -1,35 +1,40 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
"""Basic example for a bot that can receive payment from user.
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
This program is dedicated to the public domain under the CC0 license.
|
||||
"""
|
||||
Basic example for a bot that can receive payment from user.
|
||||
"""
|
||||
|
||||
from telegram import (LabeledPrice, ShippingOption)
|
||||
from telegram.ext import (Updater, CommandHandler, MessageHandler,
|
||||
Filters, PreCheckoutQueryHandler, ShippingQueryHandler)
|
||||
import logging
|
||||
|
||||
from telegram import LabeledPrice, ShippingOption, Update
|
||||
from telegram.ext import (
|
||||
Updater,
|
||||
CommandHandler,
|
||||
MessageHandler,
|
||||
Filters,
|
||||
PreCheckoutQueryHandler,
|
||||
ShippingQueryHandler,
|
||||
CallbackContext,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
|
||||
|
||||
def start_callback(bot, update):
|
||||
def start_callback(update: Update, context: CallbackContext) -> None:
|
||||
msg = "Use /shipping to get an invoice for shipping-payment, "
|
||||
msg += "or /noshipping for an invoice without shipping."
|
||||
update.message.reply_text(msg)
|
||||
|
||||
|
||||
def start_with_shipping_callback(bot, update):
|
||||
def start_with_shipping_callback(update: Update, context: CallbackContext) -> None:
|
||||
chat_id = update.message.chat_id
|
||||
title = "Payment Example"
|
||||
description = "Payment Example using python-telegram-bot"
|
||||
@@ -41,19 +46,30 @@ def start_with_shipping_callback(bot, update):
|
||||
currency = "USD"
|
||||
# price in dollars
|
||||
price = 1
|
||||
# price * 100 so as to include 2 d.p.
|
||||
# price * 100 so as to include 2 decimal points
|
||||
# check https://core.telegram.org/bots/payments#supported-currencies for more details
|
||||
prices = [LabeledPrice("Test", price * 100)]
|
||||
|
||||
# optionally pass need_name=True, need_phone_number=True,
|
||||
# need_email=True, need_shipping_address=True, is_flexible=True
|
||||
bot.sendInvoice(chat_id, title, description, payload,
|
||||
provider_token, start_parameter, currency, prices,
|
||||
need_name=True, need_phone_number=True,
|
||||
need_email=True, need_shipping_address=True, is_flexible=True)
|
||||
context.bot.send_invoice(
|
||||
chat_id,
|
||||
title,
|
||||
description,
|
||||
payload,
|
||||
provider_token,
|
||||
start_parameter,
|
||||
currency,
|
||||
prices,
|
||||
need_name=True,
|
||||
need_phone_number=True,
|
||||
need_email=True,
|
||||
need_shipping_address=True,
|
||||
is_flexible=True,
|
||||
)
|
||||
|
||||
|
||||
def start_without_shipping_callback(bot, update):
|
||||
def start_without_shipping_callback(update: Update, context: CallbackContext) -> None:
|
||||
chat_id = update.message.chat_id
|
||||
title = "Payment Example"
|
||||
description = "Payment Example using python-telegram-bot"
|
||||
@@ -65,77 +81,72 @@ def start_without_shipping_callback(bot, update):
|
||||
currency = "USD"
|
||||
# price in dollars
|
||||
price = 1
|
||||
# price * 100 so as to include 2 d.p.
|
||||
# price * 100 so as to include 2 decimal points
|
||||
prices = [LabeledPrice("Test", price * 100)]
|
||||
|
||||
# optionally pass need_name=True, need_phone_number=True,
|
||||
# need_email=True, need_shipping_address=True, is_flexible=True
|
||||
bot.sendInvoice(chat_id, title, description, payload,
|
||||
provider_token, start_parameter, currency, prices)
|
||||
context.bot.send_invoice(
|
||||
chat_id, title, description, payload, provider_token, start_parameter, currency, prices
|
||||
)
|
||||
|
||||
|
||||
def shipping_callback(bot, update):
|
||||
def shipping_callback(update: Update, context: CallbackContext) -> None:
|
||||
query = update.shipping_query
|
||||
# check the payload, is this from your bot?
|
||||
if query.invoice_payload != 'Custom-Payload':
|
||||
# answer False pre_checkout_query
|
||||
bot.answer_shipping_query(shipping_query_id=query.id, ok=False,
|
||||
error_message="Something went wrong...")
|
||||
query.answer(ok=False, error_message="Something went wrong...")
|
||||
return
|
||||
else:
|
||||
options = list()
|
||||
# a single LabeledPrice
|
||||
options.append(ShippingOption('1', 'Shipping Option A', [LabeledPrice('A', 100)]))
|
||||
# an array of LabeledPrice objects
|
||||
price_list = [LabeledPrice('B1', 150), LabeledPrice('B2', 200)]
|
||||
options.append(ShippingOption('2', 'Shipping Option B', price_list))
|
||||
bot.answer_shipping_query(shipping_query_id=query.id, ok=True,
|
||||
shipping_options=options)
|
||||
|
||||
options = list()
|
||||
# a single LabeledPrice
|
||||
options.append(ShippingOption('1', 'Shipping Option A', [LabeledPrice('A', 100)]))
|
||||
# an array of LabeledPrice objects
|
||||
price_list = [LabeledPrice('B1', 150), LabeledPrice('B2', 200)]
|
||||
options.append(ShippingOption('2', 'Shipping Option B', price_list))
|
||||
query.answer(ok=True, shipping_options=options)
|
||||
|
||||
|
||||
# after (optional) shipping, it's the pre-checkout
|
||||
def precheckout_callback(bot, update):
|
||||
def precheckout_callback(update: Update, context: CallbackContext) -> None:
|
||||
query = update.pre_checkout_query
|
||||
# check the payload, is this from your bot?
|
||||
if query.invoice_payload != 'Custom-Payload':
|
||||
# answer False pre_checkout_query
|
||||
bot.answer_pre_checkout_query(pre_checkout_query_id=query.id, ok=False,
|
||||
error_message="Something went wrong...")
|
||||
query.answer(ok=False, error_message="Something went wrong...")
|
||||
else:
|
||||
bot.answer_pre_checkout_query(pre_checkout_query_id=query.id, ok=True)
|
||||
query.answer(ok=True)
|
||||
|
||||
|
||||
# finally, after contacting to the payment provider...
|
||||
def successful_payment_callback(bot, update):
|
||||
# do something after successful receive of payment?
|
||||
# finally, after contacting the payment provider...
|
||||
def successful_payment_callback(update: Update, context: CallbackContext) -> None:
|
||||
# do something after successfully receiving payment?
|
||||
update.message.reply_text("Thank you for your payment!")
|
||||
|
||||
|
||||
def main():
|
||||
# Create the EventHandler and pass it your bot's token.
|
||||
updater = Updater(token="BOT_TOKEN")
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# simple start function
|
||||
dp.add_handler(CommandHandler("start", start_callback))
|
||||
dispatcher.add_handler(CommandHandler("start", start_callback))
|
||||
|
||||
# Add command handler to start the payment invoice
|
||||
dp.add_handler(CommandHandler("shipping", start_with_shipping_callback))
|
||||
dp.add_handler(CommandHandler("noshipping", start_without_shipping_callback))
|
||||
dispatcher.add_handler(CommandHandler("shipping", start_with_shipping_callback))
|
||||
dispatcher.add_handler(CommandHandler("noshipping", start_without_shipping_callback))
|
||||
|
||||
# Optional handler if your product requires shipping
|
||||
dp.add_handler(ShippingQueryHandler(shipping_callback))
|
||||
dispatcher.add_handler(ShippingQueryHandler(shipping_callback))
|
||||
|
||||
# Pre-checkout handler to final check
|
||||
dp.add_handler(PreCheckoutQueryHandler(precheckout_callback))
|
||||
dispatcher.add_handler(PreCheckoutQueryHandler(precheckout_callback))
|
||||
|
||||
# Success! Notify your user!
|
||||
dp.add_handler(MessageHandler(Filters.successful_payment, successful_payment_callback))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
dispatcher.add_handler(MessageHandler(Filters.successful_payment, successful_payment_callback))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116, C0103
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
First, a few callback functions are defined. Then, those functions are passed to
|
||||
the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
|
||||
Usage:
|
||||
Example of a bot-user conversation using ConversationHandler.
|
||||
Send /start to initiate the conversation.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import ReplyKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
Updater,
|
||||
CommandHandler,
|
||||
MessageHandler,
|
||||
Filters,
|
||||
ConversationHandler,
|
||||
PicklePersistence,
|
||||
CallbackContext,
|
||||
)
|
||||
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CHOOSING, TYPING_REPLY, TYPING_CHOICE = range(3)
|
||||
|
||||
reply_keyboard = [
|
||||
['Age', 'Favourite colour'],
|
||||
['Number of siblings', 'Something else...'],
|
||||
['Done'],
|
||||
]
|
||||
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
|
||||
|
||||
|
||||
def facts_to_str(user_data):
|
||||
facts = list()
|
||||
|
||||
for key, value in user_data.items():
|
||||
facts.append(f'{key} - {value}')
|
||||
|
||||
return "\n".join(facts).join(['\n', '\n'])
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
reply_text = "Hi! My name is Doctor Botter."
|
||||
if context.user_data:
|
||||
reply_text += (
|
||||
f" You already told me your {', '.join(context.user_data.keys())}. Why don't you "
|
||||
f"tell me something more about yourself? Or change anything I already know."
|
||||
)
|
||||
else:
|
||||
reply_text += (
|
||||
" I will hold a more complex conversation with you. Why don't you tell me "
|
||||
"something about yourself?"
|
||||
)
|
||||
update.message.reply_text(reply_text, reply_markup=markup)
|
||||
|
||||
return CHOOSING
|
||||
|
||||
|
||||
def regular_choice(update: Update, context: CallbackContext) -> None:
|
||||
text = update.message.text.lower()
|
||||
context.user_data['choice'] = text
|
||||
if context.user_data.get(text):
|
||||
reply_text = (
|
||||
f'Your {text}, I already know the following about that: {context.user_data[text]}'
|
||||
)
|
||||
else:
|
||||
reply_text = f'Your {text}? Yes, I would love to hear about that!'
|
||||
update.message.reply_text(reply_text)
|
||||
|
||||
return TYPING_REPLY
|
||||
|
||||
|
||||
def custom_choice(update: Update, context: CallbackContext) -> None:
|
||||
update.message.reply_text(
|
||||
'Alright, please send me the category first, ' 'for example "Most impressive skill"'
|
||||
)
|
||||
|
||||
return TYPING_CHOICE
|
||||
|
||||
|
||||
def received_information(update: Update, context: CallbackContext) -> None:
|
||||
text = update.message.text
|
||||
category = context.user_data['choice']
|
||||
context.user_data[category] = text.lower()
|
||||
del context.user_data['choice']
|
||||
|
||||
update.message.reply_text(
|
||||
"Neat! Just so you know, this is what you already told me:"
|
||||
f"{facts_to_str(context.user_data)}"
|
||||
"You can tell me more, or change your opinion on "
|
||||
"something.",
|
||||
reply_markup=markup,
|
||||
)
|
||||
|
||||
return CHOOSING
|
||||
|
||||
|
||||
def show_data(update: Update, context: CallbackContext) -> None:
|
||||
update.message.reply_text(
|
||||
f"This is what you already told me: {facts_to_str(context.user_data)}"
|
||||
)
|
||||
|
||||
|
||||
def done(update: Update, context: CallbackContext) -> None:
|
||||
if 'choice' in context.user_data:
|
||||
del context.user_data['choice']
|
||||
|
||||
update.message.reply_text(
|
||||
"I learned these facts about you:" f"{facts_to_str(context.user_data)}" "Until next time!"
|
||||
)
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
pp = PicklePersistence(filename='conversationbot')
|
||||
updater = Updater("TOKEN", persistence=pp)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
||||
# Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY
|
||||
conv_handler = ConversationHandler(
|
||||
entry_points=[CommandHandler('start', start)],
|
||||
states={
|
||||
CHOOSING: [
|
||||
MessageHandler(
|
||||
Filters.regex('^(Age|Favourite colour|Number of siblings)$'), regular_choice
|
||||
),
|
||||
MessageHandler(Filters.regex('^Something else...$'), custom_choice),
|
||||
],
|
||||
TYPING_CHOICE: [
|
||||
MessageHandler(
|
||||
Filters.text & ~(Filters.command | Filters.regex('^Done$')), regular_choice
|
||||
)
|
||||
],
|
||||
TYPING_REPLY: [
|
||||
MessageHandler(
|
||||
Filters.text & ~(Filters.command | Filters.regex('^Done$')),
|
||||
received_information,
|
||||
)
|
||||
],
|
||||
},
|
||||
fallbacks=[MessageHandler(Filters.regex('^Done$'), done)],
|
||||
name="my_conversation",
|
||||
persistent=True,
|
||||
)
|
||||
|
||||
dp.add_handler(conv_handler)
|
||||
|
||||
show_data_handler = CommandHandler('show_data', show_data)
|
||||
dp.add_handler(show_data_handler)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
# Run the bot until you press Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT. This should be used most of the time, since
|
||||
# start_polling() is non-blocking and will stop the bot gracefully.
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
Basic example for a bot that works with polls. Only 3 people are allowed to interact with each
|
||||
poll/quiz the bot generates. The preview command generates a closed poll/quiz, excatly like the
|
||||
one the user sends the bot
|
||||
"""
|
||||
import logging
|
||||
|
||||
from telegram import (
|
||||
Poll,
|
||||
ParseMode,
|
||||
KeyboardButton,
|
||||
KeyboardButtonPollType,
|
||||
ReplyKeyboardMarkup,
|
||||
ReplyKeyboardRemove,
|
||||
Update,
|
||||
)
|
||||
from telegram.ext import (
|
||||
Updater,
|
||||
CommandHandler,
|
||||
PollAnswerHandler,
|
||||
PollHandler,
|
||||
MessageHandler,
|
||||
Filters,
|
||||
CallbackContext,
|
||||
)
|
||||
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
"""Inform user about what this bot can do"""
|
||||
update.message.reply_text(
|
||||
'Please select /poll to get a Poll, /quiz to get a Quiz or /preview'
|
||||
' to generate a preview for your poll'
|
||||
)
|
||||
|
||||
|
||||
def poll(update: Update, context: CallbackContext) -> None:
|
||||
"""Sends a predefined poll"""
|
||||
questions = ["Good", "Really good", "Fantastic", "Great"]
|
||||
message = context.bot.send_poll(
|
||||
update.effective_chat.id,
|
||||
"How are you?",
|
||||
questions,
|
||||
is_anonymous=False,
|
||||
allows_multiple_answers=True,
|
||||
)
|
||||
# Save some info about the poll the bot_data for later use in receive_poll_answer
|
||||
payload = {
|
||||
message.poll.id: {
|
||||
"questions": questions,
|
||||
"message_id": message.message_id,
|
||||
"chat_id": update.effective_chat.id,
|
||||
"answers": 0,
|
||||
}
|
||||
}
|
||||
context.bot_data.update(payload)
|
||||
|
||||
|
||||
def receive_poll_answer(update: Update, context: CallbackContext) -> None:
|
||||
"""Summarize a users poll vote"""
|
||||
answer = update.poll_answer
|
||||
poll_id = answer.poll_id
|
||||
try:
|
||||
questions = context.bot_data[poll_id]["questions"]
|
||||
# this means this poll answer update is from an old poll, we can't do our answering then
|
||||
except KeyError:
|
||||
return
|
||||
selected_options = answer.option_ids
|
||||
answer_string = ""
|
||||
for question_id in selected_options:
|
||||
if question_id != selected_options[-1]:
|
||||
answer_string += questions[question_id] + " and "
|
||||
else:
|
||||
answer_string += questions[question_id]
|
||||
context.bot.send_message(
|
||||
context.bot_data[poll_id]["chat_id"],
|
||||
f"{update.effective_user.mention_html()} feels {answer_string}!",
|
||||
parse_mode=ParseMode.HTML,
|
||||
)
|
||||
context.bot_data[poll_id]["answers"] += 1
|
||||
# Close poll after three participants voted
|
||||
if context.bot_data[poll_id]["answers"] == 3:
|
||||
context.bot.stop_poll(
|
||||
context.bot_data[poll_id]["chat_id"], context.bot_data[poll_id]["message_id"]
|
||||
)
|
||||
|
||||
|
||||
def quiz(update: Update, context: CallbackContext) -> None:
|
||||
"""Send a predefined poll"""
|
||||
questions = ["1", "2", "4", "20"]
|
||||
message = update.effective_message.reply_poll(
|
||||
"How many eggs do you need for a cake?", questions, type=Poll.QUIZ, correct_option_id=2
|
||||
)
|
||||
# Save some info about the poll the bot_data for later use in receive_quiz_answer
|
||||
payload = {
|
||||
message.poll.id: {"chat_id": update.effective_chat.id, "message_id": message.message_id}
|
||||
}
|
||||
context.bot_data.update(payload)
|
||||
|
||||
|
||||
def receive_quiz_answer(update: Update, context: CallbackContext) -> None:
|
||||
"""Close quiz after three participants took it"""
|
||||
# the bot can receive closed poll updates we don't care about
|
||||
if update.poll.is_closed:
|
||||
return
|
||||
if update.poll.total_voter_count == 3:
|
||||
try:
|
||||
quiz_data = context.bot_data[update.poll.id]
|
||||
# this means this poll answer update is from an old poll, we can't stop it then
|
||||
except KeyError:
|
||||
return
|
||||
context.bot.stop_poll(quiz_data["chat_id"], quiz_data["message_id"])
|
||||
|
||||
|
||||
def preview(update: Update, context: CallbackContext) -> None:
|
||||
"""Ask user to create a poll and display a preview of it"""
|
||||
# using this without a type lets the user chooses what he wants (quiz or poll)
|
||||
button = [[KeyboardButton("Press me!", request_poll=KeyboardButtonPollType())]]
|
||||
message = "Press the button to let the bot generate a preview for your poll"
|
||||
# using one_time_keyboard to hide the keyboard
|
||||
update.effective_message.reply_text(
|
||||
message, reply_markup=ReplyKeyboardMarkup(button, one_time_keyboard=True)
|
||||
)
|
||||
|
||||
|
||||
def receive_poll(update: Update, context: CallbackContext) -> None:
|
||||
"""On receiving polls, reply to it by a closed poll copying the received poll"""
|
||||
actual_poll = update.effective_message.poll
|
||||
# Only need to set the question and options, since all other parameters don't matter for
|
||||
# a closed poll
|
||||
update.effective_message.reply_poll(
|
||||
question=actual_poll.question,
|
||||
options=[o.text for o in actual_poll.options],
|
||||
# with is_closed true, the poll/quiz is immediately closed
|
||||
is_closed=True,
|
||||
reply_markup=ReplyKeyboardRemove(),
|
||||
)
|
||||
|
||||
|
||||
def help_handler(update: Update, context: CallbackContext) -> None:
|
||||
"""Display a help message"""
|
||||
update.message.reply_text("Use /quiz, /poll or /preview to test this " "bot.")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
dispatcher = updater.dispatcher
|
||||
dispatcher.add_handler(CommandHandler('start', start))
|
||||
dispatcher.add_handler(CommandHandler('poll', poll))
|
||||
dispatcher.add_handler(PollAnswerHandler(receive_poll_answer))
|
||||
dispatcher.add_handler(CommandHandler('quiz', quiz))
|
||||
dispatcher.add_handler(PollHandler(receive_quiz_answer))
|
||||
dispatcher.add_handler(CommandHandler('preview', preview))
|
||||
dispatcher.add_handler(MessageHandler(Filters.poll, receive_poll))
|
||||
dispatcher.add_handler(CommandHandler('help', help_handler))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
# Run the bot until the user presses Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0603
|
||||
"""Simple Bot to reply to Telegram messages.
|
||||
|
||||
This is built on the API wrapper, see echobot.py to see the same example built
|
||||
on the telegram.ext bot framework.
|
||||
This program is dedicated to the public domain under the CC0 license.
|
||||
"""
|
||||
import logging
|
||||
from typing import NoReturn
|
||||
from time import sleep
|
||||
|
||||
import telegram
|
||||
from telegram.error import NetworkError, Unauthorized
|
||||
|
||||
|
||||
UPDATE_ID = None
|
||||
|
||||
|
||||
def main() -> NoReturn:
|
||||
"""Run the bot."""
|
||||
global UPDATE_ID
|
||||
# Telegram Bot Authorization Token
|
||||
bot = telegram.Bot('TOKEN')
|
||||
|
||||
# get the first pending update_id, this is so we can skip over it in case
|
||||
# we get an "Unauthorized" exception.
|
||||
try:
|
||||
UPDATE_ID = bot.get_updates()[0].update_id
|
||||
except IndexError:
|
||||
UPDATE_ID = None
|
||||
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
|
||||
while True:
|
||||
try:
|
||||
echo(bot)
|
||||
except NetworkError:
|
||||
sleep(1)
|
||||
except Unauthorized:
|
||||
# The user has removed or blocked the bot.
|
||||
UPDATE_ID += 1 # type: ignore[operator]
|
||||
|
||||
|
||||
def echo(bot: telegram.Bot) -> None:
|
||||
"""Echo the message the user sent."""
|
||||
global UPDATE_ID
|
||||
# Request updates after the last update_id
|
||||
for update in bot.get_updates(offset=UPDATE_ID, timeout=10):
|
||||
UPDATE_ID = update.update_id + 1
|
||||
|
||||
if update.message: # your bot can receive updates without messages
|
||||
if update.message.text: # not all messages contain text
|
||||
# Reply to the message
|
||||
update.message.reply_text(update.message.text)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+46
-45
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
"""Simple Bot to send timed Telegram messages.
|
||||
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
Simple Bot to send timed Telegram messages.
|
||||
|
||||
This Bot uses the Updater class to handle the bot and the JobQueue to send
|
||||
timed messages.
|
||||
|
||||
@@ -19,83 +19,84 @@ Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
from telegram.ext import Updater, CommandHandler
|
||||
import logging
|
||||
|
||||
from telegram import Update
|
||||
from telegram.ext import Updater, CommandHandler, CallbackContext
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Define a few command handlers. These usually take the two arguments bot and
|
||||
# update. Error handlers also receive the raised TelegramError object in error.
|
||||
def start(bot, update):
|
||||
# Define a few command handlers. These usually take the two arguments update and
|
||||
# context. Error handlers also receive the raised TelegramError object in error.
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
update.message.reply_text('Hi! Use /set <seconds> to set a timer')
|
||||
|
||||
|
||||
def alarm(bot, job):
|
||||
def alarm(context):
|
||||
"""Send the alarm message."""
|
||||
bot.send_message(job.context, text='Beep!')
|
||||
job = context.job
|
||||
context.bot.send_message(job.context, text='Beep!')
|
||||
|
||||
|
||||
def set_timer(bot, update, args, job_queue, chat_data):
|
||||
def remove_job_if_exists(name, context):
|
||||
"""Remove job with given name. Returns whether job was removed."""
|
||||
current_jobs = context.job_queue.get_jobs_by_name(name)
|
||||
if not current_jobs:
|
||||
return False
|
||||
for job in current_jobs:
|
||||
job.schedule_removal()
|
||||
return True
|
||||
|
||||
|
||||
def set_timer(update: Update, context: CallbackContext) -> None:
|
||||
"""Add a job to the queue."""
|
||||
chat_id = update.message.chat_id
|
||||
try:
|
||||
# args[0] should contain the time for the timer in seconds
|
||||
due = int(args[0])
|
||||
due = int(context.args[0])
|
||||
if due < 0:
|
||||
update.message.reply_text('Sorry we can not go back to future!')
|
||||
return
|
||||
|
||||
# Add job to queue
|
||||
job = job_queue.run_once(alarm, due, context=chat_id)
|
||||
chat_data['job'] = job
|
||||
job_removed = remove_job_if_exists(str(chat_id), context)
|
||||
context.job_queue.run_once(alarm, due, context=chat_id, name=str(chat_id))
|
||||
|
||||
update.message.reply_text('Timer successfully set!')
|
||||
text = 'Timer successfully set!'
|
||||
if job_removed:
|
||||
text += ' Old one was removed.'
|
||||
update.message.reply_text(text)
|
||||
|
||||
except (IndexError, ValueError):
|
||||
update.message.reply_text('Usage: /set <seconds>')
|
||||
|
||||
|
||||
def unset(bot, update, chat_data):
|
||||
def unset(update: Update, context: CallbackContext) -> None:
|
||||
"""Remove the job if the user changed their mind."""
|
||||
if 'job' not in chat_data:
|
||||
update.message.reply_text('You have no active timer')
|
||||
return
|
||||
|
||||
job = chat_data['job']
|
||||
job.schedule_removal()
|
||||
del chat_data['job']
|
||||
|
||||
update.message.reply_text('Timer successfully unset!')
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
chat_id = update.message.chat_id
|
||||
job_removed = remove_job_if_exists(str(chat_id), context)
|
||||
text = 'Timer successfully cancelled!' if job_removed else 'You have no active timer.'
|
||||
update.message.reply_text(text)
|
||||
|
||||
|
||||
def main():
|
||||
"""Run bot."""
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# on different commands - answer in Telegram
|
||||
dp.add_handler(CommandHandler("start", start))
|
||||
dp.add_handler(CommandHandler("help", start))
|
||||
dp.add_handler(CommandHandler("set", set_timer,
|
||||
pass_args=True,
|
||||
pass_job_queue=True,
|
||||
pass_chat_data=True))
|
||||
dp.add_handler(CommandHandler("unset", unset, pass_chat_data=True))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
dispatcher.add_handler(CommandHandler("start", start))
|
||||
dispatcher.add_handler(CommandHandler("help", start))
|
||||
dispatcher.add_handler(CommandHandler("set", set_timer))
|
||||
dispatcher.add_handler(CommandHandler("unset", unset))
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[tool.black]
|
||||
line-length = 99
|
||||
target-version = ['py36']
|
||||
skip-string-normalization = true
|
||||
|
||||
# We need to force-exclude the negated include pattern
|
||||
# so that pre-commit run --all-files does the correct thing
|
||||
# see https://github.com/psf/black/issues/1778
|
||||
force-exclude = '^(?!/(telegram|examples|tests)/).*\.py$'
|
||||
include = '(telegram|examples|tests)/.*\.py$'
|
||||
exclude = 'telegram/vendor'
|
||||
+12
-6
@@ -1,10 +1,16 @@
|
||||
flake8
|
||||
pep257
|
||||
pylint
|
||||
flaky
|
||||
yapf
|
||||
pre-commit
|
||||
# Make sure that the versions specified here match the pre-commit settings
|
||||
black==20.8b1
|
||||
flake8==3.8.4
|
||||
pylint==2.6.0
|
||||
mypy==0.790
|
||||
pyupgrade==2.7.4
|
||||
|
||||
pytest==4.2.0
|
||||
# Need older attrs version for pytest 4.2.0
|
||||
attrs==19.1.0
|
||||
|
||||
flaky
|
||||
beautifulsoup4
|
||||
pytest
|
||||
pytest-timeout
|
||||
wheel
|
||||
|
||||
+4
-1
@@ -1,3 +1,6 @@
|
||||
future>=0.16.0
|
||||
certifi
|
||||
cryptography
|
||||
# only telegram.ext: # Keep this line here; used in setup(-raw).py
|
||||
tornado>=5.1
|
||||
APScheduler==3.6.3
|
||||
pytz>=2018.6
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
"""The setup and build script for the python-telegram-bot-raw library."""
|
||||
|
||||
from setuptools import setup
|
||||
from setup import get_setup_kwargs
|
||||
|
||||
setup(**get_setup_kwargs(raw=True))
|
||||
@@ -1,6 +1,3 @@
|
||||
[wheel]
|
||||
universal = 1
|
||||
|
||||
[metadata]
|
||||
license_file = LICENSE.dual
|
||||
|
||||
@@ -14,12 +11,15 @@ upload-dir = docs/build/html
|
||||
|
||||
[flake8]
|
||||
max-line-length = 99
|
||||
ignore = W503
|
||||
ignore = W503, W605
|
||||
extend-ignore = E203
|
||||
exclude = setup.py, setup-raw.py docs/source/conf.py, telegram/vendor
|
||||
|
||||
[yapf]
|
||||
based_on_style = google
|
||||
split_before_logical_operator = True
|
||||
column_limit = 99
|
||||
[pylint]
|
||||
ignore=vendor
|
||||
|
||||
[pylint.message-control]
|
||||
disable = C0330,R0801,R0913,R0904,R0903,R0902,W0511,C0116,C0115,W0703,R0914,R0914,C0302,R0912,R0915,R0401
|
||||
|
||||
[tool:pytest]
|
||||
testpaths = tests
|
||||
@@ -27,6 +27,7 @@ addopts = --no-success-flaky-report -rsxX
|
||||
filterwarnings =
|
||||
error
|
||||
ignore::DeprecationWarning
|
||||
ignore::telegram.utils.deprecate.TelegramDeprecationWarning
|
||||
|
||||
[coverage:run]
|
||||
branch = True
|
||||
@@ -38,3 +39,28 @@ omit =
|
||||
telegram/__main__.py
|
||||
telegram/vendor/*
|
||||
|
||||
[coverage:report]
|
||||
exclude_lines =
|
||||
if TYPE_CHECKING:
|
||||
|
||||
[mypy]
|
||||
warn_unused_ignores = True
|
||||
warn_unused_configs = True
|
||||
disallow_untyped_defs = True
|
||||
disallow_incomplete_defs = True
|
||||
disallow_untyped_decorators = True
|
||||
show_error_codes = True
|
||||
|
||||
[mypy-telegram.vendor.*]
|
||||
ignore_errors = True
|
||||
|
||||
# Disable strict optional for telegram objects with class methods
|
||||
# We don't want to clutter the code with 'if self.bot is None: raise RuntimeError()'
|
||||
[mypy-telegram.callbackquery,telegram.chat,telegram.message,telegram.user,telegram.files.*,telegram.inline.inlinequery,telegram.payment.precheckoutquery,telegram.payment.shippingquery,telegram.passport.passportdata,telegram.passport.credentials,telegram.passport.passportfile,telegram.ext.filters]
|
||||
strict_optional = False
|
||||
|
||||
[mypy-urllib3.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-apscheduler.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
@@ -3,57 +3,120 @@
|
||||
|
||||
import codecs
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
UPSTREAM_URLLIB3_FLAG = '--with-upstream-urllib3'
|
||||
|
||||
def requirements():
|
||||
|
||||
def get_requirements(raw=False):
|
||||
"""Build the requirements list for this project"""
|
||||
requirements_list = []
|
||||
|
||||
with open('requirements.txt') as requirements:
|
||||
for install in requirements:
|
||||
with open('requirements.txt') as reqs:
|
||||
for install in reqs:
|
||||
if install.startswith('# only telegram.ext:'):
|
||||
if raw:
|
||||
break
|
||||
continue
|
||||
requirements_list.append(install.strip())
|
||||
|
||||
return requirements_list
|
||||
|
||||
|
||||
packages = find_packages(exclude=['tests*'])
|
||||
def get_packages_requirements(raw=False):
|
||||
"""Build the package & requirements list for this project"""
|
||||
reqs = get_requirements(raw=raw)
|
||||
|
||||
exclude = ['tests*']
|
||||
if raw:
|
||||
exclude.append('telegram.ext*')
|
||||
|
||||
packs = find_packages(exclude=exclude)
|
||||
# Allow for a package install to not use the vendored urllib3
|
||||
if UPSTREAM_URLLIB3_FLAG in sys.argv:
|
||||
sys.argv.remove(UPSTREAM_URLLIB3_FLAG)
|
||||
reqs.append('urllib3 >= 1.19.1')
|
||||
packs = [x for x in packs if not x.startswith('telegram.vendor.ptb_urllib3')]
|
||||
|
||||
return packs, reqs
|
||||
|
||||
|
||||
def get_setup_kwargs(raw=False):
|
||||
"""Builds a dictionary of kwargs for the setup function"""
|
||||
packages, requirements = get_packages_requirements(raw=raw)
|
||||
|
||||
raw_ext = "-raw" if raw else ""
|
||||
readme = f'README{"_RAW" if raw else ""}.rst'
|
||||
|
||||
with codecs.open('README.rst', 'r', 'utf-8') as fd:
|
||||
fn = os.path.join('telegram', 'version.py')
|
||||
with open(fn) as fh:
|
||||
code = compile(fh.read(), fn, 'exec')
|
||||
exec(code)
|
||||
|
||||
setup(name='python-telegram-bot',
|
||||
version=__version__,
|
||||
author='Leandro Toledo',
|
||||
author_email='devs@python-telegram-bot.org',
|
||||
license='LGPLv3',
|
||||
url='https://python-telegram-bot.org/',
|
||||
keywords='python telegram bot api wrapper',
|
||||
description="We have made you a wrapper you can't refuse",
|
||||
long_description=fd.read(),
|
||||
packages=packages,
|
||||
install_requires=requirements(),
|
||||
extras_require={
|
||||
'json': 'ujson',
|
||||
'socks': 'PySocks'
|
||||
},
|
||||
include_package_data=True,
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)',
|
||||
'Operating System :: OS Independent',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Topic :: Communications :: Chat',
|
||||
'Topic :: Internet',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6'
|
||||
],)
|
||||
with open(readme, 'r', encoding='utf-8') as fd:
|
||||
|
||||
kwargs = dict(
|
||||
script_name=f'setup{raw_ext}.py',
|
||||
name=f'python-telegram-bot{raw_ext}',
|
||||
version=locals()['__version__'],
|
||||
author='Leandro Toledo',
|
||||
author_email='devs@python-telegram-bot.org',
|
||||
license='LGPLv3',
|
||||
url='https://python-telegram-bot.org/',
|
||||
# Keywords supported by PyPI can be found at https://git.io/JtLIZ
|
||||
project_urls={
|
||||
"Documentation": "https://python-telegram-bot.readthedocs.io",
|
||||
"Bug Tracker": "https://github.com/python-telegram-bot/python-telegram-bot/issues",
|
||||
"Source Code": "https://github.com/python-telegram-bot/python-telegram-bot",
|
||||
"News": "https://t.me/pythontelegrambotchannel",
|
||||
"Changelog": "https://python-telegram-bot.readthedocs.io/en/stable/changelog.html",
|
||||
},
|
||||
download_url=f'https://pypi.org/project/python-telegram-bot{raw_ext}/',
|
||||
keywords='python telegram bot api wrapper',
|
||||
description="We have made you a wrapper you can't refuse",
|
||||
long_description=fd.read(),
|
||||
long_description_content_type='text/x-rst',
|
||||
packages=packages,
|
||||
|
||||
install_requires=requirements,
|
||||
extras_require={
|
||||
'json': 'ujson',
|
||||
'socks': 'PySocks'
|
||||
},
|
||||
include_package_data=True,
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)',
|
||||
'Operating System :: OS Independent',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Topic :: Communications :: Chat',
|
||||
'Topic :: Internet',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
],
|
||||
python_requires='>=3.6'
|
||||
)
|
||||
|
||||
return kwargs
|
||||
|
||||
|
||||
def main():
|
||||
# If we're building, build ptb-raw as well
|
||||
if set(sys.argv[1:]) in [{'bdist_wheel'}, {'sdist'}, {'sdist', 'bdist_wheel'}]:
|
||||
args = ['python', 'setup-raw.py']
|
||||
args.extend(sys.argv[1:])
|
||||
subprocess.run(args, check=True, capture_output=True)
|
||||
|
||||
setup(**get_setup_kwargs(raw=False))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
+176
-51
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,10 +19,13 @@
|
||||
"""A library that provides a Python interface to the Telegram Bot API"""
|
||||
|
||||
from .base import TelegramObject
|
||||
from .botcommand import BotCommand
|
||||
from .user import User
|
||||
from .files.chatphoto import ChatPhoto
|
||||
from .chat import Chat
|
||||
from .chatlocation import ChatLocation
|
||||
from .chatmember import ChatMember
|
||||
from .chatpermissions import ChatPermissions
|
||||
from .files.photosize import PhotoSize
|
||||
from .files.audio import Audio
|
||||
from .files.voice import Voice
|
||||
@@ -35,8 +38,10 @@ from .files.location import Location
|
||||
from .files.venue import Venue
|
||||
from .files.videonote import VideoNote
|
||||
from .chataction import ChatAction
|
||||
from .dice import Dice
|
||||
from .userprofilephotos import UserProfilePhotos
|
||||
from .keyboardbutton import KeyboardButton
|
||||
from .keyboardbuttonpolltype import KeyboardButtonPollType
|
||||
from .replymarkup import ReplyMarkup
|
||||
from .replykeyboardmarkup import ReplyKeyboardMarkup
|
||||
from .replykeyboardremove import ReplyKeyboardRemove
|
||||
@@ -46,7 +51,11 @@ from .files.inputfile import InputFile
|
||||
from .files.file import File
|
||||
from .parsemode import ParseMode
|
||||
from .messageentity import MessageEntity
|
||||
from .messageid import MessageId
|
||||
from .games.game import Game
|
||||
from .poll import Poll, PollOption, PollAnswer
|
||||
from .loginurl import LoginUrl
|
||||
from .proximityalerttriggered import ProximityAlertTriggered
|
||||
from .games.callbackgame import CallbackGame
|
||||
from .payment.shippingaddress import ShippingAddress
|
||||
from .payment.orderinfo import OrderInfo
|
||||
@@ -57,11 +66,11 @@ from .passport.passportfile import PassportFile
|
||||
from .passport.data import IdDocumentData, PersonalDetails, ResidentialAddress
|
||||
from .passport.encryptedpassportelement import EncryptedPassportElement
|
||||
from .passport.passportdata import PassportData
|
||||
from .inline.inlinekeyboardbutton import InlineKeyboardButton
|
||||
from .inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from .message import Message
|
||||
from .callbackquery import CallbackQuery
|
||||
from .choseninlineresult import ChosenInlineResult
|
||||
from .inline.inlinekeyboardbutton import InlineKeyboardButton
|
||||
from .inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from .inline.inputmessagecontent import InputMessageContent
|
||||
from .inline.inlinequery import InlineQuery
|
||||
from .inline.inlinequeryresult import InlineQueryResult
|
||||
@@ -96,57 +105,173 @@ from .payment.shippingquery import ShippingQuery
|
||||
from .webhookinfo import WebhookInfo
|
||||
from .games.gamehighscore import GameHighScore
|
||||
from .update import Update
|
||||
from .files.inputmedia import (InputMedia, InputMediaVideo, InputMediaPhoto, InputMediaAnimation,
|
||||
InputMediaAudio, InputMediaDocument)
|
||||
from .files.inputmedia import (
|
||||
InputMedia,
|
||||
InputMediaVideo,
|
||||
InputMediaPhoto,
|
||||
InputMediaAnimation,
|
||||
InputMediaAudio,
|
||||
InputMediaDocument,
|
||||
)
|
||||
from .constants import (
|
||||
MAX_MESSAGE_LENGTH,
|
||||
MAX_CAPTION_LENGTH,
|
||||
SUPPORTED_WEBHOOK_PORTS,
|
||||
MAX_FILESIZE_DOWNLOAD,
|
||||
MAX_FILESIZE_UPLOAD,
|
||||
MAX_MESSAGES_PER_SECOND_PER_CHAT,
|
||||
MAX_MESSAGES_PER_SECOND,
|
||||
MAX_MESSAGES_PER_MINUTE_PER_GROUP,
|
||||
)
|
||||
from .passport.passportelementerrors import (
|
||||
PassportElementError,
|
||||
PassportElementErrorDataField,
|
||||
PassportElementErrorFile,
|
||||
PassportElementErrorFiles,
|
||||
PassportElementErrorFrontSide,
|
||||
PassportElementErrorReverseSide,
|
||||
PassportElementErrorSelfie,
|
||||
PassportElementErrorTranslationFile,
|
||||
PassportElementErrorTranslationFiles,
|
||||
PassportElementErrorUnspecified,
|
||||
)
|
||||
from .passport.credentials import (
|
||||
Credentials,
|
||||
DataCredentials,
|
||||
SecureData,
|
||||
FileCredentials,
|
||||
TelegramDecryptionError,
|
||||
)
|
||||
from .bot import Bot
|
||||
from .constants import (MAX_MESSAGE_LENGTH, MAX_CAPTION_LENGTH, SUPPORTED_WEBHOOK_PORTS,
|
||||
MAX_FILESIZE_DOWNLOAD, MAX_FILESIZE_UPLOAD,
|
||||
MAX_MESSAGES_PER_SECOND_PER_CHAT, MAX_MESSAGES_PER_SECOND,
|
||||
MAX_MESSAGES_PER_MINUTE_PER_GROUP)
|
||||
from .passport.passportelementerrors import (PassportElementError,
|
||||
PassportElementErrorDataField,
|
||||
PassportElementErrorFile,
|
||||
PassportElementErrorFiles,
|
||||
PassportElementErrorFrontSide,
|
||||
PassportElementErrorReverseSide,
|
||||
PassportElementErrorSelfie)
|
||||
from .passport.credentials import (Credentials,
|
||||
DataCredentials,
|
||||
SecureData,
|
||||
FileCredentials,
|
||||
TelegramDecryptionError)
|
||||
from .version import __version__ # flake8: noqa
|
||||
from .version import __version__ # noqa: F401
|
||||
|
||||
__author__ = 'devs@python-telegram-bot.org'
|
||||
|
||||
__all__ = [
|
||||
'Audio', 'Bot', 'Chat', 'ChatMember', 'ChatAction', 'ChosenInlineResult', 'CallbackQuery',
|
||||
'Contact', 'Document', 'File', 'ForceReply', 'InlineKeyboardButton',
|
||||
'InlineKeyboardMarkup', 'InlineQuery', 'InlineQueryResult', 'InlineQueryResult',
|
||||
'InlineQueryResultArticle', 'InlineQueryResultAudio', 'InlineQueryResultCachedAudio',
|
||||
'InlineQueryResultCachedDocument', 'InlineQueryResultCachedGif',
|
||||
'InlineQueryResultCachedMpeg4Gif', 'InlineQueryResultCachedPhoto',
|
||||
'InlineQueryResultCachedSticker', 'InlineQueryResultCachedVideo',
|
||||
'InlineQueryResultCachedVoice', 'InlineQueryResultContact', 'InlineQueryResultDocument',
|
||||
'InlineQueryResultGif', 'InlineQueryResultLocation', 'InlineQueryResultMpeg4Gif',
|
||||
'InlineQueryResultPhoto', 'InlineQueryResultVenue', 'InlineQueryResultVideo',
|
||||
'InlineQueryResultVoice', 'InlineQueryResultGame', 'InputContactMessageContent', 'InputFile',
|
||||
'InputLocationMessageContent', 'InputMessageContent', 'InputTextMessageContent',
|
||||
'InputVenueMessageContent', 'KeyboardButton', 'Location', 'EncryptedCredentials',
|
||||
'PassportFile', 'EncryptedPassportElement', 'PassportData', 'Message', 'MessageEntity',
|
||||
'ParseMode', 'PhotoSize', 'ReplyKeyboardRemove', 'ReplyKeyboardMarkup', 'ReplyMarkup',
|
||||
'Sticker', 'TelegramError', 'TelegramObject', 'Update', 'User', 'UserProfilePhotos', 'Venue',
|
||||
'Video', 'Voice', 'MAX_MESSAGE_LENGTH', 'MAX_CAPTION_LENGTH', 'SUPPORTED_WEBHOOK_PORTS',
|
||||
'MAX_FILESIZE_DOWNLOAD', 'MAX_FILESIZE_UPLOAD', 'MAX_MESSAGES_PER_SECOND_PER_CHAT',
|
||||
'MAX_MESSAGES_PER_SECOND', 'MAX_MESSAGES_PER_MINUTE_PER_GROUP', 'WebhookInfo', 'Animation',
|
||||
'Game', 'GameHighScore', 'VideoNote', 'LabeledPrice', 'SuccessfulPayment', 'ShippingOption',
|
||||
'ShippingAddress', 'PreCheckoutQuery', 'OrderInfo', 'Invoice', 'ShippingQuery', 'ChatPhoto',
|
||||
'StickerSet', 'MaskPosition', 'CallbackGame', 'InputMedia', 'InputMediaPhoto',
|
||||
'InputMediaVideo', 'PassportElementError', 'PassportElementErrorFile',
|
||||
'PassportElementErrorReverseSide', 'PassportElementErrorFrontSide',
|
||||
'PassportElementErrorFiles', 'PassportElementErrorDataField', 'PassportElementErrorFile',
|
||||
'Credentials', 'DataCredentials', 'SecureData', 'FileCredentials', 'IdDocumentData',
|
||||
'PersonalDetails', 'ResidentialAddress', 'InputMediaVideo', 'InputMediaAnimation',
|
||||
'InputMediaAudio', 'InputMediaDocument', 'TelegramDecryptionError',
|
||||
'PassportElementErrorSelfie'
|
||||
'Audio',
|
||||
'Bot',
|
||||
'Chat',
|
||||
'ChatMember',
|
||||
'ChatPermissions',
|
||||
'ChatAction',
|
||||
'ChosenInlineResult',
|
||||
'CallbackQuery',
|
||||
'Contact',
|
||||
'Document',
|
||||
'File',
|
||||
'ForceReply',
|
||||
'InlineKeyboardButton',
|
||||
'InlineKeyboardMarkup',
|
||||
'InlineQuery',
|
||||
'InlineQueryResult',
|
||||
'InlineQueryResult',
|
||||
'InlineQueryResultArticle',
|
||||
'InlineQueryResultAudio',
|
||||
'InlineQueryResultCachedAudio',
|
||||
'InlineQueryResultCachedDocument',
|
||||
'InlineQueryResultCachedGif',
|
||||
'InlineQueryResultCachedMpeg4Gif',
|
||||
'InlineQueryResultCachedPhoto',
|
||||
'InlineQueryResultCachedSticker',
|
||||
'InlineQueryResultCachedVideo',
|
||||
'InlineQueryResultCachedVoice',
|
||||
'InlineQueryResultContact',
|
||||
'InlineQueryResultDocument',
|
||||
'InlineQueryResultGif',
|
||||
'InlineQueryResultLocation',
|
||||
'InlineQueryResultMpeg4Gif',
|
||||
'InlineQueryResultPhoto',
|
||||
'InlineQueryResultVenue',
|
||||
'InlineQueryResultVideo',
|
||||
'InlineQueryResultVoice',
|
||||
'InlineQueryResultGame',
|
||||
'InputContactMessageContent',
|
||||
'InputFile',
|
||||
'InputLocationMessageContent',
|
||||
'InputMessageContent',
|
||||
'InputTextMessageContent',
|
||||
'InputVenueMessageContent',
|
||||
'Location',
|
||||
'ChatLocation',
|
||||
'ProximityAlertTriggered',
|
||||
'EncryptedCredentials',
|
||||
'PassportFile',
|
||||
'EncryptedPassportElement',
|
||||
'PassportData',
|
||||
'Message',
|
||||
'MessageEntity',
|
||||
'ParseMode',
|
||||
'PhotoSize',
|
||||
'ReplyKeyboardRemove',
|
||||
'ReplyKeyboardMarkup',
|
||||
'ReplyMarkup',
|
||||
'Sticker',
|
||||
'TelegramError',
|
||||
'TelegramObject',
|
||||
'Update',
|
||||
'User',
|
||||
'UserProfilePhotos',
|
||||
'Venue',
|
||||
'Video',
|
||||
'Voice',
|
||||
'MAX_MESSAGE_LENGTH',
|
||||
'MAX_CAPTION_LENGTH',
|
||||
'SUPPORTED_WEBHOOK_PORTS',
|
||||
'MAX_FILESIZE_DOWNLOAD',
|
||||
'MAX_FILESIZE_UPLOAD',
|
||||
'MAX_MESSAGES_PER_SECOND_PER_CHAT',
|
||||
'MAX_MESSAGES_PER_SECOND',
|
||||
'MAX_MESSAGES_PER_MINUTE_PER_GROUP',
|
||||
'WebhookInfo',
|
||||
'Animation',
|
||||
'Game',
|
||||
'GameHighScore',
|
||||
'VideoNote',
|
||||
'LabeledPrice',
|
||||
'SuccessfulPayment',
|
||||
'ShippingOption',
|
||||
'ShippingAddress',
|
||||
'PreCheckoutQuery',
|
||||
'OrderInfo',
|
||||
'Invoice',
|
||||
'ShippingQuery',
|
||||
'ChatPhoto',
|
||||
'StickerSet',
|
||||
'MaskPosition',
|
||||
'CallbackGame',
|
||||
'InputMedia',
|
||||
'InputMediaPhoto',
|
||||
'InputMediaVideo',
|
||||
'PassportElementError',
|
||||
'PassportElementErrorFile',
|
||||
'PassportElementErrorReverseSide',
|
||||
'PassportElementErrorFrontSide',
|
||||
'PassportElementErrorFiles',
|
||||
'PassportElementErrorDataField',
|
||||
'PassportElementErrorFile',
|
||||
'Credentials',
|
||||
'DataCredentials',
|
||||
'SecureData',
|
||||
'FileCredentials',
|
||||
'IdDocumentData',
|
||||
'PersonalDetails',
|
||||
'ResidentialAddress',
|
||||
'InputMediaVideo',
|
||||
'InputMediaAnimation',
|
||||
'InputMediaAudio',
|
||||
'InputMediaDocument',
|
||||
'TelegramDecryptionError',
|
||||
'PassportElementErrorSelfie',
|
||||
'PassportElementErrorTranslationFile',
|
||||
'PassportElementErrorTranslationFiles',
|
||||
'PassportElementErrorUnspecified',
|
||||
'Poll',
|
||||
'PollOption',
|
||||
'PollAnswer',
|
||||
'LoginUrl',
|
||||
'KeyboardButton',
|
||||
'KeyboardButtonPollType',
|
||||
'Dice',
|
||||
'BotCommand',
|
||||
'MessageId',
|
||||
]
|
||||
|
||||
+21
-8
@@ -1,7 +1,7 @@
|
||||
# !/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -16,22 +16,35 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=E0401, C0114
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
import certifi
|
||||
import future
|
||||
|
||||
from . import __version__ as telegram_ver
|
||||
|
||||
|
||||
def print_ver_info():
|
||||
print('python-telegram-bot {0}'.format(telegram_ver))
|
||||
print('certifi {0}'.format(certifi.__version__))
|
||||
print('future {0}'.format(future.__version__))
|
||||
print('Python {0}'.format(sys.version.replace('\n', ' ')))
|
||||
def _git_revision() -> Optional[str]:
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
["git", "describe", "--long", "--tags"], stderr=subprocess.STDOUT
|
||||
)
|
||||
except (subprocess.SubprocessError, OSError):
|
||||
return None
|
||||
return output.decode().strip()
|
||||
|
||||
|
||||
def main():
|
||||
def print_ver_info() -> None:
|
||||
git_revision = _git_revision()
|
||||
print(f'python-telegram-bot {telegram_ver}' + (f' ({git_revision})' if git_revision else ''))
|
||||
print(f'certifi {certifi.__version__}') # type: ignore[attr-defined]
|
||||
sys_version = sys.version.replace('\n', ' ')
|
||||
print(f'Python {sys_version}')
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print_ver_info()
|
||||
|
||||
|
||||
|
||||
+50
-24
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -17,37 +17,58 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""Base class for Telegram Objects."""
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
except ImportError:
|
||||
import json
|
||||
import json # type: ignore[no-redef]
|
||||
|
||||
from abc import ABCMeta
|
||||
import warnings
|
||||
from typing import TYPE_CHECKING, List, Optional, Tuple, Type, TypeVar
|
||||
|
||||
from telegram.utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
TO = TypeVar('TO', bound='TelegramObject', covariant=True)
|
||||
|
||||
|
||||
class TelegramObject(object):
|
||||
class TelegramObject:
|
||||
"""Base class for most telegram objects."""
|
||||
|
||||
__metaclass__ = ABCMeta
|
||||
_id_attrs = ()
|
||||
_id_attrs: Tuple[object, ...] = ()
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
return str(self.to_dict())
|
||||
|
||||
def __getitem__(self, item):
|
||||
def __getitem__(self, item: str) -> object:
|
||||
return self.__dict__[item]
|
||||
|
||||
@staticmethod
|
||||
def parse_data(data: Optional[JSONDict]) -> Optional[JSONDict]:
|
||||
if not data:
|
||||
return None
|
||||
return data.copy()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
def de_json(cls: Type[TO], data: Optional[JSONDict], bot: 'Bot') -> Optional[TO]:
|
||||
data = cls.parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = data.copy()
|
||||
if cls == TelegramObject:
|
||||
return cls()
|
||||
return cls(bot=bot, **data) # type: ignore[call-arg]
|
||||
|
||||
return data
|
||||
@classmethod
|
||||
def de_list(cls: Type[TO], data: Optional[List[JSONDict]], bot: 'Bot') -> List[Optional[TO]]:
|
||||
if not data:
|
||||
return []
|
||||
|
||||
def to_json(self):
|
||||
return [cls.de_json(d, bot) for d in data]
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""
|
||||
Returns:
|
||||
:obj:`str`
|
||||
@@ -56,16 +77,11 @@ class TelegramObject(object):
|
||||
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
def to_dict(self):
|
||||
def to_dict(self) -> JSONDict:
|
||||
data = dict()
|
||||
|
||||
for key in iter(self.__dict__):
|
||||
if key in ('bot',
|
||||
'_id_attrs',
|
||||
'_credentials',
|
||||
'_decrypted_credentials',
|
||||
'_decrypted_data',
|
||||
'_decrypted_secret'):
|
||||
if key == 'bot' or key.startswith('_'):
|
||||
continue
|
||||
|
||||
value = self.__dict__[key]
|
||||
@@ -79,12 +95,22 @@ class TelegramObject(object):
|
||||
data['from'] = data.pop('from_user', None)
|
||||
return data
|
||||
|
||||
def __eq__(self, other):
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, self.__class__):
|
||||
if self._id_attrs == ():
|
||||
warnings.warn(
|
||||
f"Objects of type {self.__class__.__name__} can not be meaningfully tested for"
|
||||
" equivalence."
|
||||
)
|
||||
if other._id_attrs == ():
|
||||
warnings.warn(
|
||||
f"Objects of type {other.__class__.__name__} can not be meaningfully tested"
|
||||
" for equivalence."
|
||||
)
|
||||
return self._id_attrs == other._id_attrs
|
||||
return super(TelegramObject, self).__eq__(other) # pylint: disable=no-member
|
||||
return super().__eq__(other) # pylint: disable=no-member
|
||||
|
||||
def __hash__(self):
|
||||
def __hash__(self) -> int:
|
||||
if self._id_attrs:
|
||||
return hash((self.__class__, self._id_attrs)) # pylint: disable=no-member
|
||||
return super(TelegramObject, self).__hash__()
|
||||
return super().__hash__()
|
||||
|
||||
+2849
-1344
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=R0903
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Bot Command."""
|
||||
from typing import Any
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
class BotCommand(TelegramObject):
|
||||
"""
|
||||
This object represents a bot command.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`command` and :attr:`description` are equal.
|
||||
|
||||
Args:
|
||||
command (:obj:`str`): Text of the command, 1-32 characters. Can contain only lowercase
|
||||
English letters, digits and underscores.
|
||||
description (:obj:`str`): Description of the command, 3-256 characters.
|
||||
|
||||
Attributes:
|
||||
command (:obj:`str`): Text of the command.
|
||||
description (:obj:`str`): Description of the command.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, command: str, description: str, **_kwargs: Any):
|
||||
self.command = command
|
||||
self.description = description
|
||||
|
||||
self._id_attrs = (self.command, self.description)
|
||||
+523
-72
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -16,9 +16,22 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=W0622
|
||||
"""This module contains an object that represents a Telegram CallbackQuery"""
|
||||
from typing import TYPE_CHECKING, Any, List, Optional, Union, Tuple, ClassVar
|
||||
|
||||
from telegram import TelegramObject, Message, User
|
||||
from telegram import Message, TelegramObject, User, Location, ReplyMarkup, constants
|
||||
from telegram.utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import (
|
||||
Bot,
|
||||
GameHighScore,
|
||||
InlineKeyboardMarkup,
|
||||
MessageId,
|
||||
InputMedia,
|
||||
MessageEntity,
|
||||
)
|
||||
|
||||
|
||||
class CallbackQuery(TelegramObject):
|
||||
@@ -29,58 +42,62 @@ class CallbackQuery(TelegramObject):
|
||||
:attr:`message` will be present. If the button was attached to a message sent via the bot (in
|
||||
inline mode), the field :attr:`inline_message_id` will be present.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`id` is equal.
|
||||
|
||||
Note:
|
||||
* In Python `from` is a reserved word, use `from_user` instead.
|
||||
* Exactly one of the fields :attr:`data` or :attr:`game_short_name` will be present.
|
||||
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique identifier for this query.
|
||||
from_user (:class:`telegram.User`): Sender.
|
||||
message (:class:`telegram.Message`): Optional. Message with the callback button that
|
||||
originated the query.
|
||||
inline_message_id (:obj:`str`): Optional. Identifier of the message sent via the bot in
|
||||
inline mode, that originated the query.
|
||||
chat_instance (:obj:`str`): Optional. Global identifier, uniquely corresponding to the chat
|
||||
to which the message with the callback button was sent.
|
||||
data (:obj:`str`): Optional. Data associated with the callback button.
|
||||
game_short_name (:obj:`str`): Optional. Short name of a Game to be returned.
|
||||
* After the user presses an inline button, Telegram clients will display a progress bar
|
||||
until you call :attr:`answer`. It is, therefore, necessary to react
|
||||
by calling :attr:`telegram.Bot.answer_callback_query` even if no notification to the user
|
||||
is needed (e.g., without specifying any of the optional parameters).
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this query.
|
||||
from_user (:class:`telegram.User`): Sender.
|
||||
chat_instance (:obj:`str`): Global identifier, uniquely corresponding to the chat to which
|
||||
the message with the callback button was sent. Useful for high scores in games.
|
||||
message (:class:`telegram.Message`, optional): Message with the callback button that
|
||||
originated the query. Note that message content and message date will not be available
|
||||
if the message is too old.
|
||||
inline_message_id (:obj:`str`, optional): Identifier of the message sent via the bot in
|
||||
inline mode, that originated the query.
|
||||
chat_instance (:obj:`str`, optional): Global identifier, uniquely corresponding to the chat
|
||||
to which the message with the callback button was sent. Useful for high scores in
|
||||
games.
|
||||
data (:obj:`str`, optional): Data associated with the callback button. Be aware that a bad
|
||||
client can send arbitrary data in this field.
|
||||
inline_message_id (:obj:`str`, optional): Identifier of the message sent via the bot in
|
||||
inline mode, that originated the query.
|
||||
game_short_name (:obj:`str`, optional): Short name of a Game to be returned, serves as
|
||||
the unique identifier for the game
|
||||
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
|
||||
|
||||
Note:
|
||||
After the user presses an inline button, Telegram clients will display a progress bar
|
||||
until you call :attr:`answer`. It is, therefore, necessary to react
|
||||
by calling :attr:`telegram.Bot.answer_callback_query` even if no notification to the user
|
||||
is needed (e.g., without specifying any of the optional parameters).
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique identifier for this query.
|
||||
from_user (:class:`telegram.User`): Sender.
|
||||
chat_instance (:obj:`str`): Global identifier, uniquely corresponding to the chat to which
|
||||
the message with the callback button was sent.
|
||||
message (:class:`telegram.Message`): Optional. Message with the callback button that
|
||||
originated the query.
|
||||
data (:obj:`str`): Optional. Data associated with the callback button.
|
||||
inline_message_id (:obj:`str`): Optional. Identifier of the message sent via the bot in
|
||||
inline mode, that originated the query.
|
||||
game_short_name (:obj:`str`): Optional. Short name of a Game to be returned.
|
||||
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
from_user,
|
||||
chat_instance,
|
||||
message=None,
|
||||
data=None,
|
||||
inline_message_id=None,
|
||||
game_short_name=None,
|
||||
bot=None,
|
||||
**kwargs):
|
||||
def __init__(
|
||||
self,
|
||||
id: str, # pylint: disable=W0622
|
||||
from_user: User,
|
||||
chat_instance: str,
|
||||
message: Message = None,
|
||||
data: str = None,
|
||||
inline_message_id: str = None,
|
||||
game_short_name: str = None,
|
||||
bot: 'Bot' = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.id = id
|
||||
self.id = id # pylint: disable=C0103
|
||||
self.from_user = from_user
|
||||
self.chat_instance = chat_instance
|
||||
# Optionals
|
||||
@@ -94,96 +111,530 @@ class CallbackQuery(TelegramObject):
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['CallbackQuery']:
|
||||
data = cls.parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(CallbackQuery, cls).de_json(data, bot)
|
||||
|
||||
data['from_user'] = User.de_json(data.get('from'), bot)
|
||||
data['message'] = Message.de_json(data.get('message'), bot)
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def answer(self, *args, **kwargs):
|
||||
def answer(
|
||||
self,
|
||||
text: str = None,
|
||||
show_alert: bool = False,
|
||||
url: str = None,
|
||||
cache_time: int = None,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.answer_callback_query(update.callback_query.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.answer_callback_query`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, ``True`` is returned.
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
return self.bot.answerCallbackQuery(self.id, *args, **kwargs)
|
||||
return self.bot.answer_callback_query(
|
||||
callback_query_id=self.id,
|
||||
text=text,
|
||||
show_alert=show_alert,
|
||||
url=url,
|
||||
cache_time=cache_time,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def edit_message_text(self, *args, **kwargs):
|
||||
def edit_message_text(
|
||||
self,
|
||||
text: str,
|
||||
parse_mode: str = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
bot.edit_message_text(chat_id=update.callback_query.message.chat_id,
|
||||
message_id=update.callback_query.message.message_id,
|
||||
*args, **kwargs)
|
||||
update.callback_query.message.edit_text(text, *args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_text(inline_message_id=update.callback_query.inline_message_id,
|
||||
bot.edit_message_text(text, inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_message_text`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.edit_message_text(
|
||||
inline_message_id=self.inline_message_id, *args, **kwargs)
|
||||
else:
|
||||
return self.bot.edit_message_text(
|
||||
chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs)
|
||||
inline_message_id=self.inline_message_id,
|
||||
text=text,
|
||||
parse_mode=parse_mode,
|
||||
disable_web_page_preview=disable_web_page_preview,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
entities=entities,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
)
|
||||
return self.message.edit_text(
|
||||
text=text,
|
||||
parse_mode=parse_mode,
|
||||
disable_web_page_preview=disable_web_page_preview,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
entities=entities,
|
||||
)
|
||||
|
||||
def edit_message_caption(self, *args, **kwargs):
|
||||
def edit_message_caption(
|
||||
self,
|
||||
caption: str = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
parse_mode: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
bot.edit_message_caption(chat_id=update.callback_query.message.chat_id,
|
||||
message_id=update.callback_query.message.message_id,
|
||||
*args, **kwargs)
|
||||
update.callback_query.message.edit_caption(caption, *args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_caption(inline_message_id=update.callback_query.inline_message_id,
|
||||
bot.edit_message_caption(caption=caption
|
||||
inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_message_caption`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.edit_message_caption(
|
||||
inline_message_id=self.inline_message_id, *args, **kwargs)
|
||||
else:
|
||||
return self.bot.edit_message_caption(
|
||||
chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs)
|
||||
caption=caption,
|
||||
inline_message_id=self.inline_message_id,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
parse_mode=parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
caption_entities=caption_entities,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
)
|
||||
return self.message.edit_caption(
|
||||
caption=caption,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
parse_mode=parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
caption_entities=caption_entities,
|
||||
)
|
||||
|
||||
def edit_message_reply_markup(self, *args, **kwargs):
|
||||
def edit_message_reply_markup(
|
||||
self,
|
||||
reply_markup: Optional['InlineKeyboardMarkup'] = None,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
bot.edit_message_replyMarkup(chat_id=update.callback_query.message.chat_id,
|
||||
message_id=update.callback_query.message.message_id,
|
||||
*args, **kwargs)
|
||||
update.callback_query.message.edit_reply_markup(
|
||||
reply_markup=reply_markup,
|
||||
*args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_reply_markup(inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
bot.edit_message_reply_markup
|
||||
inline_message_id=update.callback_query.inline_message_id,
|
||||
reply_markup=reply_markup,
|
||||
*args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_message_reply_markup`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.edit_message_reply_markup(
|
||||
inline_message_id=self.inline_message_id, *args, **kwargs)
|
||||
else:
|
||||
return self.bot.edit_message_reply_markup(
|
||||
chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs)
|
||||
reply_markup=reply_markup,
|
||||
inline_message_id=self.inline_message_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
)
|
||||
return self.message.edit_reply_markup(
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def edit_message_media(
|
||||
self,
|
||||
media: 'InputMedia' = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.edit_media(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_media(inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_message_media`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.edit_message_media(
|
||||
inline_message_id=self.inline_message_id,
|
||||
media=media,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
)
|
||||
return self.message.edit_media(
|
||||
media=media,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def edit_message_live_location(
|
||||
self,
|
||||
latitude: float = None,
|
||||
longitude: float = None,
|
||||
location: Location = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
horizontal_accuracy: float = None,
|
||||
heading: int = None,
|
||||
proximity_alert_radius: int = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.edit_live_location(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_live_location(
|
||||
inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_message_live_location`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.edit_message_live_location(
|
||||
inline_message_id=self.inline_message_id,
|
||||
latitude=latitude,
|
||||
longitude=longitude,
|
||||
location=location,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
horizontal_accuracy=horizontal_accuracy,
|
||||
heading=heading,
|
||||
proximity_alert_radius=proximity_alert_radius,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
)
|
||||
return self.message.edit_live_location(
|
||||
latitude=latitude,
|
||||
longitude=longitude,
|
||||
location=location,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
horizontal_accuracy=horizontal_accuracy,
|
||||
heading=heading,
|
||||
proximity_alert_radius=proximity_alert_radius,
|
||||
)
|
||||
|
||||
def stop_message_live_location(
|
||||
self,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.stop_live_location(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.stop_message_live_location(
|
||||
inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.stop_message_live_location`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.stop_message_live_location(
|
||||
inline_message_id=self.inline_message_id,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
)
|
||||
return self.message.stop_live_location(
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def set_game_score(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
score: int,
|
||||
force: bool = None,
|
||||
disable_edit_message: bool = None,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.set_game_score(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.set_game_score(inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.set_game_score`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.set_game_score(
|
||||
inline_message_id=self.inline_message_id,
|
||||
user_id=user_id,
|
||||
score=score,
|
||||
force=force,
|
||||
disable_edit_message=disable_edit_message,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
)
|
||||
return self.message.set_game_score(
|
||||
user_id=user_id,
|
||||
score=score,
|
||||
force=force,
|
||||
disable_edit_message=disable_edit_message,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def get_game_high_scores(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> List['GameHighScore']:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.get_game_high_score(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.get_game_high_scores(inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.get_game_high_scores`.
|
||||
|
||||
Returns:
|
||||
List[:class:`telegram.GameHighScore`]
|
||||
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.get_game_high_scores(
|
||||
inline_message_id=self.inline_message_id,
|
||||
user_id=user_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
)
|
||||
return self.message.get_game_high_scores(
|
||||
user_id=user_id,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def delete_message(
|
||||
self,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
update.callback_query.message.delete(*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.delete_message`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
return self.message.delete(
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def pin_message(
|
||||
self,
|
||||
disable_notification: bool = None,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.pin_chat_message(chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.pin_chat_message`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
return self.message.pin(
|
||||
disable_notification=disable_notification,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def unpin_message(
|
||||
self,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.unpin_chat_message(chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.unpin_chat_message`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
return self.message.unpin(
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def copy_message(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
caption: str = None,
|
||||
parse_mode: str = None,
|
||||
caption_entities: Union[Tuple['MessageEntity', ...], List['MessageEntity']] = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
allow_sending_without_reply: bool = False,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
|
||||
update.callback_query.message.copy(
|
||||
chat_id,
|
||||
from_chat_id=update.message.chat_id,
|
||||
message_id=update.message.message_id,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.copy_message`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.MessageId`: On success, returns the MessageId of the sent message.
|
||||
|
||||
"""
|
||||
return self.message.copy(
|
||||
chat_id=chat_id,
|
||||
caption=caption,
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
disable_notification=disable_notification,
|
||||
reply_to_message_id=reply_to_message_id,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
MAX_ANSWER_TEXT_LENGTH: ClassVar[int] = constants.MAX_ANSWER_CALLBACK_QUERY_TEXT_LENGTH
|
||||
"""
|
||||
:const:`telegram.constants.MAX_ANSWER_CALLBACK_QUERY_TEXT_LENGTH`
|
||||
|
||||
.. versionadded:: 13.2
|
||||
"""
|
||||
|
||||
+1179
-127
File diff suppressed because it is too large
Load Diff
+25
-23
@@ -2,7 +2,7 @@
|
||||
# pylint: disable=R0903
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -18,28 +18,30 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatAction."""
|
||||
from typing import ClassVar
|
||||
from telegram import constants
|
||||
|
||||
|
||||
class ChatAction(object):
|
||||
"""Helper class to provide constants for different chatactions."""
|
||||
class ChatAction:
|
||||
"""Helper class to provide constants for different chat actions."""
|
||||
|
||||
FIND_LOCATION = 'find_location'
|
||||
""":obj:`str`: 'find_location'"""
|
||||
RECORD_AUDIO = 'record_audio'
|
||||
""":obj:`str`: 'record_audio'"""
|
||||
RECORD_VIDEO = 'record_video'
|
||||
""":obj:`str`: 'record_video'"""
|
||||
RECORD_VIDEO_NOTE = 'record_video_note'
|
||||
""":obj:`str`: 'record_video_note'"""
|
||||
TYPING = 'typing'
|
||||
""":obj:`str`: 'typing'"""
|
||||
UPLOAD_AUDIO = 'upload_audio'
|
||||
""":obj:`str`: 'upload_audio'"""
|
||||
UPLOAD_DOCUMENT = 'upload_document'
|
||||
""":obj:`str`: 'upload_document'"""
|
||||
UPLOAD_PHOTO = 'upload_photo'
|
||||
""":obj:`str`: 'upload_photo'"""
|
||||
UPLOAD_VIDEO = 'upload_video'
|
||||
""":obj:`str`: 'upload_video'"""
|
||||
UPLOAD_VIDEO_NOTE = 'upload_video_note'
|
||||
""":obj:`str`: 'upload_video_note'"""
|
||||
FIND_LOCATION: ClassVar[str] = constants.CHATACTION_FIND_LOCATION
|
||||
""":const:`telegram.constants.CHATACTION_FIND_LOCATION`"""
|
||||
RECORD_AUDIO: ClassVar[str] = constants.CHATACTION_RECORD_AUDIO
|
||||
""":const:`telegram.constants.CHATACTION_RECORD_AUDIO`"""
|
||||
RECORD_VIDEO: ClassVar[str] = constants.CHATACTION_RECORD_VIDEO
|
||||
""":const:`telegram.constants.CHATACTION_RECORD_VIDEO`"""
|
||||
RECORD_VIDEO_NOTE: ClassVar[str] = constants.CHATACTION_RECORD_VIDEO_NOTE
|
||||
""":const:`telegram.constants.CHATACTION_RECORD_VIDEO_NOTE`"""
|
||||
TYPING: ClassVar[str] = constants.CHATACTION_TYPING
|
||||
""":const:`telegram.constants.CHATACTION_TYPING`"""
|
||||
UPLOAD_AUDIO: ClassVar[str] = constants.CHATACTION_UPLOAD_AUDIO
|
||||
""":const:`telegram.constants.CHATACTION_UPLOAD_AUDIO`"""
|
||||
UPLOAD_DOCUMENT: ClassVar[str] = constants.CHATACTION_UPLOAD_DOCUMENT
|
||||
""":const:`telegram.constants.CHATACTION_UPLOAD_DOCUMENT`"""
|
||||
UPLOAD_PHOTO: ClassVar[str] = constants.CHATACTION_UPLOAD_PHOTO
|
||||
""":const:`telegram.constants.CHATACTION_UPLOAD_PHOTO`"""
|
||||
UPLOAD_VIDEO: ClassVar[str] = constants.CHATACTION_UPLOAD_VIDEO
|
||||
""":const:`telegram.constants.CHATACTION_UPLOAD_VIDEO`"""
|
||||
UPLOAD_VIDEO_NOTE: ClassVar[str] = constants.CHATACTION_UPLOAD_VIDEO_NOTE
|
||||
""":const:`telegram.constants.CHATACTION_UPLOAD_VIDEO_NOTE`"""
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a location to which a chat is connected."""
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
from telegram import TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
|
||||
from .files.location import Location
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class ChatLocation(TelegramObject):
|
||||
"""This object represents a location to which a chat is connected.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`location` is equal.
|
||||
|
||||
Args:
|
||||
location (:class:`telegram.Location`): The location to which the supergroup is connected.
|
||||
Can't be a live location.
|
||||
address (:obj:`str`): Location address; 1-64 characters, as defined by the chat owner
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
Attributes:
|
||||
location (:class:`telegram.Location`): The location to which the supergroup is connected.
|
||||
address (:obj:`str`): Location address, as defined by the chat owner
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
location: Location,
|
||||
address: str,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
self.location = location
|
||||
self.address = address
|
||||
|
||||
self._id_attrs = (self.location,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['ChatLocation']:
|
||||
data = cls.parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data['location'] = Location.de_json(data.get('location'), bot)
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
+128
-82
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -17,104 +17,148 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatMember."""
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Any, Optional, ClassVar
|
||||
|
||||
from telegram import User, TelegramObject
|
||||
from telegram.utils.helpers import to_timestamp, from_timestamp
|
||||
from telegram import TelegramObject, User, constants
|
||||
from telegram.utils.helpers import from_timestamp, to_timestamp
|
||||
from telegram.utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class ChatMember(TelegramObject):
|
||||
"""This object contains information about one member of the chat.
|
||||
"""This object contains information about one member of a chat.
|
||||
|
||||
Attributes:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
status (:obj:`str`): The member's status in the chat.
|
||||
until_date (:class:`datetime.datetime`): Optional. Date when restrictions will be lifted
|
||||
for this user.
|
||||
can_be_edited (:obj:`bool`): Optional. If the bot is allowed to edit administrator
|
||||
privileges of that user.
|
||||
can_change_info (:obj:`bool`): Optional. If the administrator can change the chat title,
|
||||
photo and other settings.
|
||||
can_post_messages (:obj:`bool`): Optional. If the administrator can post in the channel.
|
||||
can_edit_messages (:obj:`bool`): Optional. If the administrator can edit messages of other
|
||||
users.
|
||||
can_delete_messages (:obj:`bool`): Optional. If the administrator can delete messages of
|
||||
other users.
|
||||
can_invite_users (:obj:`bool`): Optional. If the administrator can invite new users to the
|
||||
chat.
|
||||
can_restrict_members (:obj:`bool`): Optional. If the administrator can restrict, ban or
|
||||
unban chat members.
|
||||
can_pin_messages (:obj:`bool`): Optional. If the administrator can pin messages.
|
||||
can_promote_members (:obj:`bool`): Optional. If the administrator can add new
|
||||
administrators.
|
||||
can_send_messages (:obj:`bool`): Optional. If the user can send text messages, contacts,
|
||||
locations and venues.
|
||||
can_send_media_messages (:obj:`bool`): Optional. If the user can send media messages,
|
||||
implies can_send_messages.
|
||||
can_send_other_messages (:obj:`bool`): Optional. If the user can send animations, games,
|
||||
stickers and use inline bots, implies can_send_media_messages.
|
||||
can_add_web_page_previews (:obj:`bool`): Optional. If user may add web page previews to his
|
||||
messages, implies can_send_media_messages
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`user` and :attr:`status` are equal.
|
||||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
status (:obj:`str`): The member's status in the chat. Can be 'creator', 'administrator',
|
||||
'member', 'restricted', 'left' or 'kicked'.
|
||||
custom_title (:obj:`str`, optional): Owner and administrators only.
|
||||
Custom title for this user.
|
||||
is_anonymous (:obj:`bool`, optional): Owner and administrators only. :obj:`True`, if the
|
||||
user's presence in the chat is hidden.
|
||||
until_date (:class:`datetime.datetime`, optional): Restricted and kicked only. Date when
|
||||
restrictions will be lifted for this user.
|
||||
can_be_edited (:obj:`bool`, optional): Administrators only. True, if the bot is allowed to
|
||||
edit administrator privileges of that user.
|
||||
can_change_info (:obj:`bool`, optional): Administrators only. True, if the administrator
|
||||
can change the chat title, photo and other settings.
|
||||
can_post_messages (:obj:`bool`, optional): Administrators only. True, if the administrator
|
||||
can post in the channel, channels only.
|
||||
can_edit_messages (:obj:`bool`, optional): Administrators only. True, if the administrator
|
||||
can edit messages of other users, channels only.
|
||||
can_delete_messages (:obj:`bool`, optional): Administrators only. True, if the
|
||||
administrator can delete messages of other user.
|
||||
can_invite_users (:obj:`bool`, optional): Administrators only. True, if the administrator
|
||||
can invite new users to the chat.
|
||||
can_restrict_members (:obj:`bool`, optional): Administrators only. True, if the
|
||||
can_be_edited (:obj:`bool`, optional): Administrators only. :obj:`True`, if the bot is
|
||||
allowed to edit administrator privileges of that user.
|
||||
can_change_info (:obj:`bool`, optional): Administrators and restricted only. :obj:`True`,
|
||||
if the user can change the chat title, photo and other settings.
|
||||
can_post_messages (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can post in the channel, channels only.
|
||||
can_edit_messages (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can edit messages of other users and can pin messages; channels only.
|
||||
can_delete_messages (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can delete messages of other users.
|
||||
can_invite_users (:obj:`bool`, optional): Administrators and restricted only. :obj:`True`,
|
||||
if the user can invite new users to the chat.
|
||||
can_restrict_members (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can restrict, ban or unban chat members.
|
||||
can_pin_messages (:obj:`bool`, optional): Administrators only. True, if the administrator
|
||||
can pin messages, supergroups only.
|
||||
can_promote_members (:obj:`bool`, optional): Administrators only. True, if the
|
||||
can_pin_messages (:obj:`bool`, optional): Administrators and restricted only. :obj:`True`,
|
||||
if the user can pin messages, groups and supergroups only.
|
||||
can_promote_members (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can add new administrators with a subset of his own privileges or demote
|
||||
administrators that he has promoted, directly or indirectly (promoted by administrators
|
||||
that were appointed by the user).
|
||||
can_send_messages (:obj:`bool`, optional): Restricted only. True, if the user can send text
|
||||
messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`, optional): Restricted only. True, if the user can
|
||||
send audios, documents, photos, videos, video notes and voice notes, implies
|
||||
can_send_messages.
|
||||
can_send_other_messages (:obj:`bool`, optional): Restricted only. True, if the user can
|
||||
send animations, games, stickers and use inline bots, implies can_send_media_messages.
|
||||
can_add_web_page_previews (:obj:`bool`, optional): Restricted only. True, if user may add
|
||||
web page previews to his messages, implies can_send_media_messages.
|
||||
is_member (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user is a member of
|
||||
the chat at the moment of the request.
|
||||
can_send_messages (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user can
|
||||
send text messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user
|
||||
can send audios, documents, photos, videos, video notes and voice notes.
|
||||
can_send_polls (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user is
|
||||
allowed to send polls.
|
||||
can_send_other_messages (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user
|
||||
can send animations, games, stickers and use inline bots.
|
||||
can_add_web_page_previews (:obj:`bool`, optional): Restricted only. :obj:`True`, if user
|
||||
may add web page previews to his messages.
|
||||
|
||||
Attributes:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
status (:obj:`str`): The member's status in the chat.
|
||||
custom_title (:obj:`str`): Optional. Custom title for owner and administrators.
|
||||
is_anonymous (:obj:`bool`): Optional. :obj:`True`, if the user's presence in the chat is
|
||||
hidden.
|
||||
until_date (:class:`datetime.datetime`): Optional. Date when restrictions will be lifted
|
||||
for this user.
|
||||
can_be_edited (:obj:`bool`): Optional. If the bot is allowed to edit administrator
|
||||
privileges of that user.
|
||||
can_change_info (:obj:`bool`): Optional. If the user can change the chat title, photo and
|
||||
other settings.
|
||||
can_post_messages (:obj:`bool`): Optional. If the administrator can post in the channel.
|
||||
can_edit_messages (:obj:`bool`): Optional. If the administrator can edit messages of other
|
||||
users.
|
||||
can_delete_messages (:obj:`bool`): Optional. If the administrator can delete messages of
|
||||
other users.
|
||||
can_invite_users (:obj:`bool`): Optional. If the user can invite new users to the chat.
|
||||
can_restrict_members (:obj:`bool`): Optional. If the administrator can restrict, ban or
|
||||
unban chat members.
|
||||
can_pin_messages (:obj:`bool`): Optional. If the user can pin messages.
|
||||
can_promote_members (:obj:`bool`): Optional. If the administrator can add new
|
||||
administrators.
|
||||
is_member (:obj:`bool`): Optional. Restricted only. :obj:`True`, if the user is a member of
|
||||
the chat at the moment of the request.
|
||||
can_send_messages (:obj:`bool`): Optional. If the user can send text messages, contacts,
|
||||
locations and venues.
|
||||
can_send_media_messages (:obj:`bool`): Optional. If the user can send media messages,
|
||||
implies can_send_messages.
|
||||
can_send_polls (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
send polls.
|
||||
can_send_other_messages (:obj:`bool`): Optional. If the user can send animations, games,
|
||||
stickers and use inline bots, implies can_send_media_messages.
|
||||
can_add_web_page_previews (:obj:`bool`): Optional. If user may add web page previews to his
|
||||
messages, implies can_send_media_messages
|
||||
|
||||
"""
|
||||
ADMINISTRATOR = 'administrator'
|
||||
""":obj:`str`: 'administrator'"""
|
||||
CREATOR = 'creator'
|
||||
""":obj:`str`: 'creator'"""
|
||||
KICKED = 'kicked'
|
||||
""":obj:`str`: 'kicked'"""
|
||||
LEFT = 'left'
|
||||
""":obj:`str`: 'left'"""
|
||||
MEMBER = 'member'
|
||||
""":obj:`str`: 'member'"""
|
||||
RESTRICTED = 'restricted'
|
||||
""":obj:`str`: 'restricted'"""
|
||||
|
||||
def __init__(self, user, status, until_date=None, can_be_edited=None,
|
||||
can_change_info=None, can_post_messages=None, can_edit_messages=None,
|
||||
can_delete_messages=None, can_invite_users=None,
|
||||
can_restrict_members=None, can_pin_messages=None,
|
||||
can_promote_members=None, can_send_messages=None,
|
||||
can_send_media_messages=None, can_send_other_messages=None,
|
||||
can_add_web_page_previews=None, **kwargs):
|
||||
ADMINISTRATOR: ClassVar[str] = constants.CHATMEMBER_ADMINISTRATOR
|
||||
""":const:`telegram.constants.CHATMEMBER_ADMINISTRATOR`"""
|
||||
CREATOR: ClassVar[str] = constants.CHATMEMBER_CREATOR
|
||||
""":const:`telegram.constants.CHATMEMBER_CREATOR`"""
|
||||
KICKED: ClassVar[str] = constants.CHATMEMBER_KICKED
|
||||
""":const:`telegram.constants.CHATMEMBER_KICKED`"""
|
||||
LEFT: ClassVar[str] = constants.CHATMEMBER_LEFT
|
||||
""":const:`telegram.constants.CHATMEMBER_LEFT`"""
|
||||
MEMBER: ClassVar[str] = constants.CHATMEMBER_MEMBER
|
||||
""":const:`telegram.constants.CHATMEMBER_MEMBER`"""
|
||||
RESTRICTED: ClassVar[str] = constants.CHATMEMBER_RESTRICTED
|
||||
""":const:`telegram.constants.CHATMEMBER_RESTRICTED`"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user: User,
|
||||
status: str,
|
||||
until_date: datetime.datetime = None,
|
||||
can_be_edited: bool = None,
|
||||
can_change_info: bool = None,
|
||||
can_post_messages: bool = None,
|
||||
can_edit_messages: bool = None,
|
||||
can_delete_messages: bool = None,
|
||||
can_invite_users: bool = None,
|
||||
can_restrict_members: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
can_promote_members: bool = None,
|
||||
can_send_messages: bool = None,
|
||||
can_send_media_messages: bool = None,
|
||||
can_send_polls: bool = None,
|
||||
can_send_other_messages: bool = None,
|
||||
can_add_web_page_previews: bool = None,
|
||||
is_member: bool = None,
|
||||
custom_title: str = None,
|
||||
is_anonymous: bool = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.user = user
|
||||
self.status = status
|
||||
|
||||
# Optionals
|
||||
self.custom_title = custom_title
|
||||
self.is_anonymous = is_anonymous
|
||||
self.until_date = until_date
|
||||
self.can_be_edited = can_be_edited
|
||||
self.can_change_info = can_change_info
|
||||
@@ -127,25 +171,27 @@ class ChatMember(TelegramObject):
|
||||
self.can_promote_members = can_promote_members
|
||||
self.can_send_messages = can_send_messages
|
||||
self.can_send_media_messages = can_send_media_messages
|
||||
self.can_send_polls = can_send_polls
|
||||
self.can_send_other_messages = can_send_other_messages
|
||||
self.can_add_web_page_previews = can_add_web_page_previews
|
||||
self.is_member = is_member
|
||||
|
||||
self._id_attrs = (self.user, self.status)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['ChatMember']:
|
||||
data = cls.parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(ChatMember, cls).de_json(data, bot)
|
||||
|
||||
data['user'] = User.de_json(data.get('user'), bot)
|
||||
data['until_date'] = from_timestamp(data.get('until_date', None))
|
||||
|
||||
return cls(**data)
|
||||
|
||||
def to_dict(self):
|
||||
data = super(ChatMember, self).to_dict()
|
||||
def to_dict(self) -> JSONDict:
|
||||
data = super().to_dict()
|
||||
|
||||
data['until_date'] = to_timestamp(self.until_date)
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatPermission."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
class ChatPermissions(TelegramObject):
|
||||
"""Describes actions that a non-administrator user is allowed to take in a chat.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`can_send_messages`, :attr:`can_send_media_messages`,
|
||||
:attr:`can_send_polls`, :attr:`can_send_other_messages`, :attr:`can_add_web_page_previews`,
|
||||
:attr:`can_change_info`, :attr:`can_invite_users` and :attr:`can_pin_message` are equal.
|
||||
|
||||
Note:
|
||||
Though not stated explicitly in the official docs, Telegram changes not only the
|
||||
permissions that are set, but also sets all the others to :obj:`False`. However, since not
|
||||
documented, this behaviour may change unbeknown to PTB.
|
||||
|
||||
Args:
|
||||
can_send_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send text
|
||||
messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
|
||||
send audios, documents, photos, videos, video notes and voice notes, implies
|
||||
:attr:`can_send_messages`.
|
||||
can_send_polls (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send polls,
|
||||
implies :attr:`can_send_messages`.
|
||||
can_send_other_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
|
||||
send animations, games, stickers and use inline bots, implies
|
||||
:attr:`can_send_media_messages`.
|
||||
can_add_web_page_previews (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
|
||||
add web page previews to their messages, implies :attr:`can_send_media_messages`.
|
||||
can_change_info (:obj:`bool`, optional): :obj:`True`, if the user is allowed to change the
|
||||
chat title, photo and other settings. Ignored in public supergroups.
|
||||
can_invite_users (:obj:`bool`, optional): :obj:`True`, if the user is allowed to invite new
|
||||
users to the chat.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to pin
|
||||
messages. Ignored in public supergroups.
|
||||
|
||||
Attributes:
|
||||
can_send_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send text
|
||||
messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
send audios, documents, photos, videos, video notes and voice notes, implies
|
||||
:attr:`can_send_messages`.
|
||||
can_send_polls (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send polls,
|
||||
implies :attr:`can_send_messages`.
|
||||
can_send_other_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
send animations, games, stickers and use inline bots, implies
|
||||
:attr:`can_send_media_messages`.
|
||||
can_add_web_page_previews (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
add web page previews to their messages, implies :attr:`can_send_media_messages`.
|
||||
can_change_info (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to change the
|
||||
chat title, photo and other settings. Ignored in public supergroups.
|
||||
can_invite_users (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to invite
|
||||
new users to the chat.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to pin
|
||||
messages. Ignored in public supergroups.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
can_send_messages: bool = None,
|
||||
can_send_media_messages: bool = None,
|
||||
can_send_polls: bool = None,
|
||||
can_send_other_messages: bool = None,
|
||||
can_add_web_page_previews: bool = None,
|
||||
can_change_info: bool = None,
|
||||
can_invite_users: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.can_send_messages = can_send_messages
|
||||
self.can_send_media_messages = can_send_media_messages
|
||||
self.can_send_polls = can_send_polls
|
||||
self.can_send_other_messages = can_send_other_messages
|
||||
self.can_add_web_page_previews = can_add_web_page_previews
|
||||
self.can_change_info = can_change_info
|
||||
self.can_invite_users = can_invite_users
|
||||
self.can_pin_messages = can_pin_messages
|
||||
|
||||
self._id_attrs = (
|
||||
self.can_send_messages,
|
||||
self.can_send_media_messages,
|
||||
self.can_send_polls,
|
||||
self.can_send_other_messages,
|
||||
self.can_add_web_page_previews,
|
||||
self.can_change_info,
|
||||
self.can_invite_users,
|
||||
self.can_pin_messages,
|
||||
)
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=R0902,R0912,R0913
|
||||
# pylint: disable=R0902,R0913
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,7 +19,13 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChosenInlineResult."""
|
||||
|
||||
from telegram import TelegramObject, User, Location
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
from telegram import Location, TelegramObject, User
|
||||
from telegram.utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class ChosenInlineResult(TelegramObject):
|
||||
@@ -27,15 +33,13 @@ class ChosenInlineResult(TelegramObject):
|
||||
Represents a result of an inline query that was chosen by the user and sent to their chat
|
||||
partner.
|
||||
|
||||
Note:
|
||||
In Python `from` is a reserved word, use `from_user` instead.
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`result_id` is equal.
|
||||
|
||||
Attributes:
|
||||
result_id (:obj:`str`): The unique identifier for the result that was chosen.
|
||||
from_user (:class:`telegram.User`): The user that chose the result.
|
||||
location (:class:`telegram.Location`): Optional. Sender location.
|
||||
inline_message_id (:obj:`str`): Optional. Identifier of the sent inline message.
|
||||
query (:obj:`str`): The query that was used to obtain the result.
|
||||
Note:
|
||||
* In Python `from` is a reserved word, use `from_user` instead.
|
||||
* It is necessary to enable inline feedback via `@Botfather <https://t.me/BotFather>`_ in
|
||||
order to receive these objects in updates.
|
||||
|
||||
Args:
|
||||
result_id (:obj:`str`): The unique identifier for the result that was chosen.
|
||||
@@ -48,15 +52,24 @@ class ChosenInlineResult(TelegramObject):
|
||||
query (:obj:`str`): The query that was used to obtain the result.
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
Attributes:
|
||||
result_id (:obj:`str`): The unique identifier for the result that was chosen.
|
||||
from_user (:class:`telegram.User`): The user that chose the result.
|
||||
location (:class:`telegram.Location`): Optional. Sender location.
|
||||
inline_message_id (:obj:`str`): Optional. Identifier of the sent inline message.
|
||||
query (:obj:`str`): The query that was used to obtain the result.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
result_id,
|
||||
from_user,
|
||||
query,
|
||||
location=None,
|
||||
inline_message_id=None,
|
||||
**kwargs):
|
||||
def __init__(
|
||||
self,
|
||||
result_id: str,
|
||||
from_user: User,
|
||||
query: str,
|
||||
location: Location = None,
|
||||
inline_message_id: str = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.result_id = result_id
|
||||
self.from_user = from_user
|
||||
@@ -68,11 +81,12 @@ class ChosenInlineResult(TelegramObject):
|
||||
self._id_attrs = (self.result_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['ChosenInlineResult']:
|
||||
data = cls.parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(ChosenInlineResult, cls).de_json(data, bot)
|
||||
# Required
|
||||
data['from_user'] = User.de_json(data.pop('from'), bot)
|
||||
# Optionals
|
||||
|
||||
+197
-13
@@ -1,5 +1,5 @@
|
||||
# python-telegram-bot - a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Copyright (C) 2015-2021
|
||||
# by the python-telegram-bot contributors <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -17,38 +17,222 @@
|
||||
"""Constants in the Telegram network.
|
||||
|
||||
The following constants were extracted from the
|
||||
`Telegram Bots FAQ <https://core.telegram.org/bots/faq>`_.
|
||||
`Telegram Bots FAQ <https://core.telegram.org/bots/faq>`_ and
|
||||
`Telegram Bots API <https://core.telegram.org/bots/api>`_.
|
||||
|
||||
Attributes:
|
||||
MAX_MESSAGE_LENGTH (:obj:`int`): 4096
|
||||
MAX_CAPTION_LENGTH (:obj:`int`): 200
|
||||
MAX_CAPTION_LENGTH (:obj:`int`): 1024
|
||||
SUPPORTED_WEBHOOK_PORTS (List[:obj:`int`]): [443, 80, 88, 8443]
|
||||
MAX_FILESIZE_DOWNLOAD (:obj:`int`): In bytes (20MB)
|
||||
MAX_FILESIZE_UPLOAD (:obj:`int`): In bytes (50MB)
|
||||
MAX_PHOTOSIZE_UPLOAD (:obj:`int`): In bytes (10MB)
|
||||
MAX_MESSAGES_PER_SECOND_PER_CHAT (:obj:`int`): `1`. Telegram may allow short bursts that go
|
||||
over this limit, but eventually you'll begin receiving 429 errors.
|
||||
MAX_MESSAGES_PER_SECOND (:obj:`int`): 30
|
||||
MAX_MESSAGES_PER_MINUTE_PER_GROUP (:obj:`int`): 20
|
||||
MAX_INLINE_QUERY_RESULTS (:obj:`int`): 50
|
||||
MAX_ANSWER_CALLBACK_QUERY_TEXT_LENGTH (:obj:`int`): 200
|
||||
|
||||
.. versionadded:: 13.2
|
||||
|
||||
The following constant have been found by experimentation:
|
||||
|
||||
Attributes:
|
||||
MAX_MESSAGE_ENTITIES (:obj:`int`): 100 (Beyond this cap telegram will simply ignore further
|
||||
formatting styles)
|
||||
ANONYMOUS_ADMIN_ID (:obj:`int`): ``1087968824`` (User id in groups for anonymous admin)
|
||||
SERVICE_CHAT_ID (:obj:`int`): ``777000`` (Telegram service chat, that also acts as sender of
|
||||
channel posts forwarded to discussion groups)
|
||||
|
||||
The following constants are related to specific classes and are also available
|
||||
as attributes of those classes:
|
||||
|
||||
:class:`telegram.Chat`:
|
||||
|
||||
Attributes:
|
||||
CHAT_PRIVATE (:obj:`str`): 'private'
|
||||
CHAT_GROUP (:obj:`str`): 'group'
|
||||
CHAT_SUPERGROUP (:obj:`str`): 'supergroup'
|
||||
CHAT_CHANNEL (:obj:`str`): 'channel'
|
||||
|
||||
:class:`telegram.ChatAction`:
|
||||
|
||||
Attributes:
|
||||
CHATACTION_FIND_LOCATION (:obj:`str`): 'find_location'
|
||||
CHATACTION_RECORD_AUDIO (:obj:`str`): 'record_audio'
|
||||
CHATACTION_RECORD_VIDEO (:obj:`str`): 'record_video'
|
||||
CHATACTION_RECORD_VIDEO_NOTE (:obj:`str`): 'record_video_note'
|
||||
CHATACTION_TYPING (:obj:`str`): 'typing'
|
||||
CHATACTION_UPLOAD_AUDIO (:obj:`str`): 'upload_audio'
|
||||
CHATACTION_UPLOAD_DOCUMENT (:obj:`str`): 'upload_document'
|
||||
CHATACTION_UPLOAD_PHOTO (:obj:`str`): 'upload_photo'
|
||||
CHATACTION_UPLOAD_VIDEO (:obj:`str`): 'upload_video'
|
||||
CHATACTION_UPLOAD_VIDEO_NOTE (:obj:`str`): 'upload_video_note'
|
||||
|
||||
:class:`telegram.ChatMember`:
|
||||
|
||||
Attributes:
|
||||
CHATMEMBER_ADMINISTRATOR (:obj:`str`): 'administrator'
|
||||
CHATMEMBER_CREATOR (:obj:`str`): 'creator'
|
||||
CHATMEMBER_KICKED (:obj:`str`): 'kicked'
|
||||
CHATMEMBER_LEFT (:obj:`str`): 'left'
|
||||
CHATMEMBER_MEMBER (:obj:`str`): 'member'
|
||||
CHATMEMBER_RESTRICTED (:obj:`str`): 'restricted'
|
||||
|
||||
:class:`telegram.Dice`:
|
||||
|
||||
Attributes:
|
||||
DICE_DICE (:obj:`str`): '🎲'
|
||||
DICE_DARTS (:obj:`str`): '🎯'
|
||||
DICE_BASKETBALL (:obj:`str`): '🏀'
|
||||
DICE_FOOTBALL (:obj:`str`): '⚽'
|
||||
DICE_SLOT_MACHINE (:obj:`str`): '🎰'
|
||||
DICE_ALL_EMOJI (List[:obj:`str`]): List of all supported base emoji.
|
||||
|
||||
:class:`telegram.MessageEntity`:
|
||||
|
||||
Attributes:
|
||||
MESSAGEENTITY_MENTION (:obj:`str`): 'mention'
|
||||
MESSAGEENTITY_HASHTAG (:obj:`str`): 'hashtag'
|
||||
MESSAGEENTITY_CASHTAG (:obj:`str`): 'cashtag'
|
||||
MESSAGEENTITY_PHONE_NUMBER (:obj:`str`): 'phone_number'
|
||||
MESSAGEENTITY_BOT_COMMAND (:obj:`str`): 'bot_command'
|
||||
MESSAGEENTITY_URL (:obj:`str`): 'url'
|
||||
MESSAGEENTITY_EMAIL (:obj:`str`): 'email'
|
||||
MESSAGEENTITY_BOLD (:obj:`str`): 'bold'
|
||||
MESSAGEENTITY_ITALIC (:obj:`str`): 'italic'
|
||||
MESSAGEENTITY_CODE (:obj:`str`): 'code'
|
||||
MESSAGEENTITY_PRE (:obj:`str`): 'pre'
|
||||
MESSAGEENTITY_TEXT_LINK (:obj:`str`): 'text_link'
|
||||
MESSAGEENTITY_TEXT_MENTION (:obj:`str`): 'text_mention'
|
||||
MESSAGEENTITY_UNDERLINE (:obj:`str`): 'underline'
|
||||
MESSAGEENTITY_STRIKETHROUGH (:obj:`str`): 'strikethrough'
|
||||
MESSAGEENTITY_ALL_TYPES (List[:obj:`str`]): List of all the types of message entity.
|
||||
|
||||
:class:`telegram.ParseMode`:
|
||||
|
||||
Attributes:
|
||||
PARSEMODE_MARKDOWN (:obj:`str`): 'Markdown'
|
||||
PARSEMODE_MARKDOWN_V2 (:obj:`str`): 'MarkdownV2'
|
||||
PARSEMODE_HTML (:obj:`str`): 'HTML'
|
||||
|
||||
:class:`telegram.Poll`:
|
||||
|
||||
Attributes:
|
||||
POLL_REGULAR (:obj:`str`): 'regular'
|
||||
POLL_QUIZ (:obj:`str`): 'quiz'
|
||||
MAX_POLL_QUESTION_LENGTH (:obj:`int`): 300
|
||||
MAX_POLL_OPTION_LENGTH (:obj:`int`): 100
|
||||
|
||||
:class:`telegram.files.MaskPosition`:
|
||||
|
||||
Attributes:
|
||||
STICKER_FOREHEAD (:obj:`str`): 'forehead'
|
||||
STICKER_EYES (:obj:`str`): 'eyes'
|
||||
STICKER_MOUTH (:obj:`str`): 'mouth'
|
||||
STICKER_CHIN (:obj:`str`): 'chin'
|
||||
|
||||
"""
|
||||
from typing import List
|
||||
|
||||
MAX_MESSAGE_LENGTH = 4096
|
||||
MAX_CAPTION_LENGTH = 200
|
||||
MAX_MESSAGE_LENGTH: int = 4096
|
||||
MAX_CAPTION_LENGTH: int = 1024
|
||||
ANONYMOUS_ADMIN_ID: int = 1087968824
|
||||
SERVICE_CHAT_ID: int = 777000
|
||||
|
||||
# constants above this line are tested
|
||||
|
||||
SUPPORTED_WEBHOOK_PORTS = [443, 80, 88, 8443]
|
||||
MAX_FILESIZE_DOWNLOAD = int(20E6) # (20MB)
|
||||
MAX_FILESIZE_UPLOAD = int(50E6) # (50MB)
|
||||
MAX_MESSAGES_PER_SECOND_PER_CHAT = 1
|
||||
MAX_MESSAGES_PER_SECOND = 30
|
||||
MAX_MESSAGES_PER_MINUTE_PER_GROUP = 20
|
||||
MAX_MESSAGE_ENTITIES = 100
|
||||
MAX_INLINE_QUERY_RESULTS = 50
|
||||
SUPPORTED_WEBHOOK_PORTS: List[int] = [443, 80, 88, 8443]
|
||||
MAX_FILESIZE_DOWNLOAD: int = int(20e6) # (20MB)
|
||||
MAX_FILESIZE_UPLOAD: int = int(50e6) # (50MB)
|
||||
MAX_PHOTOSIZE_UPLOAD: int = int(10e6) # (10MB)
|
||||
MAX_MESSAGES_PER_SECOND_PER_CHAT: int = 1
|
||||
MAX_MESSAGES_PER_SECOND: int = 30
|
||||
MAX_MESSAGES_PER_MINUTE_PER_GROUP: int = 20
|
||||
MAX_MESSAGE_ENTITIES: int = 100
|
||||
MAX_INLINE_QUERY_RESULTS: int = 50
|
||||
MAX_ANSWER_CALLBACK_QUERY_TEXT_LENGTH: int = 200
|
||||
|
||||
CHAT_PRIVATE: str = 'private'
|
||||
CHAT_GROUP: str = 'group'
|
||||
CHAT_SUPERGROUP: str = 'supergroup'
|
||||
CHAT_CHANNEL: str = 'channel'
|
||||
|
||||
CHATACTION_FIND_LOCATION: str = 'find_location'
|
||||
CHATACTION_RECORD_AUDIO: str = 'record_audio'
|
||||
CHATACTION_RECORD_VIDEO: str = 'record_video'
|
||||
CHATACTION_RECORD_VIDEO_NOTE: str = 'record_video_note'
|
||||
CHATACTION_TYPING: str = 'typing'
|
||||
CHATACTION_UPLOAD_AUDIO: str = 'upload_audio'
|
||||
CHATACTION_UPLOAD_DOCUMENT: str = 'upload_document'
|
||||
CHATACTION_UPLOAD_PHOTO: str = 'upload_photo'
|
||||
CHATACTION_UPLOAD_VIDEO: str = 'upload_video'
|
||||
CHATACTION_UPLOAD_VIDEO_NOTE: str = 'upload_video_note'
|
||||
|
||||
CHATMEMBER_ADMINISTRATOR: str = 'administrator'
|
||||
CHATMEMBER_CREATOR: str = 'creator'
|
||||
CHATMEMBER_KICKED: str = 'kicked'
|
||||
CHATMEMBER_LEFT: str = 'left'
|
||||
CHATMEMBER_MEMBER: str = 'member'
|
||||
CHATMEMBER_RESTRICTED: str = 'restricted'
|
||||
|
||||
DICE_DICE: str = '🎲'
|
||||
DICE_DARTS: str = '🎯'
|
||||
DICE_BASKETBALL: str = '🏀'
|
||||
DICE_FOOTBALL: str = '⚽'
|
||||
DICE_SLOT_MACHINE: str = '🎰'
|
||||
DICE_ALL_EMOJI: List[str] = [
|
||||
DICE_DICE,
|
||||
DICE_DARTS,
|
||||
DICE_BASKETBALL,
|
||||
DICE_FOOTBALL,
|
||||
DICE_SLOT_MACHINE,
|
||||
]
|
||||
|
||||
MESSAGEENTITY_MENTION: str = 'mention'
|
||||
MESSAGEENTITY_HASHTAG: str = 'hashtag'
|
||||
MESSAGEENTITY_CASHTAG: str = 'cashtag'
|
||||
MESSAGEENTITY_PHONE_NUMBER: str = 'phone_number'
|
||||
MESSAGEENTITY_BOT_COMMAND: str = 'bot_command'
|
||||
MESSAGEENTITY_URL: str = 'url'
|
||||
MESSAGEENTITY_EMAIL: str = 'email'
|
||||
MESSAGEENTITY_BOLD: str = 'bold'
|
||||
MESSAGEENTITY_ITALIC: str = 'italic'
|
||||
MESSAGEENTITY_CODE: str = 'code'
|
||||
MESSAGEENTITY_PRE: str = 'pre'
|
||||
MESSAGEENTITY_TEXT_LINK: str = 'text_link'
|
||||
MESSAGEENTITY_TEXT_MENTION: str = 'text_mention'
|
||||
MESSAGEENTITY_UNDERLINE: str = 'underline'
|
||||
MESSAGEENTITY_STRIKETHROUGH: str = 'strikethrough'
|
||||
MESSAGEENTITY_ALL_TYPES: List[str] = [
|
||||
MESSAGEENTITY_MENTION,
|
||||
MESSAGEENTITY_HASHTAG,
|
||||
MESSAGEENTITY_CASHTAG,
|
||||
MESSAGEENTITY_PHONE_NUMBER,
|
||||
MESSAGEENTITY_BOT_COMMAND,
|
||||
MESSAGEENTITY_URL,
|
||||
MESSAGEENTITY_EMAIL,
|
||||
MESSAGEENTITY_BOLD,
|
||||
MESSAGEENTITY_ITALIC,
|
||||
MESSAGEENTITY_CODE,
|
||||
MESSAGEENTITY_PRE,
|
||||
MESSAGEENTITY_TEXT_LINK,
|
||||
MESSAGEENTITY_TEXT_MENTION,
|
||||
MESSAGEENTITY_UNDERLINE,
|
||||
MESSAGEENTITY_STRIKETHROUGH,
|
||||
]
|
||||
|
||||
PARSEMODE_MARKDOWN: str = 'Markdown'
|
||||
PARSEMODE_MARKDOWN_V2: str = 'MarkdownV2'
|
||||
PARSEMODE_HTML: str = 'HTML'
|
||||
|
||||
POLL_REGULAR: str = 'regular'
|
||||
POLL_QUIZ: str = 'quiz'
|
||||
MAX_POLL_QUESTION_LENGTH: int = 300
|
||||
MAX_POLL_OPTION_LENGTH: int = 100
|
||||
|
||||
STICKER_FOREHEAD: str = 'forehead'
|
||||
STICKER_EYES: str = 'eyes'
|
||||
STICKER_MOUTH: str = 'mouth'
|
||||
STICKER_CHIN: str = 'chin'
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=R0903
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Dice."""
|
||||
from typing import Any, List, ClassVar
|
||||
|
||||
from telegram import TelegramObject, constants
|
||||
|
||||
|
||||
class Dice(TelegramObject):
|
||||
"""
|
||||
This object represents an animated emoji with a random value for currently supported base
|
||||
emoji. (The singular form of "dice" is "die". However, PTB mimics the Telegram API, which uses
|
||||
the term "dice".)
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`value` and :attr:`emoji` are equal.
|
||||
|
||||
Note:
|
||||
If :attr:`emoji` is "🎯", a value of 6 currently represents a bullseye, while a value of 1
|
||||
indicates that the dartboard was missed. However, this behaviour is undocumented and might
|
||||
be changed by Telegram.
|
||||
|
||||
If :attr:`emoji` is "🏀", a value of 4 or 5 currently score a basket, while a value of 1 to
|
||||
3 indicates that the basket was missed. However, this behaviour is undocumented and might
|
||||
be changed by Telegram.
|
||||
|
||||
If :attr:`emoji` is "⚽", a value of 4 to 5 currently scores a goal, while a value of 1 to
|
||||
3 indicates that the goal was missed. However, this behaviour is undocumented and might
|
||||
be changed by Telegram.
|
||||
|
||||
If :attr:`emoji` is "🎰", each value corresponds to a unique combination of symbols, which
|
||||
can be found at our `wiki <https://git.io/JkeC6>`_. However, this behaviour is undocumented
|
||||
and might be changed by Telegram.
|
||||
|
||||
Args:
|
||||
value (:obj:`int`): Value of the dice. 1-6 for dice and darts, 1-5 for basketball and
|
||||
football/soccer ball, 1-64 for slot machine.
|
||||
emoji (:obj:`str`): Emoji on which the dice throw animation is based.
|
||||
|
||||
Attributes:
|
||||
value (:obj:`int`): Value of the dice.
|
||||
emoji (:obj:`str`): Emoji on which the dice throw animation is based.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, value: int, emoji: str, **_kwargs: Any):
|
||||
self.value = value
|
||||
self.emoji = emoji
|
||||
|
||||
self._id_attrs = (self.value, self.emoji)
|
||||
|
||||
DICE: ClassVar[str] = constants.DICE_DICE
|
||||
""":const:`telegram.constants.DICE_DICE`"""
|
||||
DARTS: ClassVar[str] = constants.DICE_DARTS
|
||||
""":const:`telegram.constants.DICE_DARTS`"""
|
||||
BASKETBALL: ClassVar[str] = constants.DICE_BASKETBALL
|
||||
""":const:`telegram.constants.DICE_BASKETBALL`"""
|
||||
FOOTBALL: ClassVar[str] = constants.DICE_FOOTBALL
|
||||
""":const:`telegram.constants.DICE_FOOTBALL`"""
|
||||
SLOT_MACHINE: ClassVar[str] = constants.DICE_SLOT_MACHINE
|
||||
""":const:`telegram.constants.DICE_SLOT_MACHINE`"""
|
||||
ALL_EMOJI: ClassVar[List[str]] = constants.DICE_ALL_EMOJI
|
||||
""":const:`telegram.constants.DICE_ALL_EMOJI`"""
|
||||
+46
-20
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Copyright (C) 2015-2021
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -16,29 +16,31 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=C0115
|
||||
"""This module contains an object that represents Telegram errors."""
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def _lstrip_str(in_s, lstr):
|
||||
def _lstrip_str(in_s: str, lstr: str) -> str:
|
||||
"""
|
||||
Args:
|
||||
in_s (:obj:`str`): in string
|
||||
lstr (:obj:`str`): substr to strip from left side
|
||||
|
||||
Returns:
|
||||
str:
|
||||
:obj:`str`: The stripped string.
|
||||
|
||||
"""
|
||||
if in_s.startswith(lstr):
|
||||
res = in_s[len(lstr):]
|
||||
res = in_s[len(lstr) :]
|
||||
else:
|
||||
res = in_s
|
||||
return res
|
||||
|
||||
|
||||
class TelegramError(Exception):
|
||||
def __init__(self, message):
|
||||
super(TelegramError, self).__init__()
|
||||
def __init__(self, message: str):
|
||||
super().__init__()
|
||||
|
||||
msg = _lstrip_str(message, 'Error: ')
|
||||
msg = _lstrip_str(msg, '[Error]: ')
|
||||
@@ -48,8 +50,11 @@ class TelegramError(Exception):
|
||||
msg = msg.capitalize()
|
||||
self.message = msg
|
||||
|
||||
def __str__(self):
|
||||
return '%s' % (self.message)
|
||||
def __str__(self) -> str:
|
||||
return '%s' % self.message
|
||||
|
||||
def __reduce__(self) -> Tuple[type, Tuple[str]]:
|
||||
return self.__class__, (self.message,)
|
||||
|
||||
|
||||
class Unauthorized(TelegramError):
|
||||
@@ -57,9 +62,11 @@ class Unauthorized(TelegramError):
|
||||
|
||||
|
||||
class InvalidToken(TelegramError):
|
||||
def __init__(self) -> None:
|
||||
super().__init__('Invalid token')
|
||||
|
||||
def __init__(self):
|
||||
super(InvalidToken, self).__init__('Invalid token')
|
||||
def __reduce__(self) -> Tuple[type, Tuple]: # type: ignore[override]
|
||||
return self.__class__, ()
|
||||
|
||||
|
||||
class NetworkError(TelegramError):
|
||||
@@ -71,32 +78,51 @@ class BadRequest(NetworkError):
|
||||
|
||||
|
||||
class TimedOut(NetworkError):
|
||||
def __init__(self) -> None:
|
||||
super().__init__('Timed out')
|
||||
|
||||
def __init__(self):
|
||||
super(TimedOut, self).__init__('Timed out')
|
||||
def __reduce__(self) -> Tuple[type, Tuple]: # type: ignore[override]
|
||||
return self.__class__, ()
|
||||
|
||||
|
||||
class ChatMigrated(TelegramError):
|
||||
"""
|
||||
Args:
|
||||
new_chat_id (:obj:`int`):
|
||||
new_chat_id (:obj:`int`): The new chat id of the group.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, new_chat_id):
|
||||
super(ChatMigrated,
|
||||
self).__init__('Group migrated to supergroup. New chat id: {}'.format(new_chat_id))
|
||||
def __init__(self, new_chat_id: int):
|
||||
super().__init__(f'Group migrated to supergroup. New chat id: {new_chat_id}')
|
||||
self.new_chat_id = new_chat_id
|
||||
|
||||
def __reduce__(self) -> Tuple[type, Tuple[int]]: # type: ignore[override]
|
||||
return self.__class__, (self.new_chat_id,)
|
||||
|
||||
|
||||
class RetryAfter(TelegramError):
|
||||
"""
|
||||
Args:
|
||||
retry_after (:obj:`int`):
|
||||
retry_after (:obj:`int`): Time in seconds, after which the bot can retry the request.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, retry_after):
|
||||
super(RetryAfter,
|
||||
self).__init__('Flood control exceeded. Retry in {} seconds'.format(retry_after))
|
||||
def __init__(self, retry_after: int):
|
||||
super().__init__(f'Flood control exceeded. Retry in {float(retry_after)} seconds')
|
||||
self.retry_after = float(retry_after)
|
||||
|
||||
def __reduce__(self) -> Tuple[type, Tuple[float]]: # type: ignore[override]
|
||||
return self.__class__, (self.retry_after,)
|
||||
|
||||
|
||||
class Conflict(TelegramError):
|
||||
"""
|
||||
Raised when a long poll or webhook conflicts with another one.
|
||||
|
||||
Args:
|
||||
msg (:obj:`str`): The message from telegrams server.
|
||||
|
||||
"""
|
||||
|
||||
def __reduce__(self) -> Tuple[type, Tuple[str]]:
|
||||
return self.__class__, (self.message,)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user